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