package pl.edu.pw.mini.sg.matrix.deterministic

import pl.edu.pw.mini.sg.game.deterministic.DeterministicGame
import pl.edu.pw.mini.sg.matrix.MatrixGameConfig


sealed trait MatrixGame extends DeterministicGame[Int, Int, MatrixGameState, MatrixGameState, MatrixGame]

final case class InitialMatrixGame(config: MatrixGameConfig) extends MatrixGame
 {
   override val attackerPayoff : Double = 0
   override val defenderPayoff : Double = 0
   override val defenderState : ColumnChoiceState = ColumnChoiceState(config.defenderMoveCount)
   override val attackerState : ColumnChoiceState = ColumnChoiceState(config.attackerMoveCount)

   override def makeMove(defenderMove: Int, attackerMove: Int) = {
     require(defenderMove >= 0 && defenderMove < config.defenderMoveCount, "Illegal defender move")
     require(attackerMove >= 0 && attackerMove < config.attackerMoveCount, "Illegal attacker move")

     FinishedMatrixGame(
       config.getDefenderPayoff(defenderMove, attackerMove),
       config.getAttackerPayoff(defenderMove, attackerMove)
     )
   }
}

final case class FinishedMatrixGame(defenderPayoff: Double, attackerPayoff: Double) extends MatrixGame {
  override val defenderState : AfterChoiceState.type = AfterChoiceState
  override val attackerState : AfterChoiceState.type = AfterChoiceState
  override def makeMove(defenderMove: Int, attackerMove: Int) =
    throw new IllegalStateException("No moves allowed in terminal state")
}
