nicer level parser
This commit is contained in:
parent
50a01efc5f
commit
884ea15e6c
130
app/Main.hs
130
app/Main.hs
|
@ -10,6 +10,7 @@ import System.Environment ( getArgs )
|
||||||
|
|
||||||
import Model
|
import Model
|
||||||
import Rendering ( render )
|
import Rendering ( render )
|
||||||
|
import Parser (parse)
|
||||||
|
|
||||||
data Game = Game {
|
data Game = Game {
|
||||||
gameWorlds :: NonEmpty World,
|
gameWorlds :: NonEmpty World,
|
||||||
|
@ -72,6 +73,7 @@ worldList = Map.fromList
|
||||||
, ("infiniteEnter17", infiniteEnter17)
|
, ("infiniteEnter17", infiniteEnter17)
|
||||||
, ("infiniteEnter19", infiniteEnter19)
|
, ("infiniteEnter19", infiniteEnter19)
|
||||||
, ("infiniteEnter20", infiniteEnter20)
|
, ("infiniteEnter20", infiniteEnter20)
|
||||||
|
, ("multiInfinite5", multiInfinite5)
|
||||||
, ("multiInfinite8", multiInfinite8)
|
, ("multiInfinite8", multiInfinite8)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -174,56 +176,58 @@ center8 =
|
||||||
(Location 'a' 3 2)
|
(Location 'a' 3 2)
|
||||||
|
|
||||||
center13 :: World
|
center13 :: World
|
||||||
center13 =
|
center13 = parse
|
||||||
World
|
"player p\n\
|
||||||
(Map.fromList
|
\block t cyan boring\n\
|
||||||
[('a',
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
Box (Location 'a' 3 (-3))
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
(Original (makeWalls [
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
"▓▓▓▓▓▓▓▓▓",
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
"▓ ▓",
|
\▓▓▓▓t▓a▓▓\n\
|
||||||
"▓ ▓",
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
"▓ ▓",
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
"▓ ▓",
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
"▓ ▓▓▓ ▓▓",
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
"▓ ▓ ▓ ▓▓",
|
\block a cyan interesting\n\
|
||||||
"▓ ▓▓ ▓",
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
"▓▓▓▓▓▓▓▓▓"
|
\▓ p =▓\n\
|
||||||
]))
|
\▓ ▓\n\
|
||||||
(withForeColor defAttr cyan)
|
\▓ x g ▓\n\
|
||||||
False),
|
\▓ ▓\n\
|
||||||
('1',
|
\▓ ▓▓▓ ▓▓\n\
|
||||||
Box
|
\▓ ▓-▓ ▓▓\n\
|
||||||
(Location 'a' (-1) 1)
|
\▓ ▓ ▓\n\
|
||||||
(Original (makeWalls [
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
" ",
|
\block g green interesting\n\
|
||||||
" ▓▓▓▓▓▓▓ ",
|
\ \n\
|
||||||
" ▓▓▓▓▓▓▓ ",
|
\ ▓▓▓▓▓▓▓ \n\
|
||||||
" ▓▓▓▓▓▓▓ ",
|
\ ▓▓▓▓▓▓▓ \n\
|
||||||
" ▓▓▓▓▓▓▓ ",
|
\ ▓▓▓▓▓▓▓ \n\
|
||||||
" ▓▓▓▓▓▓▓ ",
|
\ ▓▓▓▓▓▓▓ \n\
|
||||||
" ▓▓▓▓▓▓▓ ",
|
\ ▓▓▓▓▓▓▓ \n\
|
||||||
" ▓▓▓▓▓▓▓ ",
|
\ ▓▓▓▓▓▓▓ \n\
|
||||||
" "
|
\ ▓▓▓▓▓▓▓ \n\
|
||||||
]))
|
\ \n\
|
||||||
(withForeColor defAttr green)
|
\block x yellow boring\n\
|
||||||
False),
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
('2',
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
Box
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
(Location 'a' (-1) (-1))
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
(Original (solid 9))
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
(withForeColor defAttr yellow)
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
True),
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
('b',
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
Box
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
(Location 'a' (-3) 0)
|
\block p magenta boring\n\
|
||||||
(Original (solid 9))
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
(withForeColor defAttr red)
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
True)
|
\▓ ▓▓▓ ▓▓▓\n\
|
||||||
]) 'b'
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
Set.empty
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
(Location 'a' 2 0)
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
|
\▓▓▓▓▓▓▓▓▓\n"
|
||||||
|
|
||||||
clone11 :: World
|
clone11 :: World
|
||||||
clone11 =
|
clone11 =
|
||||||
|
@ -1234,6 +1238,32 @@ infiniteEnter20 =
|
||||||
Set.empty
|
Set.empty
|
||||||
(Location 'w' (-3) 3)
|
(Location 'w' (-3) 3)
|
||||||
|
|
||||||
|
multiInfinite5 :: World
|
||||||
|
multiInfinite5 = parse
|
||||||
|
"player p\n\
|
||||||
|
\block b blue interesting\n\
|
||||||
|
\▓▓▓ ▓\n\
|
||||||
|
\▓▓▓ ▓\n\
|
||||||
|
\▓▓▓ b 1 ▓\n\
|
||||||
|
\▓=▓ p ▓\n\
|
||||||
|
\▓-▓ 3 2 ▓\n\
|
||||||
|
\▓-▓ ▓\n\
|
||||||
|
\▓-▓ ▓\n\
|
||||||
|
\▓ ▓\n\
|
||||||
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
|
\block p magenta boring\n\
|
||||||
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
|
\▓▓ ▓▓▓ ▓▓\n\
|
||||||
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
|
\▓▓▓▓▓▓▓▓▓\n\
|
||||||
|
\infinity 1 b blue\n\
|
||||||
|
\infinity 2 b blue\n\
|
||||||
|
\infinity 3 b blue\n"
|
||||||
|
|
||||||
multiInfinite8 :: World
|
multiInfinite8 :: World
|
||||||
multiInfinite8 =
|
multiInfinite8 =
|
||||||
|
|
78
app/Parser.hs
Normal file
78
app/Parser.hs
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
{-# Language ViewPatterns #-}
|
||||||
|
module Parser where
|
||||||
|
|
||||||
|
import Model
|
||||||
|
import Graphics.Vty.Attributes
|
||||||
|
import Data.Array (Array, listArray)
|
||||||
|
import Data.Map qualified as Map
|
||||||
|
import Data.Set qualified as Set
|
||||||
|
|
||||||
|
parse :: String -> World
|
||||||
|
parse str = either error id $
|
||||||
|
case lines str of
|
||||||
|
x:xs ->
|
||||||
|
do h <- parseHeader x
|
||||||
|
bs <- parseBlocks xs
|
||||||
|
let m = Map.fromListWith (++) [(k,[v]) | (_,_,kvs) <- bs, (k,v) <- kvs]
|
||||||
|
pure $ World
|
||||||
|
(Map.fromList [
|
||||||
|
(n, b { boxLocation = head (m Map.! n)})
|
||||||
|
| (n,b,_) <- bs
|
||||||
|
])
|
||||||
|
h
|
||||||
|
(Set.fromList (Map.findWithDefault [] '-' m))
|
||||||
|
(head (m Map.! '='))
|
||||||
|
[] -> Left "empty input"
|
||||||
|
|
||||||
|
parseHeader :: String -> Either String Char
|
||||||
|
parseHeader (words -> ["player", [p]]) = Right p
|
||||||
|
parseHeader _ = Left "bad header"
|
||||||
|
|
||||||
|
parseBlocks :: [String] -> Either String [(Char, Box, [(Char, Location)])]
|
||||||
|
parseBlocks [] = Right []
|
||||||
|
parseBlocks (x:xs) =
|
||||||
|
case words x of
|
||||||
|
["block", [name], color, boring] ->
|
||||||
|
do color_ <- parseColor color
|
||||||
|
let (xs1,xs2) = splitAt 9 xs
|
||||||
|
let locs = findLocs name xs1
|
||||||
|
let b = Box undefined (Original (walls xs1)) color_ (boring == "boring")
|
||||||
|
bs <- parseBlocks xs2
|
||||||
|
pure ((name, b, locs):bs)
|
||||||
|
["link", [name], [target], color] ->
|
||||||
|
do color_ <- parseColor color
|
||||||
|
bs <- parseBlocks xs
|
||||||
|
pure ((name, Box undefined (Link target) color_ True, []):bs)
|
||||||
|
["infinity", [name], [target], color] ->
|
||||||
|
do color_ <- parseColor color
|
||||||
|
bs <- parseBlocks xs
|
||||||
|
pure ((name, Box undefined (Infinity target) color_ False,[]):bs)
|
||||||
|
["epsilon", [name], [target], color] ->
|
||||||
|
do color_ <- parseColor color
|
||||||
|
let (xs1,xs2) = splitAt 9 xs
|
||||||
|
let locs = findLocs name xs1
|
||||||
|
let b = Box undefined (Epsilon target (walls xs1)) color_ False
|
||||||
|
bs <- parseBlocks xs2
|
||||||
|
pure ((name, b, locs):bs)
|
||||||
|
_ -> Left "bad block"
|
||||||
|
|
||||||
|
parseColor :: String -> Either String Attr
|
||||||
|
parseColor "white" = Right (withForeColor defAttr white)
|
||||||
|
parseColor "cyan" = Right (withForeColor defAttr cyan)
|
||||||
|
parseColor "blue" = Right (withForeColor defAttr blue)
|
||||||
|
parseColor "red" = Right (withForeColor defAttr red)
|
||||||
|
parseColor "yellow" = Right (withForeColor defAttr yellow)
|
||||||
|
parseColor "magenta" = Right (withForeColor defAttr magenta)
|
||||||
|
parseColor "black" = Right (withForeColor defAttr black)
|
||||||
|
parseColor "green" = Right (withForeColor defAttr green)
|
||||||
|
parseColor x = Left ("bad color " ++ x)
|
||||||
|
|
||||||
|
walls :: [String] -> Array Coord Bool
|
||||||
|
walls rows = listArray ((-4,-4),(4,4)) (map ('▓'==) (concat rows))
|
||||||
|
|
||||||
|
findLocs :: Char -> [[Char]] -> [(Char, Location)]
|
||||||
|
findLocs name xs =
|
||||||
|
[ (c, Location name y x)
|
||||||
|
| (y, row) <- zip [-4..] xs
|
||||||
|
, (x, c ) <- zip [-4..] row
|
||||||
|
]
|
|
@ -19,7 +19,7 @@ common warnings
|
||||||
executable parabox
|
executable parabox
|
||||||
import: warnings
|
import: warnings
|
||||||
main-is: Main.hs
|
main-is: Main.hs
|
||||||
other-modules: Rendering, Model
|
other-modules: Rendering, Model, Parser
|
||||||
-- other-modules:
|
-- other-modules:
|
||||||
default-extensions: ImportQualifiedPost, BlockArguments, LambdaCase
|
default-extensions: ImportQualifiedPost, BlockArguments, LambdaCase
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user