|
|
- module Datatypes.Game (Game(..), Command(..), completed, new, cacheToScore, updateCache, powerPhrases, phraseConverter) where -- FIXME exports
-
- import Data.Hashable (hash)
- import qualified Data.List as List
- import Data.Map.Strict (Map)
- import qualified Data.Map.Strict as Map
- import Data.Set (Set)
- import qualified Data.Set as Set
-
- import Datatypes.Board (Board)
- import Datatypes.Unit (Unit)
- import qualified Datatypes.Unit as Unit
-
- data Command = MoveW
- | MoveE
- | MoveSW
- | MoveSE
- | RotateClockwise
- | RotateCounterclockwise
- deriving (Show,Eq,Ord)
-
- type UnitHash = Int
-
- type PhrasesCache = Map [Command] Int
-
- data Game = Game {
- board :: Board,
- units :: [Unit],
- visitedUnits :: Set UnitHash,
- oldLines :: Int,
- score :: Int,
- history :: [Command],
- phrasesCache :: PhrasesCache
- }
- deriving Show
-
- completed :: Game -> Bool
- completed game = null $ units game
-
- new :: Board -> [Unit] -> Game
- new b us = Game {
- board = b,
- units = (c:cs),
- visitedUnits = Set.singleton (hash c),
- oldLines = 0,
- score = 0,
- history = [],
- phrasesCache = Map.empty
- } where (c:cs) = map (flip Unit.centeredIn b) us
-
- phraseConverter :: [Command] -> String
- phraseConverter s = if s == reverse [MoveE, MoveSW, MoveW]
- then "ei!"
- else if s == reverse [MoveSW, MoveSW, MoveW, MoveSE, MoveSW, MoveSW, MoveW]
- then "ia! ia!"
- else "PUPPA"
-
- powerPhrases :: [[Command]]
- powerPhrases = [
- reverse [MoveE, MoveSW, MoveW],
- reverse [MoveSW, MoveSW, MoveW, MoveSE, MoveSW, MoveSW, MoveW]
- ]
-
- updateCache :: PhrasesCache -> [Command] -> PhrasesCache
- updateCache cache history = innerUpdate cache history powerPhrases where
- innerUpdate cache _ [] = cache
- innerUpdate cache history (p:ps) = innerUpdate (updatedCache cache history p) history ps
- updatedCache c h p | p `List.isPrefixOf` h = if Map.member p c
- then Map.update (\a -> Just $ a + 1) p c
- else Map.insert p 1 c
- updatedCache c _ _ = c
-
- cacheToScore :: PhrasesCache -> Int
- cacheToScore items = sum $ map evalScore (Map.toAscList items) where
- evalScore (phrase, count) = 2 * (length phrase) * count + if count > 0 then 300 else 0
|