Created
March 18, 2016 15:38
-
-
Save mattgreen/fc37f35ab11bd93a2981 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Control.Monad (guard) | |
import Data.List (foldl', sort) | |
-- Types | |
data Player = Player Name Rating | |
deriving (Eq, Show) | |
type Name = String | |
type Rating = Integer | |
instance Ord Player where | |
(Player _ r1) `compare` (Player _ r2) = r1 `compare` r2 | |
type Team = [Player] | |
-- Sorts players by MMR in decreasing order, pairing them with their | |
-- closest rated player. The pairs are then split between the teams. | |
-- To avoid the first team being stacked using this method, we alternate | |
-- which team the first player in a pairing is assigned to. | |
balance :: [Player] -> Maybe (Team, Team) | |
balance players = do | |
guard (evenLength players) | |
return $ foldl' assign ([], []) pairings | |
where | |
pairings = pair . reverse . sort $ players | |
evenLength x = (length x) `rem` 2 == 0 | |
assign (t1, t2) (p1, p2) = | |
if evenLength t1 | |
then (p1:t1, p2:t2) | |
else (p2:t1, p1:t2) | |
pair (p1:p2:ps) = (p1,p2) : pair ps | |
pair _ = [] | |
teamMmrAverage :: Team -> Integer | |
teamMmrAverage team = sum mmrs `div` count | |
where | |
count = fromIntegral . length $ team | |
mmrs = map (\(Player _ mmr) -> mmr) team | |
stats :: (Team, Team) -> (Integer, Integer) | |
stats (t1, t2) = (teamMmrAverage t1, teamMmrAverage t2) | |
-- Sample data | |
players :: [Player] | |
players = [Player "a" 400, Player "b" 500, Player "c" 600, Player "d" 700, Player "e" 800, Player "f" 900, Player "g" 1000, Player "h" 1100, Player "i" 1200, Player "j" 1300] | |
betterPool = [ Player "avg" 2000 | |
, Player "avg2" 2100 | |
, Player "avg3" 2150 | |
, Player "good1" 3300 | |
, Player "good2" 3200 | |
, Player "lessgood" 1500 | |
, Player "gettingbetter" 1700 | |
, Player "great" 3500 | |
, Player "avg4" 2400 | |
, Player "avg5" 2200 ] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment