蟒2:399个 401 349 333 317 370字节
2x错误修复:贡献给l4m2
-52个字符:贷记入undergroundmonorail
-16个字元:归功于Jonathan Frech
-26个字符:贷记到user202729
def f(b):
t=4,9,2,3,5,7,8,1,6;n=lambda k:[t[i]for i,j in enumerate(b)if j==k];p,o,a,I=n(2),n(1),n(0),t.index
for i in p:
for j in p:
for k in a:
if i+j+k==15and-j+i:return I(k)
for i in o:
for j in o:
for k in a:
if i+j+k==15and-j+i:return I(k)
for i in 9,3,7,1:
if i in a and 5 in p:return I(i)
for i in 5,4,2,8,6:
if i in a:return I(i)
return I(a[0])
在线尝试!
在上学期的线性代数课程的第一天,我精明的研究生导师建议,如果您将井字游戏板表示为矩阵:
4 | 9 | 2
--+---+--
3 | 5 | 7
--+---+--
8 | 1 | 6
那么连续获得三个等于在[1,9]范围内选择三个加起来为15的数字。此答案利用了这个想法。该函数获取一个包含九个代表板的数字的列表。0表示有空位,1被对手占据,2表示程序进行的上一局。前三行指出程序选择了哪些数字(p),反对者选择了哪些数字(o),并且仍然可用(a)。然后,它查看可用的数字,看看是否有任何数字与已经选择的两个数字相加,得出15个数字。如果是这样,它将选择那个正方形并赢。如果没有立即获胜的举动,它将检查对手是否可以使用相同的方法获胜。如果他们能,那将是他们获胜的地方。如果既没有获胜也没有阻止举动,它会在一个角落移动。这样可以防止傻瓜伴侣:
- - -
- X -
- - -
- O - # Bad Move
- X -
- - -
- O X
- X -
- - -
- O X
- X -
O - -
- O X
- X -
O - X
如果这些情况都没有发生,它将任意选择一个正方形。函数输出一个数字[0,8],表示由算法选择的0索引平方。
编辑:该算法现在优先于对角线优先选择中心,这将防止l4m2和相关策略指出的另一个傻瓜交配可能性。
编辑:为明确起见,该函数以阵列形式接收板,并在[0,8]上以整数形式输出移动。由于此I / O策略非常笨拙,因此下面的包装脚本使它更具交互性。它只接受一个命令行参数,如果玩家先进入,则应为1;如果程序先进入,则应为0。
import sys
def f(b):
t=4,9,2,3,5,7,8,1,6;n=lambda k:[t[i]for i,j in enumerate(b)if j==k];p,o,a,I=n(2),n(1),n(0),t.index
for i in p:
for j in p:
for k in a:
if i+j+k==15and-j+i:return I(k)
for i in o:
for j in o:
for k in a:
if i+j+k==15and-j+i:return I(k)
for i in 9,3,7,1:
if i in a and 5 in p:return I(i)
for i in 5,4,2,8,6:
if i in a:return I(i)
return I(a[0])
board = [0,0,0,0,0,0,0,0,0]
rep = {0:"-",1:"X",2:"O"}
turn = int(sys.argv[1])
while True:
for i in range(3):
print rep[board[i*3]]+" "+rep[board[i*3+1]]+" "+rep[board[i*3+2]]
print
if turn:
move = int(raw_input("Enter Move [0-8]: "))
else:
move = f(board)
board[move] = turn+1
turn = (turn+1)%2
we can assume that all previous moves of the 2nd player were also played by our engine