# Path: src/nashpy/algorithms/lemke_howson.py
# def shift_tableau(tableau: npt.NDArray, shape: Tuple[int, ...]) -> npt.NDArray:
#     """
#     Shift a tableau to ensure labels of pairs of tableaux coincide
# 
#     Parameters
#     ----------
#     tableau : array
#         a tableau corresponding to a vertex of a polytope.
#     shape : tuple
#         the required shape of the tableau
# 
#     Returns
#     -------
#     array
#         The shifted tableau
#     """
#     return np.append(
#         np.roll(tableau[:, :-1], shape[0], axis=1),
#         np.ones((shape[0], 1)),
#         axis=1,
#     )
# 
# def tableau_to_strategy(
#     tableau: npt.NDArray, basic_labels: Set[int], strategy_labels: Iterable
# ) -> npt.NDArray:
#     """
#     Return a strategy vector from a tableau
# 
#     Parameters
#     ----------
#     tableau : array
#         a tableau corresponding to a vertex of a polytope.
#     basic_labels : set
#         the set of basic labels.
#     strategy_labels : Iterable
#         the set of labels that correspond to strategies.
# 
#     Returns
#     -------
#     array
#         A strategy.
#     """
#     vertex = []
#     for column in strategy_labels:
#         if column in basic_labels:
#             for i, row in enumerate(tableau[:, column]):
#                 if row != 0:
#                     vertex.append(tableau[i, -1] / row)
#         else:
#             vertex.append(0)
#     strategy = np.array(vertex)
#     return strategy / sum(strategy)


from itertools import cycle
from typing import Tuple
from nashpy.integer_pivoting import make_tableau, pivot_tableau_lex
from .lemke_howson import shift_tableau, tableau_to_strategy
import numpy as np
import numpy.typing as npt
     2. Choose an initial label to drop and move in the polytope for which
        the vertex has that label to the edge that does not share that label.
    (This is implemented using integer pivoting and the choice of label
    to drop is implemented using lexicographical ordering)
     3. A label will now be duplicated in the other polytope, drop it in a
        similar way.
     4. Repeat steps 2 and 3 until have Nash Equilibrium.

    Parameters
    ----------
    A : array
        The row player payoff matrix
    B : array
        The column player payoff matrix
    initial_dropped_label: int
        The initial dropped label.

    Returns
    -------
    Tuple
        An equilibria
    """

    if np.min(A) <= 0:
        A = A + abs(np.min(A)) + 1
    if np.min(B) <= 0:
        B = B + abs(np.min(B)) + 1

    # build tableaux
    col_tableau = make_tableau(A)

# Path: src/nashpy/algorithms/lemke_howson.py
# def shift_tableau(tableau: npt.NDArray, shape: Tuple[int, ...]) -> npt.NDArray:
#     """
#     Shift a tableau to ensure labels of pairs of tableaux coincide
# 
#     Parameters
#     ----------
#     tableau : array
#         a tableau corresponding to a vertex of a polytope.
#     shape : tuple
#         the required shape of the tableau
# 
#     Returns
#     -------
#     array
#         The shifted tableau
#     """
#     return np.append(
#         np.roll(tableau[:, :-1], shape[0], axis=1),
#         np.ones((shape[0], 1)),
#         axis=1,
#     )
# 
# def tableau_to_strategy(
#     tableau: npt.NDArray, basic_labels: Set[int], strategy_labels: Iterable
# ) -> npt.NDArray:
#     """
#     Return a strategy vector from a tableau
# 
#     Parameters
#     ----------
#     tableau : array
#         a tableau corresponding to a vertex of a polytope.
#     basic_labels : set
#         the set of basic labels.
#     strategy_labels : Iterable
#         the set of labels that correspond to strategies.
# 
#     Returns
#     -------
#     array
#         A strategy.
#     """
#     vertex = []
#     for column in strategy_labels:
#         if column in basic_labels:
#             for i, row in enumerate(tableau[:, column]):
#                 if row != 0:
#                     vertex.append(tableau[i, -1] / row)
#         else:
#             vertex.append(0)
#     strategy = np.array(vertex)
#     return strategy / sum(strategy)


# Path: src/nashpy/algorithms/lemke_howson_lex.py
from itertools import cycle
from typing import Tuple
from nashpy.integer_pivoting import make_tableau, pivot_tableau_lex
from .lemke_howson import shift_tableau, tableau_to_strategy
import numpy as np
import numpy.typing as npt

     2. Choose an initial label to drop and move in the polytope for which
        the vertex has that label to the edge that does not share that label.
    (This is implemented using integer pivoting and the choice of label
    to drop is implemented using lexicographical ordering)
     3. A label will now be duplicated in the other polytope, drop it in a
        similar way.
     4. Repeat steps 2 and 3 until have Nash Equilibrium.

    Parameters
    ----------
    A : array
        The row player payoff matrix
    B : array
        The column player payoff matrix
    initial_dropped_label: int
        The initial dropped label.

    Returns
    -------
    Tuple
        An equilibria
    """

    if np.min(A) <= 0:
        A = A + abs(np.min(A)) + 1
    if np.min(B) <= 0:
        B = B + abs(np.min(B)) + 1

    # build tableaux
    col_tableau = make_tableau(A)

    col_tableau = shift_tableau(col_tableau, A.shape)