package pl.edu.pw.mini.jk.sg.mixeduct;

import com.google.common.collect.{ImmutableList, ImmutableMap}
import pl.edu.pw.mini.jk.sg.game.DefenderAttackerGame
import pl.edu.pw.mini.jk.sg.game.common.DefenderMove
import pl.edu.pw.mini.jk.sg.game.common.advanceable.{AdvanceableAttackerState, AdvanceableDefenderState}
import pl.edu.pw.mini.jk.sg.gteval.GameMatrices
import pl.edu.pw.mini.jk.sg.mixeduct.attackerresponse.AttackerSolverResult
import pl.edu.pw.mini.jk.sg.mixeduct.attackerresponse.OptimalAttacker
import pl.edu.pw.mini.jk.sg.mixeduct.attackerresponse.ExpectedPayoff

case class IterationResult[DM <: DefenderMove, AM, AS <: AdvanceableAttackerState[AM], DS <: AdvanceableDefenderState[DM], G <: pl.edu.pw.mini.jk.sg.game.common.Cloneable[G] with DefenderAttackerGame[AM, DM, AS, DS, _]]
  (defenderStrategy: ImmutableMap[ImmutableList[DM], java.lang.Double],
   attackerStrategy: AttackerSolverResult[AM],
    gameMatrices: GameMatrices[AM,DM,AS,DS,G]) {


  lazy val givenPayoff : ExpectedPayoff = gameMatrices.getExpectedPayoff(defenderStrategy, attackerStrategy.strategy)

  lazy val optimalAttacker : ImmutableMap[ImmutableList[AM], java.lang.Double] = if(attackerStrategy.exact)
    attackerStrategy.strategy
  else
    OptimalAttacker.solveAttackerOptimalStrategy(gameMatrices, defenderStrategy)

  lazy val optimalAttackerPayoff : ExpectedPayoff =
    if(attackerStrategy.exact)
      givenPayoff
    else
      gameMatrices.getExpectedPayoff(defenderStrategy, optimalAttacker)
}
