Last active
December 7, 2021 19:46
-
-
Save luccabb/a3cfadcc865ffab1bc3eb2c535b4cbec to your computer and use it in GitHub Desktop.
Negamax function in python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def negamax( | |
board: chess.Board, | |
depth: int, | |
player: int) -> Tuple[Union[int, chess.Move]]: | |
""" | |
This functions receives a board, depth and a player; and it returns | |
the best move for the current board based on how many depths we're looking ahead | |
and which player is playing. For every move we will do the recursion until | |
leaf nodes and evaluate all leaf lodes. | |
OBS: | |
- We only need to evaluate the value for leaf nodes because they are our final states | |
of the board and therefore we need to use their scores to decide the best move. | |
Arguments: | |
- board: chess board state | |
- depth: how many depths we want to calculate for this board | |
- player: player that is currently moving pieces. 1 for AI (max), -1 for human (min). | |
Returns: | |
- best_score, best_move: returns best move that it found and its value. | |
""" | |
# recursion base case | |
if depth == 0: | |
# evaluate current board | |
score = board_value(board) | |
return score, None | |
best_move = None | |
# initializing best_score | |
best_score = float("-inf") | |
for move in board.legal_moves: | |
# make the move | |
board.push(move) | |
# if threefold repetition we do not analyze this position | |
if board.can_claim_threefold_repetition(): | |
board.pop() # unmake the last move | |
continue | |
score = -negamax(board, depth-1, -player)[0] | |
# take move back | |
board.pop() | |
if score > best_score: | |
# if it was the highest evaluation function move so far, we make this move | |
best_score = score | |
best_move = move | |
# if it returned no best move, we make a random one | |
if not best_move: | |
if board.legal_moves: | |
best_move = random.choice([move for move in board.legal_moves]) | |
else: | |
best_move = (None, None) | |
return best_score, best_move |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment