SverreNystad / board-master

BoardMaster utilizes the power of the Minimax algorithm, to simulate the best AI opponents one can face in simple board games.
MIT License
3 stars 0 forks source link

Minimax agent with Alpha beta pruning #15

Closed SverreNystad closed 11 months ago

SverreNystad commented 11 months ago

Some python code I wrote to implement it

class AlphaBetaAgent(MultiAgentSearchAgent):
    """
    Your minimax agent with alpha-beta pruning (question 3)
    """

    def getAction(self, gameState):
        """
        Returns the minimax action using self.depth and self.evaluationFunction
        """

        best_action = None
        current_best_value = float('-inf')
        lower_bound = float('-inf')   # Initialize alpha, lower_bound is alpha
        upper_bound = float('inf')    # Initialize beta, upper_bound is beta

        for action in gameState.getLegalActions(PAC_MANS_TURN):
            value = self.minimax_depth(gameState.generateSuccessor(PAC_MANS_TURN, action), 
                                       self.depth, 
                                       PAC_MANS_TURN + 1, 
                                       lower_bound, upper_bound)
            if value > current_best_value:
                current_best_value = value
                best_action = action
            # Update alpha
            lower_bound = max(lower_bound, current_best_value)  
        return best_action

    def minimax_depth(self, gameState, depth: int, agent_id: int, lower_bound: float, upper_bound: float) -> float:
        """
        Args:
        - lower_bound: corresponds to the alpha
        - upper_bound: corresponds to the beta
        """
        if depth == 0 or gameState.isWin() or gameState.isLose():
            return self.evaluationFunction(gameState)

        if agent_id == PAC_MANS_TURN:
            value = float('-inf')
            for action in gameState.getLegalActions(PAC_MANS_TURN):
                successor_state = gameState.generateSuccessor(PAC_MANS_TURN, action)
                value = max(value, self.minimax_depth(successor_state, depth, PAC_MANS_TURN + 1, lower_bound, upper_bound))

                # Pruning condition for maximizer
                if value > upper_bound:  
                    return value
                # Update alpha
                lower_bound = max(lower_bound, value)  
            return value

        else:
            value = float('inf')
            for action in gameState.getLegalActions(agent_id):
                successor_state = gameState.generateSuccessor(agent_id, action)
                if successor_state.getNumAgents() - 1 == agent_id:
                    value = min(value, self.minimax_depth(successor_state, depth - 1, PAC_MANS_TURN, lower_bound, upper_bound))
                else:
                    value = min(value, self.minimax_depth(successor_state, depth, agent_id + 1, lower_bound, upper_bound))
                # Pruning condition for minimizer
                if value < lower_bound:  
                    return value
                # Update beta
                upper_bound = min(upper_bound, value)  
            return value
SverreNystad commented 11 months ago

This is now done