package pl.edu.pw.mini.sg.game.deterministic.single

import pl.edu.pw.mini.sg.rng.RandomGenerator
import org.scalatest.{ Matchers, WordSpec }
import pl.edu.pw.mini.sg.game.deterministic.AdvanceablePlayerVisibleState
import scalaz.NonEmptyList


final class LinearizedAdvanceableGameSpec extends WordSpec with Matchers {
  def browseLeaves[M, S <: AdvanceablePlayerVisibleState[M,S]](
    g: LinearizedAdvanceableGame[M, S]
  ) : Stream[LinearizedAdvanceableGame[M, S]]  = {
    if(g.possibleMoves.isEmpty) Stream(g)
    else {
      g.possibleMoves.toStream.flatMap(m => browseLeaves[M,S](g.makeMove(m)))
    }
  }


 final case class SumGame(v: Int) extends AdvanceablePlayerVisibleState[Int, SumGame] {
   override def possibleMoves = Range.inclusive(1, v).toList
   override def possibleContinuations(m: Int) : List[SumGame] = Range.inclusive(0, v-m).map(x => new SumGame(x)).toList
   override def sampleContinuations(m: Int)(implicit rng: RandomGenerator) : SumGame = ???
 }


  "linearized advanceable game" when {
    "applied to sum game (3)" should {

      val lg = new LinearizedAdvanceableGame[Int, SumGame](NonEmptyList(new SumGame(3)), Nil, Nil)
      "generate 4 leaves" in {
        browseLeaves(lg).length shouldEqual(4)

        browseLeaves(lg).map(_.pureStrategy) should contain allOf(
          SimplePureStrategy(3, new SumGame(3), Map()),
          SimplePureStrategy(2, new SumGame(3), Map(
            new SumGame(1) -> SimplePureStrategy(1, new SumGame(1), Map())
          )),
          SimplePureStrategy(1, new SumGame(3), Map(
            new SumGame(2) -> SimplePureStrategy(2, new SumGame(2), Map()),
            new SumGame(1) -> SimplePureStrategy(1, new SumGame(1), Map())
          )),
          SimplePureStrategy(1, new SumGame(3), Map(
            new SumGame(2) -> SimplePureStrategy(1, new SumGame(2), Map(
              new SumGame(1) -> SimplePureStrategy(1, new SumGame(1), Map())
            )),
            new SumGame(1) -> SimplePureStrategy(1, new SumGame(1), Map())
          ))
        )
      }
    }
  }
}
