def alphabeta_minimax(self, minimax_branch, is_maxing_white, alpha, beta): if minimax_branch == 0 or not self.board.legal_moves: return evaluate_board(self.board) self.total_score_computer = -1e8 if is_maxing_white is True else 1e8 for move in self.board.legal_moves: self.board.push(move) provincial_score = self.alphabeta_minimax(minimax_branch - 1, not is_maxing_white, alpha, beta) if is_maxing_white: self.total_score_computer = max(self.total_score_computer, provincial_score) alpha = max(alpha, self.total_score_computer) else: self.total_score_computer = min(self.total_score_computer, provincial_score) beta = min(beta, self.total_score_computer) self.board.pop() if beta <= alpha: break return self.total_score_computer
def mp_max_search(inputs): """Special case of the first move for multiprocessing.""" board = inputs[0] move = inputs[1] token = inputs[2] opp_token = inputs[3] temp_board = update_board(board, move, token) winner = evaluate_board(temp_board) if winner != TOKENS.BLANK: value = get_value(winner, token, opp_token) else: _, value = mini_search(temp_board, token, opp_token) return move, value
def mini_search(board, token, opp_token): """Search for the best move your opponent can make.""" best_value = None best_move = None for move in possible_moves(board): temp_board = update_board(board, move, opp_token) winner = evaluate_board(temp_board) if winner != TOKENS.BLANK: value = get_value(winner, token, opp_token) else: _, value = max_search(temp_board, token, opp_token) if best_value is None or value < best_value: best_value = value best_move = move return best_move, best_value
def play(game_board, x_player, o_player): """Play a game.""" players = [x_player, o_player] active_player = 0 winner = TOKENS.BLANK while winner is TOKENS.BLANK: print("~~~~~~~~~~Turn {}~~~~~~~~~~".format(active_player)) print_board(game_board) game_board = players[active_player % len(players)].play(game_board) winner = evaluate_board(game_board) active_player += 1 print("~~~~~~~~~GAME OVER~~~~~~~~~~") print_board(game_board) print("{}wins!".format(value_to_str(winner)))
def minimax(self, depth, is_maxing_white, alpha, beta): # if board in cache if self.hash_board(depth, is_maxing_white) in self.board_caches: self.cache_hit += 1 return self.board_caches[self.hash_board(depth, is_maxing_white)] self.cache_miss += 1 # if depth is 0 or game is over if depth == 0 or not self.board.legal_moves: self.board_caches[self.hash_board( depth, is_maxing_white)] = evaluate_board(self.board) return self.board_caches[self.hash_board(depth, is_maxing_white)] # else best_score = -1e8 if is_maxing_white else 1e8 for move in self.board.legal_moves: self.board.push(move) local_score = self.minimax(depth - 1, not is_maxing_white, alpha, beta) self.board_caches[self.hash_board( depth - 1, not is_maxing_white)] = local_score if is_maxing_white: best_score = max(best_score, local_score) alpha = max(alpha, best_score) else: best_score = min(best_score, local_score) beta = min(beta, best_score) self.board.pop() if beta <= alpha: break self.board_caches[self.hash_board(depth, is_maxing_white)] = best_score return self.board_caches[self.hash_board(depth, is_maxing_white)]