def best_response(self, opponents_actions, tie_breaking='smallest',
                      payoff_perturbation=None, tol=None, random_state=None):
        """
        Return the best response action(s) to `opponents_actions`.

        Parameters
        ----------
        opponents_actions : scalar(int) or array_like
            A profile of N-1 opponents' actions, represented by either
            scalar(int), array_like(float), array_like(int), or
            array_like(array_like(float)). If N=2, then it must be a
            scalar of integer (in which case it is treated as the
            opponent's pure action) or a 1-dimensional array of floats
            (in which case it is treated as the opponent's mixed
            action). If N>2, then it must be an array of N-1 objects,
            where each object must be an integer (pure action) or an
            array of floats (mixed action).

        tie_breaking : str, optional(default='smallest')
            str in {'smallest', 'random', False}. Control how, or
            whether, to break a tie (see Returns for details).

        payoff_perturbation : array_like(float), optional(default=None)
            Array of length equal to the number of actions of the player
            containing the values ("noises") to be added to the payoffs
            in determining the best response.

        tol : scalar(float), optional(default=None)
            Tolerance level used in determining best responses. If None,
            default to the value of the `tol` attribute.

        random_state : int or np.random.RandomState, optional
            Random seed (integer) or np.random.RandomState instance to
            set the initial state of the random number generator for
            reproducibility. If None, a randomly initialized RandomState
            is used. Relevant only when tie_breaking='random'.

        Returns
        -------
        scalar(int) or ndarray(int, ndim=1)
            If tie_breaking=False, returns an array containing all the
            best response pure actions. If tie_breaking='smallest',
            returns the best response action with the smallest index; if
            tie_breaking='random', returns an action randomly chosen
            from the best response actions.

        """
        if tol is None:
            tol = self.tol

        payoff_vector = self.payoff_vector(opponents_actions)
        if payoff_perturbation is not None:
            try:
                payoff_vector += payoff_perturbation
            except TypeError:  # type mismatch
                payoff_vector = payoff_vector + payoff_perturbation

        best_responses = \
            np.where(payoff_vector >= payoff_vector.max() - tol)[0]

        if tie_breaking == 'smallest':
            return best_responses[0]
        elif tie_breaking == 'random':
            return self.random_choice(best_responses,
                                      random_state=random_state)
        elif tie_breaking is False:
            return best_responses
        else:
            msg = "tie_breaking must be one of 'smallest', 'random', or False"
            raise ValueError(msg)