diff --git a/src/League.elm b/src/League.elm index 4acae30..63b39d1 100644 --- a/src/League.elm +++ b/src/League.elm @@ -14,17 +14,18 @@ module League exposing -} -import Dict exposing (Dict) +import Dict as ComparableDict import Elo import Json.Decode as Decode exposing (Decoder) import Json.Encode as Encode -import Player exposing (Player) +import Player exposing (Player, PlayerId) import Random exposing (Generator) +import Sort.Dict as Dict exposing (Dict) type League = League - { players : Dict String Player + { players : Dict PlayerId Player , currentMatch : Maybe Match } @@ -40,7 +41,7 @@ type Match init : League init = League - { players = Dict.empty + { players = Dict.empty Player.idSorter , currentMatch = Nothing } @@ -58,15 +59,18 @@ decoder = [ playersDecoder , -- old format: only players as a dict Decode.dict Player.decoder + |> Decode.map ComparableDict.toList + |> Decode.map (List.map (\( _, player ) -> ( player.id, player ))) + |> Decode.map (Dict.fromList Player.idSorter) ] ) -playersDecoder : Decoder (Dict String Player) +playersDecoder : Decoder (Dict PlayerId Player) playersDecoder = Decode.field "players" (Decode.list Player.decoder) - |> Decode.map (List.map (\player -> ( player.name, player ))) - |> Decode.map Dict.fromList + |> Decode.map (List.map (\player -> ( player.id, player ))) + |> Decode.map (Dict.fromList Player.idSorter) encode : League -> Encode.Value @@ -85,9 +89,9 @@ players (League league) = Dict.values league.players -getPlayer : String -> League -> Maybe Player -getPlayer name (League league) = - Dict.get name league.players +getPlayer : PlayerId -> League -> Maybe Player +getPlayer id (League league) = + Dict.get id league.players addPlayer : Player -> League -> League @@ -101,20 +105,20 @@ addPlayer player (League league) = nonEmpty -> List.sum nonEmpty // List.length nonEmpty in - League { league | players = Dict.insert player.name (Player.setRating initialRating player) league.players } + League { league | players = Dict.insert player.id (Player.setRating initialRating player) league.players } {-| -} updatePlayer : Player -> League -> League updatePlayer player (League league) = - League { league | players = Dict.insert player.name player league.players } + League { league | players = Dict.insert player.id player league.players } retirePlayer : Player -> League -> League retirePlayer player (League league) = League { league - | players = Dict.remove player.name league.players + | players = Dict.remove player.id league.players , currentMatch = case league.currentMatch of Nothing -> @@ -231,8 +235,8 @@ startMatch (Match playerA playerB) (League league) = -- don't start a match with players that aren't in the -- league... Maybe.map2 Tuple.pair - (Dict.get playerA.name league.players) - (Dict.get playerB.name league.players) + (Dict.get playerA.id league.players) + (Dict.get playerB.id league.players) |> Maybe.andThen (\( gotA, gotB ) -> -- ... or when the players are the same player diff --git a/src/Player.elm b/src/Player.elm index 04244ea..7c7b11c 100644 --- a/src/Player.elm +++ b/src/Player.elm @@ -1,9 +1,10 @@ -module Player exposing (Player, PlayerId, decoder, encode, incrementMatchesPlayed, init, playerIdFromIntForTestOnly, setRating) +module Player exposing (Player, PlayerId, decoder, encode, idSorter, incrementMatchesPlayed, init, playerIdFromIntForTestOnly, setRating) import Elo import Json.Decode as Decode exposing (Decoder) import Json.Encode as Encode exposing (Value) import Murmur3 +import Sort exposing (Sorter) type PlayerId @@ -15,6 +16,11 @@ playerIdFromIntForTestOnly = PlayerId +idSorter : Sorter PlayerId +idSorter = + Sort.by (\(PlayerId id) -> id) Sort.increasing + + type alias Player = { id : PlayerId , name : String diff --git a/tests/LeagueTest.elm b/tests/LeagueTest.elm index 830c3de..d3681a2 100644 --- a/tests/LeagueTest.elm +++ b/tests/LeagueTest.elm @@ -89,10 +89,10 @@ startMatchTests = \playerA playerB -> let uniqueA = - { playerA | name = "real " ++ playerA.name } + Player.init ("real " ++ playerA.name) uniqueB = - { playerB | name = "fake " ++ playerB.name } + Player.init ("real " ++ playerB.name) in League.init |> League.addPlayer uniqueA @@ -103,7 +103,7 @@ startMatchTests = \playerA playerBMaybeSame -> let playerB = - { playerBMaybeSame | name = "unique " ++ playerBMaybeSame.name } + Player.init ("unique " ++ playerBMaybeSame.name) in League.init |> League.addPlayer playerA @@ -141,10 +141,10 @@ finishMatchTests = |> League.startMatch (Match winner dummy) |> League.finishMatch (Win { won = winner, lost = dummy }) |> Expect.all - [ League.getPlayer winner.name + [ League.getPlayer winner.id >> Maybe.map .matches >> Expect.equal (Just (winner.matches + 1)) - , League.getPlayer dummy.name + , League.getPlayer dummy.id >> Maybe.map .matches >> Expect.equal (Just (dummy.matches + 1)) ] @@ -162,10 +162,10 @@ finishMatchTests = |> League.startMatch (Match winner dummy) |> League.finishMatch (Win { won = winner, lost = dummy }) |> Expect.all - [ League.getPlayer winner.name + [ League.getPlayer winner.id >> Maybe.map .rating >> Expect.equal (Just newRatings.won) - , League.getPlayer dummy.name + , League.getPlayer dummy.id >> Maybe.map .rating >> Expect.equal (Just newRatings.lost) ] @@ -188,10 +188,10 @@ finishMatchTests = |> League.startMatch (Match player dummy) |> League.finishMatch (Draw { playerA = player, playerB = dummy }) |> Expect.all - [ League.getPlayer player.name + [ League.getPlayer player.id >> Maybe.map .matches >> Expect.equal (Just (player.matches + 1)) - , League.getPlayer dummy.name + , League.getPlayer dummy.id >> Maybe.map .matches >> Expect.equal (Just (dummy.matches + 1)) ] @@ -217,10 +217,10 @@ finishMatchTests = |> League.startMatch (Match player dummy) |> League.finishMatch (Draw { playerA = player, playerB = dummy }) |> Expect.all - [ League.getPlayer player.name + [ League.getPlayer player.id >> Maybe.map .rating >> Expect.equal (Just newRatings.playerA) - , League.getPlayer dummy.name + , League.getPlayer dummy.id >> Maybe.map .rating >> Expect.equal (Just newRatings.playerB) ]