# HG changeset patch # User unc0rr # Date 1447528745 -10800 # Node ID 437a60995fe1c82fc6dbe6d99547e7fd5ba3a1cf # Parent ff0fa38bdb18e54141d23836062b1bef111253f1 Rating updater, alpha version diff -r ff0fa38bdb18 -r 437a60995fe1 gameServer/OfficialServer/Glicko2.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 diff -r ff0fa38bdb18 -r 437a60995fe1 gameServer/OfficialServer/updateRating.hs --- 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 {