def __init__(self, data, dtype=None):
        # data represents an array_like of Players
        if hasattr(data, '__getitem__') and isinstance(data[0], Player):
            N = len(data)

            # Check that the shapes of the payoff arrays are consistent
            # and the dtypes coincide
            shape_0 = data[0].payoff_array.shape
            dtype_0 = data[0].payoff_array.dtype
            for i in range(1, N):
                shape = data[i].payoff_array.shape
                if not (
                    len(shape) == N and
                    shape == shape_0[i:] + shape_0[:i]
                ):
                    raise ValueError(
                        'shapes of payoff arrays must be consistent'
                    )
                dtype = data[i].payoff_array.dtype
                if dtype != dtype_0:
                    raise ValueError(
                        'dtypes of payoff arrays must coincide'
                    )

            self.players = tuple(data)
            self.dtype = dtype_0

        # data represents action sizes or a payoff array
        else:
            data = np.asarray(data)

            if data.ndim == 0:  # data represents action size
                # Trivial game consisting of one player
                N = 1
                self.players = (Player(np.zeros(data)),)
                self.dtype = data.dtype

            elif data.ndim == 1:  # data represents action sizes
                N = data.size
                # N instances of Player created
                # with payoff_arrays filled with zeros
                # Payoff values set via __setitem__
                self.players = tuple(
                    Player(np.zeros(tuple(data[i:]) + tuple(data[:i]),
                                    dtype=dtype))
                    for i in range(N)
                )
                self.dtype = self.players[0].payoff_array.dtype

            elif data.ndim == 2 and data.shape[1] >= 2:
                # data represents a payoff array for symmetric two-player game
                # Number of actions must be >= 2
                if data.shape[0] != data.shape[1]:
                    raise ValueError(
                        'symmetric two-player game must be represented ' +
                        'by a square matrix'
                    )
                N = 2
                self.players = tuple(Player(data) for i in range(N))
                self.dtype = data.dtype

            else:  # data represents a payoff array
                # data must be of shape (n_0, ..., n_{N-1}, N),
                # where n_i is the number of actions available to player i,
                # and the last axis contains the payoff profile
                N = data.ndim - 1
                if data.shape[-1] != N:
                    raise ValueError(
                        'size of innermost array must be equal to ' +
                        'the number of players'
                    )
                self.players = tuple(
                    Player(
                        data.take(i, axis=-1).transpose(list(range(i, N)) +
                                                        list(range(i)))
                    ) for i in range(N)
                )
                self.dtype = data.dtype

        self.N = N  # Number of players
        self.nums_actions = tuple(
            player.num_actions for player in self.players
        )
dataset/ETHPy150Open QuantEcon/QuantEcon.py/quantecon/game_theory/normal_form_game.py/NormalFormGame.__init__/original