Альфа бета шашки - один и тот же игрок всегда выигрывает
Я внедряю простой AI для проверки, используя альфа-бета (минимаксный) поиск, и завершаю реализацию. У меня есть два игрока, 1 и 2, но независимо от того, какую глубину я использую для своего поиска (даже если глубина 1> 2), игрок 2, кажется, выигрывает. Я не могу понять, что я делаю неправильно. Есть ли у вас мысли о том, что может быть причиной этого? Я не уверен, что моя реализация альфа-бета-поиска полностью верна или я что-то неправильно понимаю. Игра работает правильно, просто результаты не такие, как ожидалось. Пожалуйста, дайте мне знать, если я могу уточнить это каким-либо образом. Ваша помощь очень ценится! Я убрал графический интерфейс для целей этого вопроса, но это ни на что не должно повлиять. Спасибо!
Board - это класс, имеющий атрибут board, представляющий собой массив 8x8 целых. 0 пустое место
1 белый кусок
2 красных куска
3 белых короля
4 красных короля
class Player:
def __init__(self, id, depth):
self.id = id
self.depth = depth
def board_eval(self, board):
if len(board.get_moves(self.id)) == 0:
return float('inf')*-1
else:
red = 0
redK = 0
white = 0
whiteK = 0
for r in range(len(board.board[0])):
for c in range(len(board.board[0])):
if board.board[r][c]>0:
if board.board[r][c]==1:
white+=1
elif board.board[r][c]==2:
red+=1
elif board.board[r][c]==3:
whiteK+=1
elif board.board[r][c]==4:
redK+=1
if self.id == 1:
return white+whiteK-red-redK
else:
return red+redK-white-whiteK
def minimax (self, board, depth, alpha, beta, player):
board_value = self.board_eval(board)
if depth == 0 or board_value == float('inf') or board_value == float('inf')*-1:
return board_value
if self.id == player:
for poss_board in board.get_moves(player):
alpha = max(alpha, self.minimax(poss_board, depth - 1, alpha, beta, (player%2)+1))
if (alpha >= beta):
break
return alpha
else:
for poss_board in board.get_moves(player): #TODO: should this be the other player? pretty sure no
beta = min(beta, self.minimax(poss_board, depth - 1, alpha, beta, (player%2)+1))
if (beta <= alpha):
break
return beta
def update_board(self, board):
best_move = None
best_score = float('inf') * -1
for poss_move in board.get_moves(self.id):
alpha = self.minimax(poss_move, self.depth-1, best_score, float('inf'), (self.id%2)+1)
if best_move is None or alpha > best_score:
best_move = poss_move
best_score = alpha
elif alpha == best_score and random.random() <= 0.3: #arbitrary randomness if multiple best moves
best_move = poss_move
return best_move
class Game:
def __init__(self):
self.board = Board()
self.p1 = Player(1, 4) #id, depth
self.p2 = Player(2, 2)
self.height=800
self.width=800
self.win= GraphWin("Checkerboard", self.width, self.height)
self.lag_win = GraphWin("Prev Board", self.width, self.height)
self.lag_board = copy.deepcopy(self.board)
self.cell_size = 50 # Height and width of checkerboard squares.
self.offset_x = (self.width - 8*self.cell_size) / 2
self.offset_y = (self.height - 8*self.cell_size) / 2
def play(self):
while True:
self.board = self.p1.update_board(self.board)
if self.board is None: #print("Game over, player 2 wins\n")
return 2
self.board = self.p2.update_board(self.board)
if self.board is None: #print("Game over, player 1 wins\n")
return 1
game = Game()
winner = game.play()
1 ответ
Ваш board_eval, похоже, возвращает счет по отношению к игроку, но минимаксная часть кода, кажется, предполагает абсолютный счет. Что произойдет, если вы устраните это if
в board_eval
и просто return white+whiteK-red-redK
?