evac/Groups.hs
2019-05-16 09:39:06 +12:00

70 lines
2.4 KiB
Haskell

module Groups where
import State
-- Each characters default adjacents
defFrens :: MainCharacter -> [MainCharacter]
defFrens Asuka = [Rei, Shinji, Misato]
defFrens Shinji = [Rei, Gendo, Ritsuko, Misato, Asuka]
defFrens Rei = [Gendo, Shinji, Asuka]
defFrens Misato = [Asuka, Shinji, Ritsuko]
defFrens Ritsuko = [Misato, Shinji, Gendo]
defFrens Gendo = [Rei, Shinji, Ritsuko]
-- The group that character x belongs to
charsGroup :: MainCharacter -> NeoTokyo -> Group
charsGroup x nt = head $ filter (\g -> x `elem` g) nt
-- The characters currently grouped with x
curFrens :: MainCharacter -> NeoTokyo -> [MainCharacter]
curFrens x nt = filter (/= x) $ charsGroup x nt
-- Remove duplicates, stabily
uniq :: (Eq a) => [a] -> [a]
uniq x = reverse $ go x []
where
go [] al = al
go (c:cs) al = if (c `elem` al) then (go cs al) else (go cs (c:al))
-- The groups a character is adaject to
adjGroups :: MainCharacter -> NeoTokyo -> [Group]
adjGroups x nt = filter (\g -> any (\x -> x `elem` adjFrens) g) (otherGroups x nt)
where
adjFrens = uniq $ foldr (++) [] (map defFrens $ charsGroup x nt)
-- The groups a character isnt in
otherGroups :: MainCharacter -> NeoTokyo -> [Group]
otherGroups x nt = filter (\g -> not $ x `elem` g) nt
-- All characters a X is adjacent to
getAdj :: MainCharacter -> NeoTokyo -> [MainCharacter]
getAdj x nt = curFrens x nt ++ (foldr (++) [] (adjGroups x nt))
-- X hurts Y (only if adjacent)
hurt :: MainCharacter -> MainCharacter -> BoardState -> BoardState
hurt x y (nt,d)
| not $ y `elem` (getAdj x nt) = (nt,d)
| otherwise = hurt' x y (nt,d)
-- X hurts Y (no restrictions)
hurt' :: MainCharacter -> MainCharacter -> BoardState -> BoardState
hurt' x y (nt,d)
| y `elem` d = if (curFrens y nt == [])
then (nt, d)
else ([y] : (groupMinusChar y) : (otherGroups y nt), d)
| otherwise = (nt, y:d)
where
groupMinusChar y = (filter (/= y) $ charsGroup y nt)
-- Attract X and Y (only if adjacent)
attract :: MainCharacter -> MainCharacter -> BoardState -> BoardState
attract x y (nt,d)
| not $ y `elem` (getAdj x nt) = (nt,d)
| otherwise = attract' x y (nt,d)
-- Attract X and Y (no restrictions)
attract' :: MainCharacter -> MainCharacter -> BoardState -> BoardState
attract' x y (nt,d)
| x `elem` d = (nt, (filter (/= x) d))
| otherwise = ((uniq (charsGroup x nt ++ charsGroup y nt)) : (otherGroups y (otherGroups x nt)), d)