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

import pl.edu.pw.mini.sg.game.deterministic.{ DeterministicGame, PlayerVisibleState }
import pl.edu.pw.mini.sg.game.deterministic.single.DefenderGameView


sealed trait GameTreePosition[DM, AM, DS <: PlayerVisibleState[DM], AS <: PlayerVisibleState[AM], G <: DeterministicGame[DM, AM, DS, AS, G]] {
  def next(move: DM) : GameTreePosition[DM, AM, DS, AS, G];
}

final class BothTreesPosition[DM, AM, DS <: PlayerVisibleState[DM], AS <: PlayerVisibleState[AM], G <: DeterministicGame[DM, AM, DS, AS, G]](
  val desiredAttacker: DefenderGameView[DM, AM, DS, AS, G],
  val optimalAttacker: DefenderGameView[DM, AM, DS, AS, G]
) extends GameTreePosition[DM, AM, DS, AS, G] {
  override def next(move: DM) : GameTreePosition[DM, AM, DS, AS, G] = {
    val nextDA = desiredAttacker.makeMove(move)
    val nextOA = optimalAttacker.makeMove(move)

    if(nextDA.gameState.defenderState == nextOA.gameState.defenderState) {
      new BothTreesPosition(nextDA, nextOA)
    } else {
      new OptimalTreePosition[DM, AM, DS, AS, G](nextOA)
    }
  }

  def desiredState = desiredAttacker.gameState
  def optimalState = optimalAttacker.gameState
}

final class OptimalTreePosition[DM, AM, DS <: PlayerVisibleState[DM], AS <: PlayerVisibleState[AM], G <: DeterministicGame[DM, AM, DS, AS, G]](
  val optimalAttacker: DefenderGameView[DM, AM, DS, AS, G]
) extends GameTreePosition[DM, AM, DS, AS, G] {

  override def next(move: DM) : OptimalTreePosition[DM, AM, DS, AS, G] = {
    new OptimalTreePosition(optimalAttacker.makeMove(move))
  }

}
