package beerpongelo import ( "math" ) func winProbPlayer(p, e1, e2 float64) float64 { const MAGIC float64 = 500 lhs := 1 / (1 + math.Pow(10., (p-e1)/MAGIC)) rhs := 1 / (1 + math.Pow(10., (p-e2)/MAGIC)) return (lhs + rhs) / 2. } func NewRating(t0p0, t0p1, t1p0, t1p1 float64, score int) (float64, float64, float64, float64) { const K float64 = 50 const SCORE_BIAS float64 = 1 const SCORE_SCALE float64 = 0.4 const MAX_SCORE float64 = 10 et0p0 := winProbPlayer(t0p0, t1p0, t1p1) et0p1 := winProbPlayer(t0p1, t1p0, t1p1) et1p0 := winProbPlayer(t1p0, t0p0, t0p1) et1p1 := winProbPlayer(t1p1, t0p0, t0p1) et0 := (et0p0 + et0p1) / 2. et1 := (et1p0 + et1p1) / 2. ct0p0 := t0p0 / (t0p0 + t0p1) ct0p1 := t0p1 / (t0p0 + t0p1) ct1p0 := t1p0 / (t1p0 + t1p1) ct1p1 := t1p1 / (t1p0 + t1p1) var st0 float64 var st1 float64 if score > 0 { st0 = 1 st1 = 0 } else { st0 = 0 st1 = 1 } scoreMod := SCORE_SCALE * math.Log(math.Abs(float64(score))+SCORE_BIAS) / (math.Log(MAX_SCORE) + SCORE_BIAS) newt0p0 := t0p0 + K*scoreMod*((st0*ct0p0)-(et0*ct0p0)) newt0p1 := t0p1 + K*scoreMod*((st0*ct0p1)-(et0*ct0p1)) newt1p0 := t1p0 + K*scoreMod*((st1*ct1p0)-(et1*ct1p0)) newt1p1 := t1p1 + K*scoreMod*((st1*ct1p1)-(et1*ct1p1)) return newt0p0, newt0p1, newt1p0, newt1p1 }