package pl.edu.pw.mini.sg.game.boundedrationality

import pl.edu.pw.mini.sg.game.Payoff


final class DistortedPayoff(
  val real : Payoff,
  val distortedAttacker : Payoff 
) {
  override def hashCode : Int = (real,distortedAttacker).##
  override def equals(other: Any) = other match {
    case dp : DistortedPayoff => real == dp.real && distortedAttacker == dp.distortedAttacker
    case _ => false
  }

  /** real, distorted */
  def *(x : (Double, Double)) = new DistortedPayoff(real*x._1, distortedAttacker*x._2)
  def +(rhs: DistortedPayoff) = new DistortedPayoff(real+rhs.real, distortedAttacker+rhs.distortedAttacker)

  override def toString : String = s"(r: $real, da: $distortedAttacker)"


  final def equalsEps(other: DistortedPayoff, eps: Double) =
    DistortedPayoff.equalsEps(real.attacker, other.real.attacker, eps) &&
  DistortedPayoff.equalsEps(real.defender, other.real.defender, eps) &&
  DistortedPayoff.equalsEps(distortedAttacker.attacker, other.distortedAttacker.attacker, eps) &&
  DistortedPayoff.equalsEps(distortedAttacker.defender, other.distortedAttacker.defender, eps)

}

object DistortedPayoff {
  implicit class Distrotion(payoff: Payoff)(implicit br: BoundedRationality) {
    def toDistorted : DistortedPayoff = new DistortedPayoff(payoff, br.payoffChanger.changeExpectedPayoff(payoff))
  }

  val zero : DistortedPayoff = new DistortedPayoff(Payoff.zero, Payoff.zero)

  final def equalsEps(x1: Double, x2: Double, eps: Double) : Boolean = math.abs(x1-x2) < eps
}
