我正在尝试使用AI创建名为Connect Four的游戏,它在python中使用alpha-beta修剪算法。以下是我设法做的代码:
# -*- coding: utf-8 -*-
import sys
class ConnectFour:
def __init__(self):
self.board = [[],[],[],[],[],[]]
for i in range(7):
for j in range(6):
self.board[j].append(" ")
self.moves = 0
self.colstack = [0,0,0,0,0,0,0]
self.node = 0
self.move = 0
def PrintGameBoard(self):
print(' 0 1 2 3 4 5 6')
for i in range(5, -1, -1):
print('|---|---|---|---|---|---|---|')
print("| ",end="")
for j in range(7):
print(self.board[i][j],end="")
if j != 6:
print(" | ",end="")
else:
print(" |")
print('`---------------------------´')
def CanPlay(self, col):
return self.colstack[col] < 6
def Play(self, col, board):
board[self.colstack[col]][col] = 2
self.colstack[col] += 1
self.moves += 1
return board
def IsWinning(self, currentplayer):
for i in range(6):
for j in range(4):
if self.board[i][j] == currentplayer and self.board[i][j+1] == currentplayer and self.board[i][j+2] == currentplayer and self.board[i][j+3] == currentplayer:
return True
for i in range(3):
for j in range(7):
if self.board[i][j] == currentplayer and self.board[i+1][j] == currentplayer and self.board[i+2][j] == currentplayer and self.board[i+3][j] == currentplayer:
return True
for i in range(3):
for j in range(4):
if self.board[i][j] == currentplayer and self.board[i+1][j+1] == currentplayer and self.board[i+2][j+2] == currentplayer and self.board[i+3][j+3] == currentplayer:
return True
for i in range(3,6):
for j in range(4):
if self.board[i][j] == currentplayer and self.board[i-1][j+1] == currentplayer and self.board[i-2][j+2] == currentplayer and self.board[i-3][j+3] == currentplayer:
return True
return False
def AlphaBeta(self, alpha, beta):
self.node += 1
if self.moves == 42:
return 0
for col in range(7):
if self.CanPlay(col) and self.IsWinning(2):
return (43 - self.moves)/2
max = (41 - self.moves)/2
if beta > max:
beta = max
if alpha >= beta:
return beta
for col in range(7):
if self.CanPlay(col):
self.board[self.colstack[col]][col] = 2
self.move = col
score = -self.AlphaBeta(-alpha, -beta)
if score >= beta:
return score
elif score > alpha:
alpha = score
self.board[self.colstack[col]][col] = " "
def Solve(self, table, week=False):
self.node = 0
self.board = table
if week:
self.AlphaBeta(-1, 1)
self.board = self.Play(self.move, table)
return self.board
else:
self.AlphaBeta(-21, 21)
self.board = self.Play(self.move, table)
return self.board
def PlayerMove(self, table):
self.board = table
try:
allowedmove = False
while not allowedmove:
print("Choose a column where you want to make your move (0-6): ",end="")
col =input()
if self.CanPlay(int(col)):
self.board[self.colstack[int(col)]][int(col)] = 1
self.moves += 1
self.colstack[int(col)] += 1
allowedmove = True
else:
print("This column is full")
except (NameError, ValueError, IndexError, TypeError, SyntaxError) as e:
print("Give a number as an integer between 0-6!")
else:
return self.board
def PlayerMark():
print("Player 1 starts the game")
mark = ''
while not (mark == "1" or mark == "2"):
print('Do you want to be 1 or 2: ',end="")
mark = input()
if mark == "1":
return 1
else:
return 2
def PlayAgain():
print('Do you want to play again? (yes or no) :',end="")
return input().lower().startswith('y')
def main():
sys.setrecursionlimit(2000)
print("Connect4")
while True:
mark = PlayerMark()
connectfour = ConnectFour()
if mark==1:
print("You are going to start the game\r\n\r\n")
else:
print("Computer (negamax) starts the game")
gameisgoing = True
table = [[],[],[],[],[],[]]
for i in range(7):
for j in range(6):
table[j].append(" ")
while gameisgoing:
connectfour.PrintGameBoard()
if mark == 1:
table = connectfour.PlayerMove(table)
if connectfour.IsWinning(1):
connectfour.PrintGameBoard()
print('You won the game!')
gameisgoing = False
else:
if connectfour.moves==42:
connectfour.PrintGameBoard()
print('Game is tie')
break
else:
mark = 2
else:
move = connectfour.Solve(table)
if connectfour.IsWinning(2):
connectfour.PrintGameBoard()
print('Computer won the game')
gameisgoing = False
else:
if connectfour.moves==42:
connectfour.PrintGameBoard()
print('Game is tie')
break
else:
mark = 1
if not PlayAgain():
print("Game ended")
break
if __name__ == '__main__':
main()
我不确定算法是否正常工作,但问题是我得到了RecursionError:相比之下,超出了最大重新调整深度。如果我增加recursionlimit,我会得到大约10000 MemoryError:Stack Overflow。我认为问题在于我的计算机处理的状态太多了。这就是为什么我将negamax算法改为alpha-beta修剪但似乎仍有许多状态。有没有一种有效的技术,算法搜索例如最大深度10和仍然计算机几乎是原则。我在等你的解决方案。