Make enumerateUnits a Traversal instad of just a Fold

This commit is contained in:
Emi Simpson 2023-12-06 14:57:43 -05:00
parent 70d8b0d1b0
commit 1f65275d5b
Signed by: Emi
GPG Key ID: A12F2C2FFDC3D847
1 changed files with 19 additions and 9 deletions

View File

@ -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