在井字游戏中迷路


18

编写一个将播放Misère井字游戏的程序。也就是说,目标是迫使对手连续三局。

在标准输入上接受“ X”或“ O”(字母,不是零),以确定程序将以哪一侧播放。然后在回合中输出个位数,直到对手结束,直到对手结束(X总是先行)。确定赢家后,输出X或O代表谁,或D代表平局。例如,如果O连续获得3,则X获胜。

假设木板编号如下:

0|1|2
-----
3|4|5
-----
6|7|8

理想情况下,解决方案将是最佳的,并且永远不会失败。像井字游戏一样,完美的比赛总是会导致平局。如果遵守上述协议,我可以针对各种可能的策略自动测试提交内容。

优胜者是最短的代码。如果它从同样好的动作中随机选择,则会获得加分,使它变得更加不可预测。

Answers:


10

Python,383个字符

M=[21,1344,86016,4161,16644,66576,65793,4368]
X=lambda B,k:any(m*k==B&m*3for m in M)
def S(B):
 if X(B,2):return 1,
 M=[i for i in range(0,18,2)if B>>i&3<2]
 return max((-S((B|3<<i)^87381)[0],i)for i in M)if M else(0,)
r='D'
c=ord(raw_input())&1
B=0
for i in range(9):
 if i&1==c:m=S(B^c*87381)[1];print m/2;B|=3-c<<m
 else:
  B|=2+c<<input()*2
  if X(B,2+c):r='XO'[c];break
print r

该板B被表示为使用每平方两个位,用一个整数0001代表空的,10代表O和11表示X. M是一组位掩码的与01在丢失的三元组(的斑点21= 0b010101=顶行等) X,如果任何丢失单位计算k存在于板上的三元组。S会执行minimax搜索X的最佳移动,并返回一对得分(1 =胜利,-1 =失败,0 =平局)和平方指数。 ^87381(= ^0b010101010101010101)翻转X和O,同时保持空白正方形不变。

电脑永远不会丢失,所以我不需要包括这张支票:)。

可能存在一个更容易/更短的基于规则的算法,但这是可行的。


鬼nea偷偷摸摸的按位巫术+1
Rohan Jhunjhunwala
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.