package pl.edu.pw.mini.jk.sg.game

import squants.time.Time

final case class GameVariantRunnerResult[R] (
  methodResult: R,
  gameComputationTime: Time
)

trait GameVariantRunner {
  def runWithSingleMovePerTimestepFactory[R](action: NormalizableFactoryAction[R]): GameVariantRunnerResult[R]
  def runWithMultiMovePerTimestepFactory[R](action: NormalizableFactoryAction[R]): GameVariantRunnerResult[R]
  def runWithCoordGameFactory[R](action: NormalizableFactoryAction[R]): GameVariantRunnerResult[R]
  def runWithCompactGameFactory[R](action: NormalizableFactoryAction[R]): GameVariantRunnerResult[R]
}

sealed trait GameVariant {
  def runWithFactory[R](gvr: GameVariantRunner, normalizableFactoryAction: NormalizableFactoryAction[R]): GameVariantRunnerResult[R]
}

object GameVariant {
  object SingleMovePerTimestep extends GameVariant {
    override def runWithFactory[R](gvr: GameVariantRunner, action: NormalizableFactoryAction[R]) = gvr.runWithSingleMovePerTimestepFactory(action)
  }

  object MultiMovePerTimestep extends GameVariant {
    override def runWithFactory[R](gvr: GameVariantRunner, action: NormalizableFactoryAction[R]) = gvr.runWithMultiMovePerTimestepFactory(action)
  }

  object CoordMove extends GameVariant {
    override def runWithFactory[R](gvr: GameVariantRunner, action: NormalizableFactoryAction[R]) = gvr.runWithCoordGameFactory(action)
  }

  object CompactGame extends GameVariant {
    override def runWithFactory[R](gvr: GameVariantRunner, action: NormalizableFactoryAction[R]) = gvr.runWithCompactGameFactory(action)
  }
}
