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

import argonaut.{ EncodeJson, Json }
import pl.edu.pw.mini.sg.game.deterministic.json.DeterministicGameJson
import pl.edu.pw.mini.sg.game.deterministic.plugin.GameFactory
import pl.edu.pw.mini.sg.matrix.MatrixGameConfig



object MatrixGameFactory extends GameFactory[MatrixGameConfig] {
  override type DefenderMove = Int
  override type AttackerMove = Int
  override type DefenderState = MatrixGameState
  override type AttackerState = MatrixGameState
  override type Game = MatrixGame

  override def create(gameConfig : MatrixGameConfig) = InitialMatrixGame(gameConfig)
  override val json = MatrixGameJson

  def maxDefenderPayoff(gameConfig: MatrixGameConfig): Double = gameConfig.defenderMatrix.view.flatten.max
  def minDefenderPayoff(gameConfig: MatrixGameConfig): Double = gameConfig.defenderMatrix.view.flatten.min
  def maxAttackerPayoff(gameConfig: MatrixGameConfig): Double = gameConfig.attackerMatrix.view.flatten.max
  def minAttackerPayoff(gameConfig: MatrixGameConfig): Double = gameConfig.attackerMatrix.view.flatten.min

}

object MatrixGameJson extends DeterministicGameJson[Int, Int, MatrixGameState, MatrixGameState] {
  implicit val defenderMoveEncode = EncodeJson.IntEncodeJson
  implicit val attackerMoveEncode = EncodeJson.IntEncodeJson
  implicit val defenderStateEncode = EncodeJson {state =>
    state match {
      case ColumnChoiceState(_) => Json.jString("initialState")
      case AfterChoiceState => Json.jString("finalState")
    }
  }
  implicit val attackerStateEncode = defenderStateEncode
}
