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)