package pl.edu.pw.mini.sg.game.graph.discounting

import pl.edu.pw.mini.sg.rng.RandomGenerator
import pl.edu.pw.mini.sg.game.deterministic.AdvanceablePlayerVisibleState
import scala.util.hashing.MurmurHash3



final class DiscountingGraphGameAttackerState(
  val vertex: Int,
  val timeStep: Int,
  val defenderUnit: Int,
  gameConfig: DiscountingGraphGameConfig
) extends AdvanceablePlayerVisibleState[Int, DiscountingGraphGameAttackerState] {
  override val hashCode: Int = {
    import MurmurHash3.{mix, mixLast, finalizeHash}
    finalizeHash(mixLast(mix(mix(MurmurHash3.arraySeed,vertex),timeStep), defenderUnit),3)
  }

  override def equals(other: Any): Boolean = other match {
    case dgas : DiscountingGraphGameAttackerState => dgas.vertex == vertex && dgas.timeStep == timeStep && dgas.defenderUnit == defenderUnit
    case _ => false
  }

  def continuation(move: Int) : DiscountingGraphGameAttackerState = {
    assert(defenderUnit==0 || move == vertex)
    new DiscountingGraphGameAttackerState(move,
      if(defenderUnit == gameConfig.graphConfig.defenderUnitCount -1) timeStep+1 else timeStep,
      (defenderUnit+1)%gameConfig.graphConfig.defenderUnitCount,
      gameConfig)
  }


  override def possibleContinuations(move: Int): List[DiscountingGraphGameAttackerState] = List(continuation(move))
  override def sampleContinuations(move: Int)(implicit rng: RandomGenerator): DiscountingGraphGameAttackerState = continuation(move)
  override def possibleMoves: List[Int] =
    if(timeStep >= gameConfig.graphConfig.rounds) Nil
    else if(defenderUnit > 0) List(vertex)
    else gameConfig.graphConfig.possibleMovesFromVertex(vertex)

  def makeFinal: DiscountingGraphGameAttackerState = new DiscountingGraphGameAttackerState(
    vertex, gameConfig.graphConfig.rounds, 0, gameConfig)
}
