package pl.edu.pw.mini.game.flipit.deterministic.noinfo

import pl.edu.pw.mini.sg.rng.RandomGenerator
import pl.edu.pw.mini.sg.game.deterministic.AdvanceablePlayerVisibleState
import pl.edu.pw.mini.game.flipit.deterministic.FlipItMove


sealed trait NoInfoFlipItState extends AdvanceablePlayerVisibleState[FlipItMove, NoInfoFlipItState] {
  def nextState: NoInfoFlipItState
}

object NoInfoFlipitStateTerminal extends NoInfoFlipItState {
  override def possibleMoves : List[FlipItMove] = Nil

  override def nextState : NoInfoFlipItState = throw new IllegalStateException("Terminal state")
  override def possibleContinuations(move: FlipItMove): List[NoInfoFlipItState] =
    throw new IllegalStateException("Terminal state")
  override def sampleContinuations(move: FlipItMove)(implicit rng: RandomGenerator): NoInfoFlipItState =
    throw new IllegalStateException("Terminal state")
}

final class NoInfoFlipItStateInner(
  cache: NoInfoFlipItCache,
  val nextState: NoInfoFlipItState
) extends NoInfoFlipItState {
  override def hashCode = cache.##

  // !!! it is not technically correct, but yields faster program
  // and is ok, because there is only single instance of this state per game tree level. 
  override def equals(other: Any) = true

  override def possibleMoves : List[FlipItMove] = cache.possibleMoves

  override def possibleContinuations(move: FlipItMove): List[NoInfoFlipItState] = List(nextState)
  override def sampleContinuations(move: FlipItMove)(implicit rng: RandomGenerator): NoInfoFlipItState = nextState
}
