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 }

import pl.edu.pw.mini.sg.util.Logging

final object SignChangeCounterGlobalAdjuster extends AssesmentBasedAdjuster with Logging {
  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) {
      val reduction = 1.0/(adjusterState.changeCount.sum.toDouble+1)
      log.debug(s"Reduction val: ${reduction}")
      assesments.zip(mixedStrategyNode.probabilities).zipWithIndex.foreach{case ((asm, (move, prob)), idx) => {
        mixedStrategyNode.updateProb(idx, Math.max(0,prob+asm*reduction))
      }}
      mixedStrategyNode.normalizeOrEqual()
      true
    } else {
      false
    }
  }

  override val ost: OptimizerStateType[AdjusterState] = SignChangeCounterType
}
