You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
5.1 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. module Strategy0(Strategy0) where
  2. import qualified Data.PQueue.Prio.Max as PQ
  3. import System.Random(StdGen)
  4. import Data.Maybe (isJust)
  5. import Datatypes
  6. import Datatypes.Game (Command(..))
  7. import qualified Datatypes.Game as Game
  8. import VM
  9. import StrategyManager
  10. commandsList :: [Command]
  11. commandsList = [MoveSE, MoveSW, MoveW, MoveE, RotateClockwise, RotateCounterclockwise]
  12. type Queue = PQ.MaxPQueue Int Game
  13. data Strategy0 = Strategy0 (Queue, [Game])
  14. instance Strategy Strategy0 where
  15. initst = strategy0initst
  16. advance = strategy0advance
  17. getbest = strategy0getbest
  18. strategy0initst :: Game -> StdGen -> Maybe [Command] -> Strategy0
  19. strategy0initst game _ _ = (Strategy0 (PQ.singleton (fullScore game) game, []))
  20. strategy0advance :: Strategy0 -> Either Strategy0 ([Command],Int)
  21. strategy0advance (Strategy0 (queue,completed)) = let candidates = map (step game) commandsList
  22. (newQueue, newCompleted) = updateCollections candidates remQueue (game:completed)
  23. in Left (Strategy0 (newQueue, newCompleted))
  24. where
  25. ((score, game), remQueue) = PQ.deleteFindMax queue
  26. updateCollections [] q l = (q, l)
  27. updateCollections ((g, n):rs) q l = case n of
  28. OK -> updateCollections rs (pushToQueue q g) l
  29. Lock _ -> updateCollections rs (pushToQueue q g) l
  30. GameOver -> updateCollections rs q (pushToList l g)
  31. _ -> updateCollections rs q l
  32. pushToQueue q x = PQ.insert (fullScore x) x q
  33. pushToList c x = x : c
  34. strategy0getbest :: Strategy0 -> ([Command], Int)
  35. strategy0getbest (Strategy0 (incomplete,completed)) = let (_, bestIncomplete) = PQ.findMax incomplete
  36. resultGame = findListMax (bestIncomplete:completed)
  37. in (reverse (Game.history resultGame), fullScore resultGame)
  38. fullScore :: Game -> Int
  39. fullScore game = Game.score game + (Game.cacheToScore $ Game.phrasesCache game)
  40. findListMax :: [Game] -> Game
  41. findListMax (x:xs) = innerFindListMax x xs where
  42. innerFindListMax currentMax [] = currentMax
  43. innerFindListMax currentMax (y:ys) = innerFindListMax (if (fullScore currentMax) > (fullScore y) then currentMax else y) ys
  44. partition :: (a -> Bool) -> [a] -> ([a], [a])
  45. partition p items = innerPartition items [] [] where
  46. innerPartition [] ts fs = (ts, fs)
  47. innerPartition (x:xs) ts fs = if p x
  48. then innerPartition xs (x:ts) fs
  49. else innerPartition xs ts (x:fs)
  50. tryPowerPhrases :: Game -> [(Game, Notes)]
  51. tryPowerPhrases game = validResults where
  52. allResults = map (innerExpand (game, OK)) Game.powerPhrases
  53. validResults = map (\(Just x) -> x) $ filter (\x -> isJust x) allResults
  54. innerExpand (game, note) [] = Just (game, note)
  55. innerExpand (game, note) [p] = let nn@(newGame, newNote) = step game p
  56. in case newNote of
  57. OK -> Just nn
  58. Lock _ -> Just nn
  59. GameOver -> Just nn
  60. _ -> Nothing
  61. innerExpand (game, note) (p:ps) = let nn@(newGame, newNote) = step game p
  62. in case newNote of
  63. OK -> innerExpand nn ps
  64. Lock _ -> innerExpand nn ps
  65. _ -> Nothing
  66. --
  67. -- Old Strategy0 Code
  68. --
  69. -- findBest :: Int -> Queue -> [Game] -> (Queue, [Game])
  70. -- findBest 0 queue completed = (queue, completed)
  71. -- findBest i queue completed = let candidates = map (step game) commandsList ++ (tryPowerPhrases game)
  72. -- (newQueue, newCompleted) = updateCollections candidates remQueue (game:completed)
  73. -- in findBest (i - 1) newQueue newCompleted
  74. -- where
  75. -- ((score, game), remQueue) = PQ.deleteFindMax queue
  76. -- updateCollections [] q l = (q, l)
  77. -- updateCollections ((g, n):rs) q l = case n of
  78. -- OK -> updateCollections rs (pushToQueue q g) l
  79. -- Lock _ -> updateCollections rs (pushToQueue q g) l
  80. -- GameOver -> updateCollections rs q (pushToList l g)
  81. -- _ -> updateCollections rs q l
  82. -- pushToQueue q x = PQ.insert (fullScore x) x q
  83. -- strat0 :: Game -> ([Command],Int)
  84. -- strat0 game = let firstQueue = PQ.singleton (fullScore game) game
  85. -- (incomplete, completed) = findBest maxIter firstQueue []
  86. -- (_, bestIncomplete) = PQ.findMax incomplete
  87. -- resultGame = findListMax (bestIncomplete:completed)
  88. -- in (reverse (Game.history resultGame), fullScore resultGame)
  89. -- where
  90. -- maxIter = 50000
  91. -- pushToList c x = x : c