井字游戏的最佳游戏


31

这个挑战是关于井字游戏,但它是在圆环上玩的。

怎么玩

要创建必要的游戏板,请首先使用常规的Tic Tac Toe游戏板。首先,通过连接左右边缘将其折叠成圆柱体。然后通过连接顶部和底部边缘将其折叠成环形。这是这种游戏板的简单可视化效果,其中包含一些操作(病漆技能!)。

井字环

井字游戏的规则与普通井字游戏的规则相同。每个玩家交替放置X和O。行,列或对角线中有3个相同符号的第一个获胜。

由于圆环很难观察到,因此我们只需将板子投影回纸上即可。现在我们可以像普通的井字游戏一样玩游戏了。唯一的区别是,您还可以用对角线中的3个相同的符号赢钱。例如,玩家1(X)赢得下一局。通过稍微改变圆环上的视图,您可以轻松看到这一点。

玩家1(X)获胜,因为一条折断的对角线上有3个X

如果您有兴趣,可以在Torus Games的Torus上玩Tic Tac Toe 。有Windows,Mac和Android版本。

最佳游戏

在这个挑战中,人们对最佳游戏感兴趣。最佳游戏是指两个玩家都扮演最佳策略的游戏。在常规的Tic Tac Toe棋盘上,最佳游戏总是以平局结束。令人着迷的是,在环形板上总是第一个玩家获胜。实际上,在圆环板上的游戏永远不会以平局告终(即使玩家玩的不是最佳状态)。

最佳策略非常容易:

  • 如果您可以通过放置符号赢钱,那就去做。
  • 否则,如果对手在一行/列/对角线中有两个符号,请尝试将其阻止。否则,请执行您想要的操作。
  • 否则,请执行您想要的操作。

每个最佳游戏都恰好由7个动作组成,这些动作可以用以下方式描述:

  1. 玩家1将X放置在棋盘上的任意位置(9个选择)
  2. 玩家2在棋盘上的任意位置放置一个O(8个选择)
  3. 玩家1将X放置在棋盘上的任意位置(7个选择)
  4. 玩家2的举动可能会被强制(1个选择),否则,他会将O放置在任何位置(6个选择)
  5. 玩家1的举动被迫(1选择)
  6. 玩家2陷入困境(玩家1可以通过两种不同方式获胜),因此玩家2必须以一种方式阻止玩家1(2个选择)
  7. 玩家1做出最后的举动并获胜(1个选择)

我们的投影板上有9 * 8 * 1 * 6 * 1 * 2 * 1 + 9 * 8 * 6 * 1 * 1 * 2 * 1 = 1728个不同的最佳游戏。在这里,您可以看到一种典型的最佳游戏:

最佳游戏的例子

如果我们用数字标记棋盘的每个单元0-8,我们可以用数字来描述这个游戏 3518207。首先,将X放置在单元格3(中间行,左列)中,而不是将O放置在单元格5中(中间行,右列)中,将X放置在单元格1中(上方行,中间列)中,...

使用此数字符号,我们自动生成了一个订单。现在,我们可以对所有1728个最佳游戏进行排序,然后得到以下列表:

Game 0000: 0123845
Game 0001: 0123854
Game 0002: 0124735
Game 0003: 0124753
Game 0004: 0125634
   ...
Game 0674: 3518207
   ...
Game 1000: 5167423
Game 1001: 5167432
Game 1002: 5168304
   ...
Game 1726: 8765034
Game 1727: 8765043

挑战

此列表是您工作的一部分。您将收到一个k介于0和1727之间的数字,并且您必须以k该已排序列表的数字符号返回该游戏。

编写一个函数或程序,将接收到的数字k(整数)计算为对应的游戏。您可以通过STDIN,命令行参数,提示或函数参数读取输入,并以可读格式(例如0123845[0, 1, 2, 3, 8, 4, 5])打印结果(7位数字),或使用字符串(人类可读格式)或整数(包含所有以10为底的数字)或任何数组/列表格式。

质询类型为代码高尔夫。因此,以最短的代码为准。


为什么玩家2的第一步必须与玩家1的第一步位于同一行或同一列?我脑子里玩了几局游戏,其中玩家2的第一步是在相同的对角线上,而它们遵循相同的最佳游戏模式。在我看来,环形棋盘的一方面是行,列和对角线在游戏中具有对称效果。
Runer112

@ Runer112大大简化了最佳策略。现在唯一的规则是,如果可以的话,阻挡对手,否则就做你想做的。
2015年

7
只是一个侧面评论:实际上,这里可能有更少的独特游戏。平移对称性使第一步的位置无关紧要(因为您始终可以将视线居中),因此除以9 ...然后旋转木板仅进行两次不同的第二步(对角线或相邻的正方形)...因此最多48种不同的游戏。如果考虑反射对称性,它会进一步下降。这个圆环版本比普通版本更无聊。打高尔夫球。
Orion 2015年

@orion实际上,圆环包裹着的事实并不能阻止我们将“ 0”视为圆环板上的“第一个”矩形,并在总体上区分所有九个域...然而,我们同意格林威治的“子午线0” ,而在地球的对面,我们可以将一只脚放在星期四的位置,而另一只脚则在星期三(当地时间差24小时!)–尽管地球是圆的并且没有一个“起点” ...
pawel.boczarski 2015年

@Rodney Nope,这是一个,而不是七个。尝试计算一下。
2015年

Answers:


6

JavaScript(ES6),266 308 317 334 341

返回字符串的函数。 编辑找到了函数M的算术解决方案(最后!)

F=(n,x=[],M=(a,b,t=-a-b)=>(a-b)%3?a<3&b<3?3+t:a>5&b>5?21+t:12+t:9+t+a%3*3)=>
[for(a of z='012345678')for(b of z)for(c of z)for(d of z) 
a-b&&c-a&&c-b&&(b-(y=M(a,c))?d==y:d-a&&d-b&&d-c)&&(
f=M(c,e=M(b,d)),g=M(a,e),g<f?[f,g]=[g,f]:0,r=a+b+c+d+e,x.push(r+f+g,r+g+f))]
&&x[n]

非常幼稚,可以通过多种方式将其缩短。它仅枚举所有可能的法律价值,并返回在n处找到的内容。M函数返回两个像元之间的位置,这是阻止对方玩家的强制动作。

更具可读性

F=(n,x=[],
  M=(a,b,t=-a-b)=>(a-b)%3? 
     a<3&b<3?
       3+t // first row
       :a>5&b>5?
          21+t // last row
          :12+t // middle row and diags
     :9+t+a%3*3 // columns
  )=>
  [for(a of z='012345678') // enumerate the first 4 moves
     for(b of z)
       for(c of z)
         for(d of z) 
           a-b&&c-a&&c-b // avoid duplicates
           &&(b-(y=M(a,c))?d==y:d-a&&d-b&&d-c) // and check if d must block a-c or it's free
           &&(
             e=M(b,d), // forced to block b-d
             f=M(c,e),g=M(a,e),g<f?[f,g]=[g,f]:0, // f and g could be in the wrong order
             r=a+b+c+d+e, // start building a return string
             x.push(r+f+g,r+g+f) // store all values in x
  )]&&x[n] // return value at requested position

3

八度,467369363309297字符

297:

global t=0*(1:9)m=dec2bin([15;113;897;1170;1316;1608;2370;2216;2580])-48 a;
function g(s,p)global a t m;
if nnz(s)<8&&any((t==1)*m>2)a=[a;s];return;end;q=t==3-p;
(r=sort(~q.*(1:9)*m(:,find([3 1]*([q;t==p]*m)==6)')))||(r=find(~t));
for i=r t(i)=p;g([s i+47],3-p);t(i)=0;end;end;g('',1);f=@(n)a(n+1,:);

唯一相关的变化是,我们从不检查当前玩家是否可以赢,仅检查对手下一轮获胜的可能性。由于玩家1可以赢的唯一回合是回合7,因此这是算法产生非最佳游戏的唯一位置,但是很容易过滤掉这种情况。我们只是简单地验证所产生的每个游戏是否被玩家1赢了-如果没有,则第7步的举动是不正确的,因此我们不会将此游戏添加到最佳游戏表中。

(此规则产生的游戏中有一半是错误的,,在第7回合中,玩家1总是有两种可能阻止玩家2,但只有一种可能使他立即获胜)。

使用:

$ octave
octave:1>> source script.m
octave:2>> f(634)
ans = 3270148

未经处理的代码如下所示:

 global t=0*(1:9);
 global m=dec2bin([15;113;897;1170;1316;1608;2370;2216;2580])-48;
 global allgames;
 allgames=[];

 function r=canbewon(by)
  global t m
  q=[t==by;t==(3-by)]*m;
  g=(find([3 1]*q==6))';
  r=sort((~(t==by).*(1:9)) * m(:,g));
 end

 function games_starting_with(s)
 global allgames t;
 if 7==numel(s) && any((t==1)*m==3) # it's 7th move and first player won
  allgames=[allgames;s];
  return;
 end;
 poss=(find(~t));                  # for now all free slots are possible
 player=1+mod(numel(s),2);
 moves = canbewon(3-player);
 if numel(moves) poss=moves; end;  # ... no, we must block the other player
 for i=poss
  t(i)=player;
  games_starting_with([s char(i+47)]);
  t(i)=0;
 end
end

games_starting_with('');
f=@(n)(allgames(n+1,:));

1
小提示:如果旧版本使用相同的逻辑,则可以
删掉
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.