def run(self, player, move, last_board, tree_level, is_max, tree_max_depth, use_memcache, alpha, beta, batch_size): new_board = ChessUtils.make_move(move, last_board) # Extract the set of possible moves for this level of the board. is_check, valid_moves = ChessUtils.get_valid_moves(player, new_board) # By default, continue recursing. end_recursion = False # Two recursion stop conditions. #------- Condition #1: Recursion Depth of maximum_depth of the tree. #------- Condition #2: No more valid player moves. if tree_level >= tree_max_depth or len(valid_moves) == 0: end_recursion = True # Ensure only one yield is generated in the case of recursions end so exit. if(end_recursion): yield common.Return((ChessUtils.get_state_utility(new_board, player, is_max, is_check, valid_moves), None)) # If child modes will be generated, then generate them as a fan-out then fan them back in. else: best_util_so_far = alpha if is_max else beta best_util_and_move = (best_util_so_far, None) yield MakeMoveIter(player, new_board, tree_level, is_max, tree_max_depth, use_memcache, alpha, beta, batch_size, best_util_and_move, valid_moves)
def run(self, player, move, board, tree_level, is_max, depth_tree, batch_size, rationality_prob): if move: board = ChessUtils.make_move(move, board) # Extract the set of possible moves for this level of the board. is_check, valid_moves = ChessUtils.get_valid_moves(player, board) # By default, continue recursing. end_recursion = False # Two recursion stop conditions. # ------- Condition #1: Recursion Depth of 6 # ------- Condition #2: No more valid player moves. if tree_level >= depth_tree or len(valid_moves) == 0: end_recursion = True # Ensure only one yield is generated in the case of recursions end so exit. if end_recursion: yield common.Return((ChessUtils.get_state_utility(board, player, is_max, is_check, valid_moves), None)) return if len(valid_moves) == 1: yield common.Return( (ChessUtils.get_state_utility(board, player, is_max, is_check, valid_moves), valid_moves[0]) ) return next_player = 1 - player is_next_player_max = not is_max utilities_and_moves = [] for new_move in valid_moves: utility_and_move = yield InnerExpectiMaxMakeMove( next_player, new_move, board, tree_level + 1, is_next_player_max, depth_tree, # Required as part of the player increment. batch_size, rationality_prob, ) utilities_and_moves.append(utility_and_move) if tree_level == 2: yield DetermineExpectiMaxUtilAndMove(is_max, valid_moves, rationality_prob, *utilities_and_moves) else: yield DetermineBestUtilAndMove(is_max, valid_moves, *utilities_and_moves)
def play_game(current_player, human_player, board): ''' Params: current_player: Integer - 0 or 1 to indicate whether it is white's or black's turn to start the game. human_player: Integer - 0 or 1 indicates whether the human player is white or black. This value should not change. board: List of lists of integers. It contains the current board. It will be updated at the end of each turn. Returns: This function runs and never returns. The program exits directly from this function. ''' while(True): check, valid_moves = ChessUtils.get_valid_moves(current_player, board) # Check if the game is over. if check and len(valid_moves) == 0: ChessUtils.print_board(board) print "\nCheckmate!" if current_player == human_player: print "The computer won! You lose!" else: print "You win!" sys.exit(0) # Check if the game is over due to stalemate. elif(not check and len(valid_moves) == 0): print "\nStalemate!\n" print "No moves possible so its a draw!" sys.exit(0) # Print the current board print "\n\nCurrent Board:" ChessUtils.print_board(board) # Human's turn. if(current_player == human_player): # Keep loop until the user enters a valid move. next_move = make_player_move(check, valid_moves, board) # Computer's turn. else: if check: print "The computer is in check. It must enter a move to exit check:\n" else: print "Its the computer's turn. It is deciding on its move.\n" next_move = query_server(current_player, board) # Print the computer's move. print "The computer's move is: (" + str(next_move[0]) + \ ", " + str(next_move[1]) + ")\n" board = ChessUtils.make_move(next_move, board) # Apply the move. current_player = 1 - current_player # update the player pass