RTM5VGIPTRMJMKLJER4543HXDRMGUZ7TI5VJBOV4ZFGUCILNQ62QC WED2P6GBYNPFJNRTA26525ZQYZRKHYLGMMK3UNB2YCO6FBYPWMVQC 3AFV4YVYLZGHZDSMO3I3DCZE2BZKA2SOBQ6DI2GZILOUGHLVRCQAC JP5KERJHMIO542MNKCKTBDFEA3UY6CSWJTVUXTVRFEP4ECVA5YAAC V2W6DX4MIMIGH3LDIHD3VLKF7POSBGCKQEWNWO5GK2SI2WP2NPRAC O7B34AE2RCSSUKPDKL6VRLOAGH3OYXD6VAI6C6KHZMA7RWUMN2MQC Y2N6GDITBJID3Q4Z2Y7KEDY46F7R3SU4DRK3ST6ZMA4CNLXWSFDAC K7KUOYE2VONTDGZ6BIAGA3F7RYQEBNTY3LQOYQM4FH3MOUTLBL6AC 6TR3H656MQ3WM3RFWZRHWATU4G5MPRR2CEVM3BAVONWMRMVNVQ4QC IFLE5R5HZWDY2KFMVHXMNEFIJQTBPV4BULFHDFROQX6XEHP5WAXAC EW3Z5HY7MUE25EJ3EOJDR4F4GP4DQQSSMIYWP5LQEPSMMGUKKKJAC FU6HYDVYMIX5ZW5ZD5S76WXJBUOA3XTO2377PTHVNW2ZLT4DJUAAC ZP4SQLRCRHHHBBXI675BPLLGS3BABWJKHAPNOKFE3FHJ37UKSQ7AC XAAWYNRWJFUVJQB22ZVBK4JTXSSO5VRKLTQCTZLQTPQY4RVBLVDAC RIB2JXPMZHC5XCLGB7Q425PVNJPHMWPJSLMR2GTFLD474WB72ZHAC 7QP2V7ZBVZ7SKQ3SYV6NYA7V77G3Y7GF5V6EPIXLIYFSMFRWR4VAC ANAAF3LVFG2YCTAWUZKMT75XQN6YNS4CLLZIXSVGKJQRWJVNBMEAC JDI62ZLKN7J4572C7E2WL2HPGAMFU5YEIDOERVGIOBPOOV3DRF5AC HACJDNXD7FEKNTKY5XM3C5KXX4WT6SKOBJBK25JABK5KL6MTMYBAC RCDJ2AGX5X4FJ7B7XFLWFVMM6LTVZKTXONYQOYT4JQB7WX5TQPMQC playGame $ Game{ gTPS = 124, gInitState = (State { center = r , rand = r },set (Hex { look = pick r total , seed = rs , parent = Nothing , i = 1 }) 0 (verse size)), gLogicFunction = logic, gDrawFunction = draw}
io 42State { center = r , rand = r }set (Hex { look = pick r total , seed = rs , parent = Nothing , i = 1 }) 0 (verse size)
data State = State { center :: Int , rand :: Int }logic :: GEnv -> (State,Verse Hex) -> Event -> Either () (State,Verse Hex)logic _ (s,v) e| Tick <- e = Right (s,sim maze () v)| KeyPress 'r' <- e , r : rs <- seed (nodes v ! 0) = Right (s { rand = r },set (Hex { look = pick r total , seed = rs , parent = Nothing , i = 1 }) 0 (verse size))| KeyPress 'h' <- e = Right (s { center = shift v 1 H $ center s },v)| KeyPress 'j' <- e = Right (s { center = shift v 1 N $ center s },v)| KeyPress 'k' <- e = Right (s { center = shift v 1 I $ center s },v)| KeyPress 'l' <- e = Right (s { center = shift v 1 L $ center s },v)| otherwise = Right (s,v)draw :: GEnv -> (State,Verse Hex) -> Planedraw e (s,v) = centerFull e $ hcat [hex,ui] & (1,1) % makeTransparent ' ' (word "hex maze")wherecanvas :: Planecanvas = blankPlane (2 * succ (2 * size) + 2) (succ (2 * size) + 2)hex :: Planehex = foldl (&) canvas [ write (x,y) | x <- [-size..size] , y <- [-size..size] , abs (x + y) <= size ]spectrum :: Int -> Colour Floatspectrum i = sRGB r g bwhere
RGB r g b = hsv (fromIntegral (mod i n) / fromIntegral n * 360) 1 1n = 6 * size * sizewrite :: (Int,Int) -> Drawwrite (x,y)| Just _ <- look h = c %.< cell '*' # color White Dull| 0 < i h = c %.< cell 'o' # rgbColor (spectrum $ i h + rand s)| otherwise = c %.< cell ' 'whereh :: Hexh = node v n-- get index of node taking scroll into accountn :: Intn = shift v mx L . shift v my I $ coordToIndex v (mod (x - div y size * size) (3 * size) , mod y size)where(mx,my) = indexToCoord v (center s)-- stretch, tilt, margin, translate to library coordinate system (1-based (y,x))c :: (Int,Int)c = join bimap succ (y + size , 2 * (x + size) + y)ui :: Plane-- ui = word "> ui content here <"ui = foldl (&) canvas[ (1,1) % vcat [info]]whereinfo :: Plane| Just h <- find (isJust . look) $ nodes v = stringPlane $ unlines $ unwords <$>[ ["value:" , show $ i h], ["look:" , show $ look h], ["anchor:" , show $ parent h]]| otherwise = word "none" # color Red Vivid
l :: Dir -> Hex -> Booll dir n| Just d <- look n = dir == opposite d| otherwise = False
l :: Dir -> Maybe (Dir,Hex)l dir| Just d <- look n , dir == opposite d = Just (dir,n)| otherwise = Nothingwheren = ns dirinstance Ansi State Hex wheretps :: TPStps = 42logic :: GEnv -> (State,Verse Hex) -> Event -> Either () (State,Verse Hex)logic _ (s,v) e| Tick <- e = Right (s,sim maze () v)| KeyPress 'r' <- e , r : rs <- seed (nodes v ! 0) = Right (s { rand = r },set (Hex { look = pick r total , seed = rs , parent = Nothing , i = 1 }) 0 (verse size))| KeyPress 'h' <- e = Right (s { center = shift v 1 H $ center s },v)| KeyPress 'j' <- e = Right (s { center = shift v 1 N $ center s },v)| KeyPress 'k' <- e = Right (s { center = shift v 1 I $ center s },v)| KeyPress 'l' <- e = Right (s { center = shift v 1 L $ center s },v)| otherwise = Right (s,v)draw :: GEnv -> (State,Verse Hex) -> Planedraw e (s,v) = centerFull e $ hcat [hex,ui] & (1,1) % makeTransparent ' ' (word "hex maze")wherecanvas :: Planecanvas = blankPlane (2 * succ (2 * size) + 2) (succ (2 * size) + 2)hex :: Planehex = foldl (&) canvas [ write (x,y) | x <- [-size..size] , y <- [-size..size] , abs (x + y) <= size ]spectrum :: Int -> Colour Floatspectrum i = sRGB r g bwhereRGB r g b = hsv (fromIntegral (mod i n) / fromIntegral n * 360) 1 1n = 6 * size * sizewrite :: (Int,Int) -> Drawwrite (x,y)| Just _ <- look h = c %.< cell '*' # color White Dull| 0 < i h = c %.< cell 'o' # rgbColor (spectrum $ i h + rand s)| otherwise = c %.< cell ' 'whereh :: Hexh = node v n-- get index of node taking scroll into accountn :: Intn = shift v mx L . shift v my I $ coordToIndex v (mod (x - div y size * size) (3 * size) , mod y size)where(mx,my) = indexToCoord v (center s)-- stretch, tilt, margin, translate to library coordinate system (1-based (y,x))c :: (Int,Int)c = join bimap succ (y + size , 2 * (x + size) + y)ui :: Plane-- ui = word "> ui content here <"ui = foldl (&) canvas[ (1,1) % vcat [info]]where
info :: Planeinfo = word "mazing"
playGame $ Game {gTPS = 9 ,gInitState = (State { rand = r , center = 0 , input = (Nothing , mempty) , mode = Full , play = False } , generate (verse 11) rs) ,gLogicFunction = logic ,gDrawFunction = draw }
io 19State { rand = r , center = 0 , input = (Nothing , mempty) , mode = Full , play = False }(generate (verse 24) rs)
logic :: GEnv -> (State,Verse Unit) -> Event -> Either () (State,Verse Unit)logic g (s,v) e| KeyPress 'q' <- e = Left ()| KeyPress 'p' <- e = Right (s { play = True } , v)| KeyPress 'P' <- e = Right (s { play = False } , v)| KeyPress 'c' <- e = Right (s { mode = Dumb } , v)| KeyPress 'C' <- e = Right (s { mode = Full } , v)| KeyPress 'H' <- e = Right (s { center = shift v 1 H $ center s } , v)| KeyPress 'J' <- e = Right (s { center = shift v 1 N $ center s } , v)| KeyPress 'K' <- e = Right (s { center = shift v 1 I $ center s } , v)| KeyPress 'L' <- e = Right (s { center = shift v 1 L $ center s } , v)| KeyPress '.' <- e = Right (s' { play = False } , sim demo s' v)| KeyPress k <- e = Right (s { input = input' k } , v)| play s , Tick <- e = Right (s' , sim demo s' v)| otherwise = Right (s , v)where
me :: Unit -> Boolme a| Robot {} <- a , "@" <- name a = True| otherwise = False
-- prevent repeat before tickinput' :: Char -> (Maybe Char,Queue Char)input' k-- | Just (q,_) <- dequeue $ snd $ input s , k == q = input s| otherwise = enqueue k <$> input s
-- Unit Automaton
s' :: State-- | Just 'x' <- k = z { }| otherwise = z
f :: State -> (Dir -> Unit) -> Unit -> Unitf s ns u| Robot { ops = [] } <- u , Just dir <- push = u { ops = [Move dir] } -- push| me u = me'| Robot {} <- u = u { ops = drop 1 $ ops u }| otherwise = u
write :: (Int,Int) -> Drawwrite (x,y) = c %.< cell (grapheme a) # style a
logic :: GEnv -> (State,Verse Unit) -> Event -> Either () (State,Verse Unit)logic g (s,v) e| KeyPress 'q' <- e = Left ()| KeyPress 'p' <- e = Right (s { play = True } , v)| KeyPress 'P' <- e = Right (s { play = False } , v)| KeyPress 'c' <- e = Right (s { mode = Dumb } , v)| KeyPress 'C' <- e = Right (s { mode = Full } , v)| KeyPress 'H' <- e = Right (s { center = shift v 1 H $ center s } , v)| KeyPress 'J' <- e = Right (s { center = shift v 1 N $ center s } , v)| KeyPress 'K' <- e = Right (s { center = shift v 1 I $ center s } , v)| KeyPress 'L' <- e = Right (s { center = shift v 1 L $ center s } , v)| KeyPress '.' <- e = Right (s' { play = False } , sim demo s' v)| KeyPress k <- e = Right (s { input = input' k } , v)| play s , Tick <- e = Right (s' , sim demo s' v)| otherwise = Right (s , v)
ui :: Plane-- ui = word "> ui content here <"ui = foldl (&) canvas[ (1,1) % vcat (intersperse (cell ' ')[ key, hcat[ scope $ take 1 $ IntMap.keys $ IntMap.filter me $ nodes v, cell ' ', vcat [word "",info]]])]
draw :: GEnv -> (State,Verse Unit) -> Planedraw e (s,v) = centerFull e $ hcat [hex,ui] & (1,1) % makeTransparent ' ' (word "nove demo")
scope :: [Int] -> Planescope n| i : _ <- n = foldl (&) (blankPlane 5 3)[ (1,2) % let a = adjacents v i Map.! U in cell (grapheme a) # style a, (1,4) % let a = adjacents v i Map.! I in cell (grapheme a) # style a, (2,1) % let a = adjacents v i Map.! H in cell (grapheme a) # style a, (2,3) % let a = node v i in cell (grapheme a), (2,5) % let a = adjacents v i Map.! L in cell (grapheme a) # style a, (3,2) % let a = adjacents v i Map.! N in cell (grapheme a) # style a, (3,4) % let a = adjacents v i Map.! M in cell (grapheme a) # style a
-- get index of node taking scroll into accountn :: Intn = shift v mx L . shift v my I $ coordToIndex v (mod (x - div y r * r) (3 * r) , mod y r)where
| Wall <- a = '#'| Box {} <- a = 'x'| Robot {} <- a = maybe 'o' (const '@') $ move a
ui :: Plane-- ui = word "> ui content here <"ui = foldl (&) canvas[ (1,1) % vcat (intersperse (cell ' ')[ key, hcat[ scope $ take 1 $ IntMap.keys $ IntMap.filter me $ nodes v, cell ' ', vcat [word "",info]]])]where
| Dumb <- mode s , me a = color White Dull| Dumb <- mode s , not (mass a) = color Black Vivid| Dumb <- mode s , Robot {} <- a , "t0" <- name a = color Blue Dull| Dumb <- mode s , Robot {} <- a , "t1" <- name a = color Magenta Dull| Dumb <- mode s , Robot {} <- a , "t2" <- name a = color Red Dull| Dumb <- mode s , Robot {} <- a , "d0" <- name a = color Yellow Dull| Dumb <- mode s , Robot {} <- a , "d1" <- name a = color Green Dull| Dumb <- mode s , Robot {} <- a , 'L':_ <- name a = color Cyan Dull| Dumb <- mode s , Robot {} <- a , "r0" <- name a = color White Vivid| Dumb <- mode s , Robot {} <- a , "r1" <- name a = color Black Vivid| Dumb <- mode s , Robot {} <- a , "m0" <- name a = color Green Vivid| Dumb <- mode s , Robot {} <- a , "m1" <- name a = color Green Vivid| Dumb <- mode s , Robot {} <- a , "p0" <- name a = color White Dull| Dumb <- mode s , Robot {} <- a , "Tp" <- name a = color White Dull| Dumb <- mode s , Robot {} <- a , "T0" <- name a = color Blue Dull| Dumb <- mode s , Robot {} <- a , "T1" <- name a = color Magenta Dull| Dumb <- mode s , Robot {} <- a , "T2" <- name a = color Red Dull| Dumb <- mode s = color White Vivid
key :: Planekey = word (maybe id (:) c $ toList q) # color Black Vividinfo :: Plane| Just m <- find me $ nodes v = word $ show m| otherwise = word "no robot found!" # color Red Vivid
| Full <- mode s , me a = rgbColor $ sRGB24 0x21 0xb2 0x8e -- #21b28e| Full <- mode s , not (mass a) = rgbColor $ sRGB24 0x66 0x66 0x66 -- #666666| Full <- mode s , Robot {} <- a , "t0" <- name a = rgbColor $ sRGB24 0x66 0x66 0x99 -- #666699| Full <- mode s , Robot {} <- a , "t1" <- name a = rgbColor $ sRGB24 0x99 0x66 0x99 -- #996699| Full <- mode s , Robot {} <- a , "t2" <- name a = rgbColor $ sRGB24 0x99 0x66 0x66 -- #996666| Full <- mode s , Robot {} <- a , "d0" <- name a = rgbColor $ sRGB24 0x99 0x99 0x66 -- #999966| Full <- mode s , Robot {} <- a , "d1" <- name a = rgbColor $ sRGB24 0x66 0x99 0x66 -- #669966| Full <- mode s , Robot {} <- a , 'L':_ <- name a = rgbColor $ sRGB24 0x66 0x99 0x99 -- #669999| Full <- mode s , Robot {} <- a , "r0" <- name a = rgbColor $ sRGB24 0x99 0x99 0x99 -- #999999| Full <- mode s , Robot {} <- a , "r1" <- name a = rgbColor $ sRGB24 0x66 0x66 0x66 -- #666666| Full <- mode s , Robot {} <- a , "m0" <- name a = rgbColor $ sRGB24 0x93 0xe9 0xbe -- #93e9be| Full <- mode s , Robot {} <- a , "m1" <- name a = rgbColor $ sRGB24 0x93 0xe9 0xbe -- #93e9be| Full <- mode s , Robot {} <- a , "p0" <- name a = rgbColor $ sRGB24 0xff 0xff 0xff -- #ffffff| Full <- mode s , Robot {} <- a , "Tp" <- name a = rgbColor $ sRGB24 0xff 0xff 0xff -- #ffffff| Full <- mode s , Robot {} <- a , "T0" <- name a = rgbColor $ sRGB24 0x66 0x66 0x99 -- #666699| Full <- mode s , Robot {} <- a , "T1" <- name a = rgbColor $ sRGB24 0x99 0x66 0x99 -- #996699| Full <- mode s , Robot {} <- a , "T2" <- name a = rgbColor $ sRGB24 0x99 0x66 0x66 -- #996666| Full <- mode s = rgbColor $ sRGB24 0x99 0x99 0x99 -- #999999
scope :: [Int] -> Planescope n| i : _ <- n = foldl (&) (blankPlane 5 3)[ (1,2) % let a = neighbours v i U in cell (grapheme a) # style a, (1,4) % let a = neighbours v i I in cell (grapheme a) # style a, (2,1) % let a = neighbours v i H in cell (grapheme a) # style a, (2,3) % let a = node v i in cell (grapheme a), (2,5) % let a = neighbours v i L in cell (grapheme a) # style a, (3,2) % let a = neighbours v i N in cell (grapheme a) # style a, (3,4) % let a = neighbours v i M in cell (grapheme a) # style a
f :: State -> Map Dir Unit -> Unit -> Unitf s ns u| Robot { ops = [] } <- u , Just dir <- push = u { ops = [Move dir] } -- push| me u = me'| Robot {} <- u = u { ops = drop 1 $ ops u }| otherwise = uwhere
| Wall <- a = '#'| Box {} <- a = 'x'| Robot {} <- a = maybe 'o' (const '@') $ move a
me' :: Unit| Just 'h' <- fst $ input s = u { ops = [Move H] }| Just 'j' <- fst $ input s = u { ops = [Move N] }| Just 'k' <- fst $ input s = u { ops = [Move I] }| Just 'l' <- fst $ input s = u { ops = [Move L] }| otherwise = u { ops = [] }
style :: Unit -> Drawstyle a
push :: Maybe Dir| [dir] <- Map.keys $ Map.filterWithKey p ns = Just $ opposite dir| otherwise = Nothingwhere
| Dumb <- mode s , me a = color White Dull| Dumb <- mode s , not (mass a) = color Black Vivid| Dumb <- mode s , Robot {} <- a , "t0" <- name a = color Blue Dull| Dumb <- mode s , Robot {} <- a , "t1" <- name a = color Magenta Dull| Dumb <- mode s , Robot {} <- a , "t2" <- name a = color Red Dull| Dumb <- mode s , Robot {} <- a , "d0" <- name a = color Yellow Dull| Dumb <- mode s , Robot {} <- a , "d1" <- name a = color Green Dull| Dumb <- mode s , Robot {} <- a , 'L':_ <- name a = color Cyan Dull| Dumb <- mode s , Robot {} <- a , "r0" <- name a = color White Vivid| Dumb <- mode s , Robot {} <- a , "r1" <- name a = color Black Vivid| Dumb <- mode s , Robot {} <- a , "m0" <- name a = color Green Vivid| Dumb <- mode s , Robot {} <- a , "m1" <- name a = color Green Vivid| Dumb <- mode s , Robot {} <- a , "p0" <- name a = color White Dull| Dumb <- mode s , Robot {} <- a , "Tp" <- name a = color White Dull| Dumb <- mode s , Robot {} <- a , "T0" <- name a = color Blue Dull| Dumb <- mode s , Robot {} <- a , "T1" <- name a = color Magenta Dull| Dumb <- mode s , Robot {} <- a , "T2" <- name a = color Red Dull| Dumb <- mode s = color White Vivid
p :: Dir -> Unit -> Boolp dir n = mass n && move n == Just (opposite dir)
| Full <- mode s , me a = rgbColor $ sRGB24 0x21 0xb2 0x8e -- #21b28e| Full <- mode s , not (mass a) = rgbColor $ sRGB24 0x66 0x66 0x66 -- #666666| Full <- mode s , Robot {} <- a , "t0" <- name a = rgbColor $ sRGB24 0x66 0x66 0x99 -- #666699| Full <- mode s , Robot {} <- a , "t1" <- name a = rgbColor $ sRGB24 0x99 0x66 0x99 -- #996699| Full <- mode s , Robot {} <- a , "t2" <- name a = rgbColor $ sRGB24 0x99 0x66 0x66 -- #996666| Full <- mode s , Robot {} <- a , "d0" <- name a = rgbColor $ sRGB24 0x99 0x99 0x66 -- #999966| Full <- mode s , Robot {} <- a , "d1" <- name a = rgbColor $ sRGB24 0x66 0x99 0x66 -- #669966| Full <- mode s , Robot {} <- a , 'L':_ <- name a = rgbColor $ sRGB24 0x66 0x99 0x99 -- #669999| Full <- mode s , Robot {} <- a , "r0" <- name a = rgbColor $ sRGB24 0x99 0x99 0x99 -- #999999| Full <- mode s , Robot {} <- a , "r1" <- name a = rgbColor $ sRGB24 0x66 0x66 0x66 -- #666666| Full <- mode s , Robot {} <- a , "m0" <- name a = rgbColor $ sRGB24 0x93 0xe9 0xbe -- #93e9be| Full <- mode s , Robot {} <- a , "m1" <- name a = rgbColor $ sRGB24 0x93 0xe9 0xbe -- #93e9be| Full <- mode s , Robot {} <- a , "p0" <- name a = rgbColor $ sRGB24 0xff 0xff 0xff -- #ffffff| Full <- mode s , Robot {} <- a , "Tp" <- name a = rgbColor $ sRGB24 0xff 0xff 0xff -- #ffffff| Full <- mode s , Robot {} <- a , "T0" <- name a = rgbColor $ sRGB24 0x66 0x66 0x99 -- #666699| Full <- mode s , Robot {} <- a , "T1" <- name a = rgbColor $ sRGB24 0x99 0x66 0x99 -- #996699| Full <- mode s , Robot {} <- a , "T2" <- name a = rgbColor $ sRGB24 0x99 0x66 0x66 -- #996666| Full <- mode s = rgbColor $ sRGB24 0x99 0x99 0x99 -- #999999
step :: forall a. Atom a => (Map Dir a -> a -> a) -> Verse a -> Verse astep f v = v { nodes = mapWithKey (f . adjacents v) nodes' }
step :: forall a. Atom a => ((Dir -> a) -> a -> a) -> Verse a -> Verse astep f v = v { nodes = mapWithKey (f . neighbours v) nodes' }
| count (== minimum ns) ns <= fromEnum a - fromEnum (minimum ns) = prev a| fromEnum (sum $ Map.filter (> a) ns) > Map.size ns = next a
| count (== minimum adjacents) adjacents <= fromEnum a - fromEnum (minimum adjacents) = prev a| fromEnum (sum $ filter (> a) adjacents) > length adjacents = next a
| count (== maxBound) ns ∈ survive , fromEnum a > n - 2 = maxBound| count (== maxBound) ns ∈ born , a < succ minBound = maxBound
| count (== maxBound) adjacents ∈ survive , fromEnum a > n - 2 = maxBound| count (== maxBound) adjacents ∈ born , fromEnum a < 1 = maxBound