def evaluateLeaf(self, leaf): # implement done if leaf.done == 0: for move in Reversi.valid_moves(leaf.state, -leaf.turn): newNode = Node(leaf.state.copy(), -leaf.turn, move) Reversi.move(newNode.state, newNode.turn, *move) if self.getID(newNode.state) not in self.tree: # redundant? newNode.calculate_stats() self.addNode(newNode) leaf.edges.append(newNode) else: # making multiple paths to same node? backFill? leaf.edges.append(self.tree[self.getID(newNode.state)]) del newNode else: pass
def play(x, y): Reversi.move(game.board, game.turn, x, y) game.turn *= -1 game.update_mboard() game_over, white_total, black_total = Reversi.check_board(game.board, game.turn) if game_over: if white_total == black_total: print("Draw: {} / {}".format(white_total, black_total)) elif white_total > black_total: print("White wins: {} / {}".format(white_total, black_total)) elif white_total < black_total: print("Black wins: {} / {}".format(black_total, white_total)) return False else: return True
def minimax(cls, board, depth, maximizingPlayer, player, turn, alpha, beta): if depth == 0 or not Reversi.valid_moves(board, turn): game_over, white_total, black_total = Reversi.check_board( board, turn) if game_over: if white_total == black_total: return 1, [] elif white_total > black_total: return player * 100, [] elif white_total < black_total: return player * -100, [] else: if player == 1: return white_total / black_total, [] elif player == -1: return black_total / white_total, [] elif maximizingPlayer: maxv = -1000000 for x, y in Reversi.valid_moves(board, turn): tboard = board.copy() Reversi.move(tboard, turn, x, y) cmax, dlist = cls.minimax(tboard, depth - 1, False, player, -turn, alpha, beta) if cmax > maxv: maxv = cmax xmax, ymax = x, y alpha = max(alpha, cmax) if beta <= alpha: break dlist.insert(0, (xmax, ymax)) return maxv, dlist else: minv = 1000000 for x, y in Reversi.valid_moves(board, turn): tboard = board.copy() Reversi.move(tboard, turn, x, y) cmin, dlist = cls.minimax(tboard, depth - 1, True, player, -turn, alpha, beta) if cmin < minv: minv = cmin xmin, ymin = x, y beta = min(beta, cmin) if beta <= alpha: break dlist.insert(0, (xmin, ymin)) return minv, dlist
def evaluateLeaf(self, leaf, value): # implement done if leaf.done == 0: value, policy = self.get_preds(leaf.state, -leaf.turn) for move in Reversi.valid_moves(leaf.state, -leaf.turn): #newNode = Node(leaf.state.copy(), -leaf.turn, move) newState = leaf.state.copy() Reversi.move(newState, -leaf.turn, *move) if self.getID(newState) not in self.tree: # redundant? newNode = Node(newState, -leaf.turn) #newNode.calculate_stats() self.addNode(newNode) else: # making multiple paths to same node? backFill? newNode = self.tree[self.getID(newState)] newEdge = Edge(leaf, newNode, policy[move[0]][move[1]], -leaf.turn, move) leaf.edges.append(newEdge) else: pass return value
def calculate_stats(self): game_over, white_total, black_total = Reversi.check_board( self.state, self.turn) if game_over: if white_total == black_total: value = 1 elif white_total > black_total: value = self.turn * 100 self.done = 1 elif white_total < black_total: value = self.turn * -100 self.done = 1 else: if self.turn == 1: value = white_total / black_total elif self.turn == -1: value = black_total / white_total self.update_stats(value)
def move(self, board): x, y = random.choice(Reversi.valid_moves(board, self.player)) return x, y
break dlist.insert(0, (xmax, ymax)) return maxv, dlist else: minv = 1000000 for x, y in Reversi.valid_moves(board, turn): tboard = board.copy() Reversi.move(tboard, turn, x, y) cmin, dlist = cls.minimax(tboard, depth - 1, True, player, -turn, alpha, beta) if cmin < minv: minv = cmin xmin, ymin = x, y beta = min(beta, cmin) if beta <= alpha: break dlist.insert(0, (xmin, ymin)) return minv, dlist def move(self, board): x, y = self.minimax(board, self.depth, True, self.player, self.player, -1000000, 1000000)[1][0] return x, y if __name__ == "__main__": game = Reversi() player = AI_minimax(-1) print(player.move(game.board))
gfxdraw.filled_circle(win, x * (pix + linew) + half, y * (pix + linew) + half, half - 6, white) gfxdraw.aacircle(win, x * (pix + linew) + half, y * (pix + linew) + half, half - 6, black) elif board[x][y] == -1: gfxdraw.filled_circle(win, x * (pix + linew) + half, y * (pix + linew) + half, half - 6, black) gfxdraw.aacircle(win, x * (pix + linew) + half, y * (pix + linew) + half, half - 6, black) for x in range(8): for y in range(8): if mboard[x][y] == turn: gfxdraw.aacircle(win, x * (pix + linew) + half, y * (pix + linew) + half, half - 6, grey) pygame.display.update() if __name__ == "__main__": game = Reversi() game.update_mboard() def play(x, y): Reversi.move(game.board, game.turn, x, y) game.turn *= -1 game.update_mboard() game_over, white_total, black_total = Reversi.check_board(game.board, game.turn) if game_over: if white_total == black_total: print("Draw: {} / {}".format(white_total, black_total)) elif white_total > black_total: print("White wins: {} / {}".format(white_total, black_total)) elif white_total < black_total: print("Black wins: {} / {}".format(black_total, white_total)) return False