From 1f65275d5b9282f2481e35e8b7e69b800a1b38e7 Mon Sep 17 00:00:00 2001 From: Emi Simpson Date: Wed, 6 Dec 2023 14:57:43 -0500 Subject: [PATCH] Make enumerateUnits a Traversal instad of just a Fold --- src/GameModel.hs | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/GameModel.hs b/src/GameModel.hs index 760a992..b9980a0 100644 --- a/src/GameModel.hs +++ b/src/GameModel.hs @@ -938,16 +938,26 @@ cidsInRange board range locus = board ^.. inner ofPlayer :: Player -> Traversal' CharacterIdentifier CharacterIdentifier ofPlayer player = filtered (owner >>> (== player)) -lookupCIDs :: Monoid r => [CharacterIdentifier] -> Getting r BoardState (CharacterIdentifier, Character) -lookupCIDs chars = to lookupCIDs' . each +-- | A traversal over pairs in the form (`CharacterIdentifier`, `Character`) +-- +-- On modifying these pairs: Modifications to the `Character` will be applied to the +-- original character, but __changes to the `CharacterIdentifier` will be completely +-- ignored__. This means you /cannot/ use this traversal to change the order of +-- characters, switch characters between players, or anything like that. +enumerateUnits :: Traversal' BoardState (CharacterIdentifier, Character) +enumerateUnits = enumerateUnits' where - ixCharacter' :: CharacterIdentifier -> Getting (First Character) BoardState Character - ixCharacter' cid = ixCharacter cid - lookupCIDs' :: BoardState -> [(CharacterIdentifier, Character)] - lookupCIDs' boardstate = mapMaybe (liftA2 (fmap . (,)) id ((boardstate ^?) . ixCharacter')) chars - -enumerateUnits :: SimpleFold BoardState (CharacterIdentifier, Character) -enumerateUnits f board = lookupCIDs (board ^.. eachCID) f board + enumerateUnits' :: forall f. Applicative f + => ((CharacterIdentifier, Character) -> f (CharacterIdentifier, Character)) + -> BoardState -> f BoardState + enumerateUnits' f = characters fCharacters + where + fUnit :: Player -> Int -> Character -> f Character + fUnit player indx c = snd <$> f ((player, indx), c) + fRoster :: Player -> [Character] -> f [Character] + fRoster player roster = zipWithM (fUnit player) [0..] roster + fCharacters :: PPair [Character] -> f (PPair [Character]) + fCharacters (PPair p1 p2) = PPair <$> fRoster Min p1 <*> fRoster Max p2 untappedUnits :: SimpleFold BoardState CharacterIdentifier untappedUnits = enumerateUnits . filtered (untapped . snd) . _1