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

import pl.edu.pw.mini.sg.rng.RandomGenerator
import org.log4s._
import pl.edu.pw.mini.sg.mixed.IterationInfo
import pl.edu.pw.mini.sg.mixed.adjuster.AssesmentBasedAdjuster
import pl.edu.pw.mini.sg.mixed.tree.{ MixedStrategyNode, OptimizerStateType }


final object SignChangeCounterLocalAdjuster extends AssesmentBasedAdjuster {
  val logger = getLogger
  override type AdjusterState = SignChangeCounter

  override def updateState(oldState: SignChangeCounter, assesments: Seq[Double])(implicit rng: RandomGenerator): SignChangeCounter = oldState.registerAssesments(assesments)
  override def updateStrategy(
    mixedStrategyNode: MixedStrategyNode[_, _, _],
    adjusterState: SignChangeCounter,
    assesments: Seq[Double]
  )(
    implicit rng: RandomGenerator, iterationInfo: IterationInfo
  ): Boolean = {
    if(rng.nextDouble() > 0.1) {
      logger.debug(s"Signchange vec: ${adjusterState.changeCount}")
      assesments.zip(mixedStrategyNode.probabilities).zipWithIndex
        .zip(adjusterState.changeCount)
        .foreach{case (((asm, (move, prob)), idx), cc) => {
          val red = 1.0/(1+cc).toDouble
          mixedStrategyNode.updateProb(idx, Math.max(0,prob+asm*red))
      }}
      mixedStrategyNode.normalizeOrEqual()
      true
    } else {
      false
    }
  }

  override val ost: OptimizerStateType[AdjusterState] = SignChangeCounterType
}
