Rating updater, alpha version
authorunc0rr
Sat, 14 Nov 2015 22:19:05 +0300
changeset 11381 437a60995fe1
parent 11380 ff0fa38bdb18
child 11383 d3b603323b2b
Rating updater, alpha version
gameServer/OfficialServer/Glicko2.hs
gameServer/OfficialServer/updateRating.hs
--- a/gameServer/OfficialServer/Glicko2.hs	Sat Nov 14 17:39:45 2015 +0300
+++ b/gameServer/OfficialServer/Glicko2.hs	Sat Nov 14 22:19:05 2015 +0300
@@ -36,7 +36,11 @@
 
 
 calcNewRating :: RatingData -> [GameData] -> RatingData
-calcNewRating oldRating [] = oldRating
+calcNewRating oldRating [] = RatingData (ratingValue oldRating) (173.7178 * sqrt (φ ^ 2 + σ ^ 2)) σ
+    where
+        φ = rD oldRating / 173.7178
+        σ = volatility oldRating
+
 calcNewRating oldRating games = RatingData (173.7178 * μ' + 1500) (173.7178 * sqrt φ'sqr) σ'
     where
         _Es = map (calcE oldRating) games
--- a/gameServer/OfficialServer/updateRating.hs	Sat Nov 14 17:39:45 2015 +0300
+++ b/gameServer/OfficialServer/updateRating.hs	Sat Nov 14 22:19:05 2015 +0300
@@ -11,6 +11,7 @@
 import Control.Exception
 import System.IO
 import qualified  Data.Map as Map
+import Data.Time.Clock
 ------
 import OfficialServer.Glicko2
 
@@ -21,8 +22,6 @@
         "SELECT \
         \     p.userid \
         \     , p.place \
-        \     , o.userid \
-        \     , o.place \
         \     , COALESCE(vp.rating, 1500) \
         \     , COALESCE(vp.rd, 350) \
         \     , COALESCE(vp.volatility, 0.06) \
@@ -38,15 +37,36 @@
         \     LEFT OUTER JOIN rating_values as vo ON (vo.epoch = e.epoch AND vo.userid = o.userid) \
         \ GROUP BY p.userid, p.gameid, p.place \
         \ ORDER BY p.userid"
+insertNewRatings = "INSERT INTO rating_values (userid, epoch, rating, rd, volatility) VALUES (?, ?, ?, ?, ?)"
+insertNewEpoch = "INSERT INTO rating_epochs (epoch, todatetime) VALUES (?, ?)"
 
---Map Int (RatingData, [GameData])
+mergeRatingData :: Map.Map Int (RatingData, [GameData]) -> [(Int, (RatingData, [GameData]))] -> Map.Map Int (RatingData, [GameData])
+mergeRatingData m s = foldr (unc0rry (Map.insertWith mf)) m s
+    where
+        mf (rd, gds) (_, gds2) = (rd, gds ++ gds2)
+        unc0rry f (a, b) c = f a b c
+
 calculateRatings dbConn = do
+    [(epochNum :: Int, fromDate :: UTCTime, toDate :: UTCTime)] <- query_ dbConn queryEpochDates
     initRatingData <- (Map.fromList . map fromDBrating) `fmap` query_ dbConn queryPreviousRatings
+    gameData <- map fromGameResult `fmap` query_ dbConn queryGameResults
+    let mData = map getNewRating . Map.toList $ mergeRatingData initRatingData gameData
+    executeMany dbConn insertNewRatings $ map (toInsert epochNum) mData
+    execute dbConn insertNewEpoch (epochNum + 1, toDate)
     return ()
-
     where
+        toInsert e (i, RatingData r rd v) = (i, e + 1, r, rd, v)
+        getNewRating (a, d) = (a, uncurry calcNewRating d)
+        convPlace :: Int -> Double
+        convPlace 0 = 0.5
+        convPlace 1 = 1.0
+        convPlace 2 = 0.0
+        convPlace _ = error "Incorrect place value"
         fromDBrating (a, b, c, d) = (a, (RatingData b c d, []))
-
+        fromGameResult (pid, place, prating, pRD, pvol, orating, oRD, ovol) =
+            (pid,
+                (RatingData prating pRD pvol
+                , [GameData (RatingData orating oRD ovol) $ convPlace place]))
 
 
 data DBConnectInfo = DBConnectInfo {