Guest User

Untitled

a guest
Dec 16th, 2018
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.51 KB | None | 0 0
  1. import qualified Data.Matrix as M
  2. import qualified Data.Map as Mp
  3. import Data.List
  4. import Debug.Trace
  5.  
  6. main = do
  7. content <- readFile "input9"
  8. let ls = lines content
  9. let mx = parseInput ls
  10. loop mx 0
  11.  
  12. return ()
  13.  
  14. loop mx i = do
  15. print $ show i
  16. let isGoElves = (length $ (findTargets mx (E 0 0 1))) == 0
  17. let isGoGoblins = (length $ (findTargets mx (G 0 0 1))) == 0
  18. let isGameOver = isGoElves || isGoGoblins
  19. let hp = sum $ map (\a -> getHp a) $ M.toList mx
  20. if isGameOver then print ("GameOver " ++ (show hp) ++ " * (" ++ (show (i-1)) ++ " or " ++ (show i) ++ ")") else return ()
  21. printMatrix mx
  22. --x <- getLine
  23. --cls
  24. let x = ""
  25. if not isGameOver && x == "" then loop (moveAll mx) (i+1) else return()
  26.  
  27. printMatrix mx = do
  28. let ls = map (\l -> concat $ map show l) $ M.toLists mx
  29. mapM_ putStrLn ls
  30. return ()
  31.  
  32. cls = putStr "\ESC[2J"
  33.  
  34. data T = E Int Int Int | G Int Int Int | C Int Int | W Int Int
  35.  
  36. instance Show T where
  37. show (E _ _ hp) = "\ESC[32m" ++ (if hp > 100 then "E" else "e") ++ "\ESC[m"
  38. show (G _ _ hp) = "\ESC[31m" ++ (if hp > 100 then "G" else "g") ++ "\ESC[m"
  39. show (C _ _) = "."
  40. show (W _ _) = "#"
  41.  
  42. toT row col '.' = C row col
  43. toT row col '#' = W row col
  44. toT row col 'G' = G row col 200
  45. toT row col 'E' = E row col 200
  46.  
  47. isW (W _ _) = True
  48. isW _ = False
  49. isE (E _ _ _) = True
  50. isE _ = False
  51. isG (G _ _ _) = True
  52. isG _ = False
  53. isWeg t = isW t || isE t || isG t
  54.  
  55. getXY (E x y _) = (x, y)
  56. getXY (G x y _) = (x, y)
  57.  
  58. setXY (E x y hp) newX newY = (E newX newY hp)
  59. setXY (G x y hp) newX newY = (G newX newY hp)
  60.  
  61. getHp (E x y hp) = hp
  62. getHp (G x y hp) = hp
  63. getHp _ = 0
  64.  
  65. setHp (E x y hp) newHp = (E x y newHp)
  66. setHp (G x y hp) newHp = (G x y newHp)
  67.  
  68. getXYHp (E x y hp) = (x, y, hp)
  69. getXYHp (G x y hp) = (x, y, hp)
  70.  
  71. parseInput ls = M.matrix (M.nrows a) (M.ncols a) (\(i, j) -> toT i j $ M.getElem i j a)
  72. where a = M.fromLists ls
  73.  
  74. neighbours mx i j = [(x,y)| (x,y) <- [(i-1,j),(i+1,j),(i,j-1),(i,j+1)], let n = (at x y mx), not (isW n || isE n || isG n)]
  75. allNeigh mx i j = [(x,y)| (x,y) <- [(i-1,j),(i+1,j),(i,j-1),(i,j+1)], x > 0, y > 0, x < M.nrows mx, y < M.ncols mx]
  76.  
  77. at i j m = if (i < 1) || (j < 1) || (i >= M.nrows m) || (j >= M.ncols m) then W i j else M.getElem i j m
  78.  
  79. flood mx x y = flood' mx x y 0 $ M.zero 1 1
  80.  
  81. flood'::M.Matrix T->Int->Int->Int->M.Matrix Int->M.Matrix Int
  82. flood' mx x y n dx | n == 0 = flood' mx x y 1 $ M.matrix nrows ncols (\(i, j) -> init i j)
  83. | newDx == dx = dx
  84. | otherwise = flood' mx x y (n+1) $ newDx
  85. where ncols = M.ncols mx
  86. nrows = M.nrows mx
  87. init i j = if (i, j) == (x, y) then 0 else (if isWeg (at i j mx) then -1 else 1024)
  88. f i j = if (any (\(_x, _y) -> (M.getElem _x _y dx) == (n-1)) (allNeigh mx i j)) then min n (M.getElem i j dx) else (M.getElem i j dx)
  89. newDx = M.matrix nrows ncols (\(i, j) -> f i j)
  90.  
  91. findTargets mx t = filter (opponent t) $ M.toList mx
  92.  
  93. opponent t = if isE t then isG else isE
  94.  
  95. accquireTargets::M.Matrix T->T->[(Int,Int,Int)]
  96. accquireTargets mx t = targets
  97. where targets =
  98. filter (\(_, _, d) -> d < 1024) $
  99. sortOn (\(_, _, d) -> d) $
  100. sortOn (\(x, _, _) -> x) $
  101. sortOn (\(_, y, _) -> y) $
  102. map (\(x, y) -> (x, y, M.getElem x y edsgar)) $
  103. concat $
  104. map (\(x, y) -> neighbours mx x y) $
  105. map getXY $
  106. findTargets mx t
  107. (tx, ty) = getXY t
  108. edsgar = flood mx tx ty
  109.  
  110. moveAndAttack::M.Matrix T->T->M.Matrix T
  111. moveAndAttack mx t | False && trace ("moveAndAttack " ++ (show t) ++ (show $ getXY t) ++ " " ++ (show noNeedToMove)) False = undefined
  112. | targets == [] = attack mx t
  113. | noNeedToMove = attack mx t
  114. | otherwise = attack (M.setElem newC (x, y) $ M.setElem newT (newX, newY) mx) newT
  115. where targets = accquireTargets mx t
  116. target = head targets
  117. (tx, ty, _) = target
  118. (x, y) = getXY t
  119. edsgar = flood mx tx ty
  120. moves =
  121. sortOn (\(_, _, d) -> d) $
  122. sortOn (\(x, _, _) -> x) $
  123. sortOn (\(_, y, _) -> y) $
  124. map (\(x,y) -> (x, y, M.getElem x y edsgar)) $
  125. neighbours mx x y
  126. (newX, newY, _) = head moves
  127. newT = setXY t newX newY
  128. newC = C x y
  129. noNeedToMove = any (\(i, j) -> opponent t (M.getElem i j mx)) $ allNeigh mx x y
  130.  
  131. attack mx t | targets == [] = mx
  132. | otherwise = M.setElem newTarget' (tx, ty) mx
  133. where targets =
  134. sortOn (\(_, _, hp) -> hp) $
  135. sortOn (\(x, _, _) -> x) $
  136. sortOn (\(_, y, _) -> y) $
  137. map (\a-> getXYHp a) $
  138. filter (opponent t) $
  139. map (\(_x, _y) -> M.getElem _x _y mx) $ allNeigh mx x y
  140. (x, y) = getXY t
  141. (tx, ty, hp) = head targets
  142. target = M.getElem tx ty mx
  143. newTarget = setHp target (hp - 3)
  144. newTarget' = if (hp - 3) <= 0 then C tx ty else newTarget
  145.  
  146. moveAll mx = moveAll' mx positions
  147. where positions = map getXY $ filter (\a-> isE a || isG a) $ M.toList mx
  148. moveAll' mx [] = mx
  149. moveAll' mx ((x,y):ps) = moveAll' newMx ps
  150. where newMx = if (isE t || isG t) then moveAndAttack mx t else mx
  151. t = M.getElem x y mx
  152.  
  153.  
  154. -- 227480 -- to low
  155. -- 230065 -- to high
Add Comment
Please, Sign In to add comment