Ais*_*ina 42 code-golf tic-tac-toe rosetta-stone
按字符数发布您的最短代码,以检查玩家是否赢了,如果是,那么.
假设你在变量b(board)中有一个整数数组,它包含Tic Tac Toe板,以及玩家的移动:
所以,鉴于阵列b = [ 1, 2, 1, 0, 1, 2, 1, 0, 2 ]将代表董事会
X|O|X
-+-+-
|X|O
-+-+-
X| |O
Run Code Online (Sandbox Code Playgroud)
对于这种情况,您的代码应该输出1以指示玩家1赢了.如果没有人赢了你可以输出0或false.
我自己的(Ruby)解决方案即将推出.
编辑:对不起,忘了将其标记为社区维基.您可以假设输入格式正确,不必进行错误检查.
更新:请以函数的形式发布您的解决方案.大多数人已经这样做了,但有些人没有,这不完全公平.电路板作为参数提供给您的功能.结果应该由函数返回.该函数可以具有您选择的名称.
esw*_*ald 37
疯狂的Python解决方案 - 79个字符
max([b[x] for x in range(9) for y in range(x) for z in range(y)
if x+y+z==12 and b[x]==b[y]==b[z]] + [0])
Run Code Online (Sandbox Code Playgroud)
但是,这假设b中的董事会职位的顺序不同:
5 | 0 | 7
---+---+---
6 | 4 | 2
---+---+---
1 | 8 | 3
Run Code Online (Sandbox Code Playgroud)
也就是说,b[5]代表左上角,依此类推.
为了尽量减少上述情况
r=range
max([b[x]for x in r(9)for y in r(x)for z in r(y)if x+y+z==12and b[x]==b[y]==b[z]]+[0])
Run Code Online (Sandbox Code Playgroud)
93个字符和换行符.
更新:使用按位AND技巧,最多79个字符和换行符:
r=range
max([b[x]&b[y]&b[z]for x in r(9)for y in r(x)for z in r(y)if x+y+z==12])
Run Code Online (Sandbox Code Playgroud)
ken*_*ytm 22
这是dmckee解决方案的变体,除了Compact Coding中的每对数字现在是ASCII字符的基数为9的数字.
在77 -char版本,不会对MSVC工作:
// "J)9\t8\r=,\0" == 82,45,63,10,62,14,67,48,00 in base 9.
char*k="J)9 8\r=,",c;f(int*b){return(c=*k++)?b[c/9]&b[c%9]&b[*k--%9]|f(b):0;}
Run Code Online (Sandbox Code Playgroud)
这个83 -char版本应该适用于每个C编译器:
f(int*b){char*k="J)9 8\r=,",s=0,c;while(c=*k++)s|=b[c%9]&b[c/9]&b[*k%9];return s;}
Run Code Online (Sandbox Code Playgroud)
(请注意,9和8之间的空格应该是一个选项卡.StackOverflow将所有选项卡转换为空格.)
测试用例:
#include <stdio.h>
void check(int* b) {
int h0 = b[0]&b[1]&b[2];
int h1 = b[3]&b[4]&b[5];
int h2 = b[6]&b[7]&b[8];
int h3 = b[0]&b[3]&b[6];
int h4 = b[1]&b[4]&b[7];
int h5 = b[2]&b[5]&b[8];
int h6 = b[0]&b[4]&b[8];
int h7 = b[2]&b[4]&b[6];
int res = h0|h1|h2|h3|h4|h5|h6|h7;
int value = f(b);
if (value != res)
printf("Assuming f({%d,%d,%d, %d,%d,%d, %d,%d,%d}) == %d; got %d instead.\n",
b[0],b[1],b[2], b[3],b[4],b[5], b[6],b[7],b[8], res, value);
}
#define MAKEFOR(i) for(b[(i)]=0;b[(i)]<=2;++b[(i)])
int main() {
int b[9];
MAKEFOR(0)
MAKEFOR(1)
MAKEFOR(2)
MAKEFOR(3)
MAKEFOR(4)
MAKEFOR(5)
MAKEFOR(6)
MAKEFOR(7)
MAKEFOR(8)
check(b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
mob*_*mob 12
不是最短的Python解决方案,但我喜欢它如何将"DICE"引入到tic-tac-toe游戏中:
W=lambda b:max([b[c/5-9]&b[c/5+c%5-9]&b[c/5-c%5-9]for c in map(ord,"DICE>3BQ")])
Run Code Online (Sandbox Code Playgroud)
简单表达的69个字符:
max([b[c/5-9]&b[c/5+c%5-9]&b[c/5-c%5-9]for c in map(ord,"DICE>3BQ")])
Run Code Online (Sandbox Code Playgroud)
mer*_*tor 10
当然,使用正则表达式返回0,1或2的函数(换行符仅用于避免滚动条):
sub V{$"='';$x='(1|2)';"@_"=~
/^(...)*$x\2\2|^..$x.\3.\3|$x..\4..\4|$x...\5...\5/?$^N:0}
Run Code Online (Sandbox Code Playgroud)
V(@b)例如,它可以被称为.
小智 10
w=:3 : '{.>:I.+./"1*./"1]1 2=/y{~2 4 6,0 4 8,i,|:i=.i.3 3'
Run Code Online (Sandbox Code Playgroud)
我不喜欢重复自己(水平/垂直和对角线),但我认为这是一个公平的开始.
C#w/LINQ:
public static int GetVictor(int[] b)
{
var r = Enumerable.Range(0, 3);
return r.Select(i => r.Aggregate(3, (s, j) => s & b[i * 3 + j])).Concat(
r.Select(i => r.Aggregate(3, (s, j) => s & b[j * 3 + i]))).Aggregate(
r.Aggregate(3, (s, i) => s & b[i * 3 + i]) | r.Aggregate(3, (s, i) => s & b[i * 3 + (2 - i)]),
(s, i) => s | i);
}
Run Code Online (Sandbox Code Playgroud)
策略:AND将行/列/对角线的每个元素与其他元素(以3作为种子)OR相加,以获得该子集的胜利者,并将它们全部放在一起.
哎呀:不知怎的,我误解了很多.这实际上是115个字符,而不是79个字符.
def t(b)[1,2].find{|p|[448,56,7,292,146,73,273,84].any?{|k|(k^b.inject(0){|m,i|m*2+((i==p)?1:0)})&k==0}}||false end
# Usage:
b = [ 1, 2, 1,
0, 1, 2,
1, 0, 2 ]
t(b) # => 1
b = [ 1, 1, 0,
2, 2, 2,
0, 2, 1 ]
t(b) # => 2
b = [ 0, 0, 1,
2, 2, 0,
0, 1, 1 ]
t(b) # => false
Run Code Online (Sandbox Code Playgroud)
和扩展代码,用于教育目的:
def tic(board)
# all the winning board positions for a player as bitmasks
wins = [ 0b111_000_000, # 448
0b000_111_000, # 56
0b000_000_111, # 7
0b100_100_100, # 292
0b010_010_010, # 146
0b001_001_001, # 73
0b100_010_001, # 273
0b001_010_100 ] # 84
[1, 2].find do |player| # find the player who's won
# for the winning player, one of the win positions will be true for :
wins.any? do |win|
# make a bitmask from the current player's moves
moves = board.inject(0) { |acc, square|
# shift it to the left and add one if this square matches the player number
(acc * 2) + ((square == player) ? 1 : 0)
}
# some logic evaluates to 0 if the moves match the win mask
(win ^ moves) & win == 0
end
end || false # return false if the find returns nil (no winner)
end
Run Code Online (Sandbox Code Playgroud)
我敢肯定这可以缩短,特别是大阵列以及可能用于获得玩家动作的位掩码的代码 - 这三元素让我感到烦恼 - 但我认为这对现在来说非常好.