作为一个项目,我正在用Python实现MinMax Tic Tac Toe AI。我进一步实现了Alpha-Beta修剪,并提出了这个庞大的代码。
代码:-
class TicTacToe:
game_state = [[' ',' ',' '],
[' ',' ',' '],
[' ',' ',' ']]
players = ['X','O']
def __init__(self,player_idx=0):
if(player_idx>1 or player_idx<0):
raise Exception("player index can only be 0 or 1")
self.current_player=player_idx
def check_current_state(self):
# Check if draw
draw_flag = 0
for i in range(3):
for j in range(3):
if self.game_state[i][j] is ' ':
draw_flag = 1
if draw_flag is 0:
return None, "Draw"
# Check horizontals
if (self.game_state[0][0] == self.game_state[0][1] and self.game_state[0][1] == self.game_state[0][2] and self.game_state[0][0] is not ' '):
return self.game_state[0][0], "Done"
if (self.game_state[1][0] == self.game_state[1][1] and self.game_state[1][1] == self.game_state[1][2] and self.game_state[1][0] is not ' '):
return self.game_state[1][0], "Done"
if (self.game_state[2][0] == self.game_state[2][1] and self.game_state[2][1] == self.game_state[2][2] and self.game_state[2][0] is not ' '):
return self.game_state[2][0], "Done"
# Check verticals
if (self.game_state[0][0] == self.game_state[1][0] and self.game_state[1][0] == self.game_state[2][0] and self.game_state[0][0] is not ' '):
return self.game_state[0][0], "Done"
if (self.game_state[0][1] == self.game_state[1][1] and self.game_state[1][1] == self.game_state[2][1] and self.game_state[0][1] is not ' '):
return self.game_state[0][1], "Done"
if (self.game_state[0][2] == self.game_state[1][2] and self.game_state[1][2] == self.game_state[2][2] and self.game_state[0][2] is not ' '):
return self.game_state[0][2], "Done"
# Check diagonals
if (self.game_state[0][0] == self.game_state[1][1] and self.game_state[1][1] == self.game_state[2][2] and self.game_state[0][0] is not ' '):
return self.game_state[1][1], "Done"
if (self.game_state[2][0] == self.game_state[1][1] and self.game_state[1][1] == self.game_state[0][2] and self.game_state[2][0] is not ' '):
return self.game_state[1][1], "Done"
return None, "Not Done"
def evaluate(self):
a,b=self.check_current_state()
if(a != None and b == "Done" and a == 'X'):
return 1
elif(a != None and b == "Done" and a == 'O'):
return -1
elif(a == None and b == "Draw"):
return 0
else:
return 6
def MiniMax(self,depth,isMax):
score=self.evaluate()
if(score==1):
return score;
if(score==-1):
return score;
if(score==0):
return score
if(isMax==True):
best=-100
for i in range(3):
for j in range(3):
if(self.game_state[i][j]==' '):
self.game_state[i][j]='X'
best=max(best,self.MiniMax(depth+1,False))
self.game_state[i][j]=' '
return best
elif(isMax==False):
best=100
for i in range(3):
for j in range(3):
if(self.game_state[i][j]==' '):
self.game_state[i][j]='O'
best=min(best,self.MiniMax(depth+1,True))
self.game_state[i][j]=' '
return best
def best_move(self):
best=-100
r=-1
c=-1
for i in range(3):
for j in range(3):
if(self.game_state[i][j]==' '):
self.game_state[i][j]='X'
move = self.MiniMax(0, False)
self.game_state[i][j]=' '
if(move>best):
r=i
c=j
best=move
return r,c
def play_move(self, block_num):
if self.game_state[int((block_num-1)/3)][(block_num-1)%3] is ' ' and self.current_player==1:
self.game_state[int((block_num-1)/3)][(block_num-1)%3] = self.players[self.current_player]
self.current_player=1-self.current_player
elif self.current_player==0:
i,j=self.best_move()
self.game_state[i][j] = self.players[self.current_player]
self.current_player=1-self.current_player
elif self.game_state[int((block_num-1)/3)][(block_num-1)%3] != ' ' and self.current_player==1:
block_num = int(input("Block is not empty, ya blockhead! Choose again: "))
self.play_move(block_num)
def print_board(self):
print('----------------')
print('| ' + str(self.game_state[0][0]) + ' || ' + str(self.game_state[0][1]) + ' || ' + str(self.game_state[0][2]) + ' |')
print('----------------')
print('| ' + str(self.game_state[1][0]) + ' || ' + str(self.game_state[1][1]) + ' || ' + str(self.game_state[1][2]) + ' |')
print('----------------')
print('| ' + str(self.game_state[2][0]) + ' || ' + str(self.game_state[2][1]) + ' || ' + str(self.game_state[2][2]) + ' |')
print('----------------')
def play(self):
current_state = "Not Done"
print("New Game!")
self.print_board()
winner = None
while current_state == "Not Done":
if(self.current_player==1):
block_choice = int(input(str(self.players[self.current_player]) + "s Turn! Choose where to place (1 to 9): "))
self.play_move(block_choice)
elif(self.current_player==0):
self.play_move(1)
self.print_board()
winner, current_state = self.check_current_state()
if winner is not None:
print(str(winner) + " won!")
if current_state is "Draw":
print("Draw!")
game=TicTacToe()
game.play()
我不知道为什么,但是这段代码给出了问题。
请帮帮我。
答案 0 :(得分:0)
您有缩进问题,我已为您解决:
class TicTacToe:
game_state = [[' ',' ',' '],
[' ',' ',' '],
[' ',' ',' ']]
players = ['X','O']
def __init__(self,player_idx=0):
if(player_idx>1 or player_idx<0):
raise Exception("player index can only be 0 or 1")
self.current_player=player_idx
def check_current_state(self):
# Check if draw
draw_flag = 0
for i in range(3):
for j in range(3):
if self.game_state[i][j] is ' ':
draw_flag = 1
if draw_flag is 0:
return None, "Draw"
# Check horizontals
if (self.game_state[0][0] == self.game_state[0][1] and self.game_state[0][1] == self.game_state[0][2] and self.game_state[0][0] is not ' '):
return self.game_state[0][0], "Done"
if (self.game_state[1][0] == self.game_state[1][1] and self.game_state[1][1] == self.game_state[1][2] and self.game_state[1][0] is not ' '):
return self.game_state[1][0], "Done"
if (self.game_state[2][0] == self.game_state[2][1] and self.game_state[2][1] == self.game_state[2][2] and self.game_state[2][0] is not ' '):
return self.game_state[2][0], "Done"
# Check verticals
if (self.game_state[0][0] == self.game_state[1][0] and self.game_state[1][0] == self.game_state[2][0] and self.game_state[0][0] is not ' '):
return self.game_state[0][0], "Done"
if (self.game_state[0][1] == self.game_state[1][1] and self.game_state[1][1] == self.game_state[2][1] and self.game_state[0][1] is not ' '):
return self.game_state[0][1], "Done"
if (self.game_state[0][2] == self.game_state[1][2] and self.game_state[1][2] == self.game_state[2][2] and self.game_state[0][2] is not ' '):
return self.game_state[0][2], "Done"
# Check diagonals
if (self.game_state[0][0] == self.game_state[1][1] and self.game_state[1][1] == self.game_state[2][2] and self.game_state[0][0] is not ' '):
return self.game_state[1][1], "Done"
if (self.game_state[2][0] == self.game_state[1][1] and self.game_state[1][1] == self.game_state[0][2] and self.game_state[2][0] is not ' '):
return self.game_state[1][1], "Done"
return None, "Not Done"
def evaluate(self):
a,b=self.check_current_state()
if(a != None and b == "Done" and a == 'X'):
return 1
elif(a != None and b == "Done" and a == 'O'):
return -1
elif(a == None and b == "Draw"):
return 0
else:
return 6
def MiniMax(self,depth,isMax):
score=self.evaluate()
if(score==1):
return score;
if(score==-1):
return score;
if(score==0):
return score
if(isMax==True):
best=-100
for i in range(3):
for j in range(3):
if(self.game_state[i][j]==' '):
self.game_state[i][j]='X'
best=max(best,self.MiniMax(depth+1,False))
self.game_state[i][j]=' '
return best
elif(isMax==False):
best=100
for i in range(3):
for j in range(3):
if(self.game_state[i][j]==' '):
self.game_state[i][j]='O'
best=min(best,self.MiniMax(depth+1,True))
self.game_state[i][j]=' '
return best
def best_move(self):
best=-100
r=-1
c=-1
for i in range(3):
for j in range(3):
if(self.game_state[i][j]==' '):
self.game_state[i][j]='X'
move = self.MiniMax(0, False)
self.game_state[i][j]=' '
if(move>best):
r=i
c=j
best=move
return r,c
def play_move(self, block_num):
if self.game_state[int((block_num-1)/3)][(block_num-1)%3] is ' ' and self.current_player==1:
self.game_state[int((block_num-1)/3)][(block_num-1)%3] = self.players[self.current_player]
self.current_player=1-self.current_player
elif self.current_player==0:
i,j=self.best_move()
self.game_state[i][j] = self.players[self.current_player]
self.current_player=1-self.current_player
elif self.game_state[int((block_num-1)/3)][(block_num-1)%3] != ' ' and self.current_player==1:
block_num = int(input("Block is not empty, ya blockhead! Choose again: "))
self.play_move(block_num)
def print_board(self):
print('----------------')
print('| ' + str(self.game_state[0][0]) + ' || ' + str(self.game_state[0][1]) + ' || ' + str(self.game_state[0][2]) + ' |')
print('----------------')
print('| ' + str(self.game_state[1][0]) + ' || ' + str(self.game_state[1][1]) + ' || ' + str(self.game_state[1][2]) + ' |')
print('----------------')
print('| ' + str(self.game_state[2][0]) + ' || ' + str(self.game_state[2][1]) + ' || ' + str(self.game_state[2][2]) + ' |')
print('----------------')
def play(self):
current_state = "Not Done"
print("New Game!")
self.print_board()
winner = None
while current_state == "Not Done":
if(self.current_player==1):
block_choice = int(input(str(self.players[self.current_player]) + "s Turn! Choose where to place (1 to 9): "))
self.play_move(block_choice)
elif(self.current_player==0):
self.play_move(1)
self.print_board()
winner, current_state = self.check_current_state()
if winner is not None:
print(str(winner) + " won!")
if current_state is "Draw":
print("Draw!")
game=TicTacToe()
game.play()