Given a tuple of payoff matrices, initialize the tableau and basis
    arrays in place.

    For each player `i`, if `payoff_matrices[i].min()` is non-positive,
    then stored in the tableau are payoff values incremented by
    `abs(payoff_matrices[i].min()) + 1` (to ensure for the tableau not
    to have a negative entry or a column identically zero).

    Suppose that the players 0 and 1 have m and n actions, respectively.

    * `tableaux[0]` has n rows and m+n+1 columns, where columns 0, ...,
      m-1 and m, ..., m+n-1 correspond to the non-slack and slack
      variables, respectively.

    * `tableaux[1]` has m rows and m+n+1 columns, where columns 0, ...,
      m-1 and m, ..., m+n-1 correspond to the slack and non-slack
      variables, respectively.

    * In each `tableaux[i]`, column m+n contains the values of the basic
      variables (which are initially 1).

    * `bases[0]` and `bases[1]` contain basic variable indices, which
      are initially m, ..., m+n-1 and 0, ..., m-1, respectively.

    Parameters
    ----------
    payoff_matrices : tuple(ndarray(ndim=2))
        Tuple of two arrays representing payoff matrices, of shape
        (m, n) and (n, m), respectively.

    tableaux : tuple(ndarray(float, ndim=2))
        Tuple of two arrays to be used to store the tableaux, of shape
        (n, m+n+1) and (m, m+n+1), respectively. Modified in place.

    bases : tuple(ndarray(int, ndim=1))
        Tuple of two arrays to be used to store the bases, of shape (n,)
        and (m,), respectively. Modified in place.

    Returns
    -------
    tableaux : tuple(ndarray(float, ndim=2))
        View to `tableaux`.

    bases : tuple(ndarray(int, ndim=1))
        View to `bases`.

    Examples
    --------
    >>> A = np.array([[3, 3], [2, 5], [0, 6]])
    >>> B = np.array([[3, 2, 3], [2, 6, 1]])
    >>> m, n = A.shape
    >>> tableaux = (np.empty((n, m+n+1)), np.empty((m, m+n+1)))
    >>> bases = (np.empty(n, dtype=int), np.empty(m, dtype=int))
    >>> tableaux, bases = _initialize_tableaux((A, B), tableaux, bases)
    >>> tableaux[0]
    array([[ 3.,  2.,  3.,  1.,  0.,  1.],
           [ 2.,  6.,  1.,  0.,  1.,  1.]])
    >>> tableaux[1]
    array([[ 1.,  0.,  0.,  4.,  4.,  1.],
           [ 0.,  1.,  0.,  3.,  6.,  1.],
           [ 0.,  0.,  1.,  1.,  7.,  1.]])
    >>> bases
    (array([3, 4]), array([0, 1, 2]))

def _initialize_tableaux(payoff_matrices, tableaux, bases):
    """
    Given a tuple of payoff matrices, initialize the tableau and basis
    arrays in place.

    For each player `i`, if `payoff_matrices[i].min()` is non-positive,
    then stored in the tableau are payoff values incremented by
    `abs(payoff_matrices[i].min()) + 1` (to ensure for the tableau not
    to have a negative entry or a column identically zero).

    Suppose that the players 0 and 1 have m and n actions, respectively.

    * `tableaux[0]` has n rows and m+n+1 columns, where columns 0, ...,
      m-1 and m, ..., m+n-1 correspond to the non-slack and slack
      variables, respectively.

    * `tableaux[1]` has m rows and m+n+1 columns, where columns 0, ...,
      m-1 and m, ..., m+n-1 correspond to the slack and non-slack
      variables, respectively.

    * In each `tableaux[i]`, column m+n contains the values of the basic
      variables (which are initially 1).

    * `bases[0]` and `bases[1]` contain basic variable indices, which
      are initially m, ..., m+n-1 and 0, ..., m-1, respectively.

    Parameters
    ----------
    payoff_matrices : tuple(ndarray(ndim=2))
        Tuple of two arrays representing payoff matrices, of shape
        (m, n) and (n, m), respectively.

    tableaux : tuple(ndarray(float, ndim=2))
        Tuple of two arrays to be used to store the tableaux, of shape
        (n, m+n+1) and (m, m+n+1), respectively. Modified in place.

    bases : tuple(ndarray(int, ndim=1))
        Tuple of two arrays to be used to store the bases, of shape (n,)
        and (m,), respectively. Modified in place.

    Returns
    -------
    tableaux : tuple(ndarray(float, ndim=2))
        View to `tableaux`.

    bases : tuple(ndarray(int, ndim=1))
        View to `bases`.

    Examples
    --------
    >>> A = np.array([[3, 3], [2, 5], [0, 6]])
    >>> B = np.array([[3, 2, 3], [2, 6, 1]])
    >>> m, n = A.shape
    >>> tableaux = (np.empty((n, m+n+1)), np.empty((m, m+n+1)))
    >>> bases = (np.empty(n, dtype=int), np.empty(m, dtype=int))
    >>> tableaux, bases = _initialize_tableaux((A, B), tableaux, bases)
    >>> tableaux[0]
    array([[ 3.,  2.,  3.,  1.,  0.,  1.],
           [ 2.,  6.,  1.,  0.,  1.,  1.]])
    >>> tableaux[1]
    array([[ 1.,  0.,  0.,  4.,  4.,  1.],
           [ 0.,  1.,  0.,  3.,  6.,  1.],
           [ 0.,  0.,  1.,  1.,  7.,  1.]])
    >>> bases
    (array([3, 4]), array([0, 1, 2]))

    """
    nums_actions = payoff_matrices[0].shape

    consts = np.zeros(2)  # To be added to payoffs if min <= 0
    for pl in range(2):
        min_ = payoff_matrices[pl].min()
        if min_ <= 0:
            consts[pl] = min_ * (-1) + 1

    for pl, (py_start, sl_start) in enumerate(zip((0, nums_actions[0]),
                                                  (nums_actions[0], 0))):
        for i in range(nums_actions[1-pl]):
            for j in range(nums_actions[pl]):
                tableaux[pl][i, py_start+j] = \
                    payoff_matrices[1-pl][i, j] + consts[1-pl]
            for j in range(nums_actions[1-pl]):
                if j == i:
                    tableaux[pl][i, sl_start+j] = 1
                else:
                    tableaux[pl][i, sl_start+j] = 0
            tableaux[pl][i, -1] = 1

        for i in range(nums_actions[1-pl]):
            bases[pl][i] = sl_start + i

    return tableaux, bases