package pl.edu.pw.mini.sg.mixed

import pl.edu.pw.mini.sg.game.boundedrationality.DistortedPayoff
import pl.edu.pw.mini.sg.game.deterministic.PlayerVisibleState
import pl.edu.pw.mini.sg.mixed.tree.MixedStrategyNode

sealed trait StrategyResult[DM, DS, OST]

final case class FeasibleStrategy[DM, DS <: PlayerVisibleState[DM], OST](
  strategy: MixedStrategyNode[DM, DS, OST],
  payoff: DistortedPayoff
) extends StrategyResult[DM, DS, OST]

final case class MaybeFeasibleStrategy[DM, DS <: PlayerVisibleState[DM], OST](
  strategy: MixedStrategyNode[DM, DS, OST],
  payoffUB: DistortedPayoff,
  iteration: IterationInfo
) extends StrategyResult[DM, DS, OST]

final case class InfeasibleStrategy[DM, DS <: PlayerVisibleState[DM], OST](
  strategy: MixedStrategyNode[DM, DS, OST],
  payoff: DistortedPayoff
) extends StrategyResult[DM, DS, OST]

object StrategyResult {
  def feasibleResult[DM, DS <: PlayerVisibleState[DM], OST](strategy: MixedStrategyNode[DM, DS, OST],
    payoff: DistortedPayoff, isMethodExact: Boolean)(implicit iterationInfo: IterationInfo) : StrategyResult[DM, DS, OST] =
    if(isMethodExact) FeasibleStrategy.apply(strategy, payoff) else MaybeFeasibleStrategy.apply(strategy, payoff, iterationInfo)
}
