parabox/app/Main.hs

434 lines
11 KiB
Haskell
Raw Normal View History

2022-11-30 13:38:12 -08:00
module Main where
import Data.Map qualified as Map
import Graphics.Vty
import Control.Exception
import Data.List.NonEmpty (NonEmpty(..))
import Data.List.NonEmpty qualified as NonEmpty
2022-12-02 20:53:45 -08:00
import Data.Set qualified as Set
import System.Environment
2022-11-30 13:38:12 -08:00
2022-12-02 10:54:31 -08:00
import Model
import Rendering
2022-11-30 16:44:30 -08:00
2022-11-30 13:38:12 -08:00
world0 :: World
world0 = World {
2022-12-02 20:53:45 -08:00
worldButtons = Set.empty,
worldHome = Location '2' 0 0,
2022-11-30 13:38:12 -08:00
worldMe = 'b',
worldBoxes = Map.fromList
[('1', Box {
boxColor = withForeColor defAttr green,
boxLocation = Location '1' (-1) 0,
2022-12-02 15:28:05 -08:00
boxType = Original $ makeWalls [
2022-12-02 15:46:42 -08:00
"▓▓ ▓▓",
"▓ ▓",
"▓ ▓",
"▓ ▓",
"",
"▓ ▓ ▓",
"▓ ▓",
"▓ ▓",
"▓ ▓▓▓▓▓ ▓"
2022-11-30 13:38:12 -08:00
]
}),
('2', Box {
boxColor = withForeColor defAttr cyan,
boxLocation = Location '1' 1 1,
2022-12-02 15:28:05 -08:00
boxType = Original $ makeWalls [
2022-12-02 15:46:42 -08:00
"▓ ▓▓ ▓▓ ▓",
" ",
2022-12-02 18:49:26 -08:00
"",
"",
2022-12-02 15:46:42 -08:00
" ",
"▓ ▓",
"▓ ▓",
" ",
"▓ ▓▓ ▓▓ ▓"
2022-11-30 13:38:12 -08:00
]
2022-11-30 23:20:18 -08:00
}),
2022-12-02 15:28:05 -08:00
('₂', Box {
boxColor = withForeColor defAttr cyan,
boxLocation = Location '1' 2 (-1),
boxType = Link '2'
}),
2022-11-30 23:20:18 -08:00
('3', Box {
boxColor = withForeColor defAttr blue,
boxLocation = Location '2' 1 1,
2022-12-02 15:28:05 -08:00
boxType = Original $ makeWalls [
2022-12-02 15:46:42 -08:00
"▓▓▓▓▓▓▓▓▓",
2022-12-02 18:49:26 -08:00
" ",
"▓▓▓▓▓▓▓▓ ",
"▓▓ ▓▓▓ ",
"▓▓ ▓▓▓ ",
"▓▓▓▓ ▓▓▓ ",
2022-12-02 15:46:42 -08:00
"▓▓ ▓▓▓▓",
"▓▓ ▓▓▓▓",
"▓▓▓▓ ▓▓▓▓"
2022-11-30 23:20:18 -08:00
]
}),
('4', Box {
boxColor = withForeColor defAttr black,
2022-12-02 15:46:42 -08:00
boxLocation = Location 'b' (-3) 0,
2022-12-02 15:28:05 -08:00
boxType = Original $ makeWalls [
2022-12-02 15:46:42 -08:00
"▓▓▓ ▓▓▓",
"▓ ▓ ▓",
"▓ ▓",
"▓ ▓",
"▓ ▓",
"▓ ▓",
"▓ ▓",
"▓ ▓",
"▓▓▓▓ ▓▓▓▓"
2022-11-30 23:20:18 -08:00
]
2022-11-30 13:38:12 -08:00
}),
('b', Box {
boxColor = withForeColor defAttr red,
boxLocation = Location '1' 0 1,
2022-12-02 15:28:05 -08:00
boxType = Original $ makeWalls [
2022-12-02 15:46:42 -08:00
"▓▓▓▓▓▓▓▓▓",
"▓ ▓",
"▓ ▓",
2022-12-02 18:49:26 -08:00
"▓ ▓ ▓ ▓",
"▓ ▓",
2022-12-02 15:46:42 -08:00
"▓ ▓",
"▓ ▓",
"▓ ▓",
"▓▓▓▓▓▓▓▓▓"
2022-12-02 11:26:00 -08:00
]
2022-11-30 13:38:12 -08:00
}),
('x', Box {
boxColor = withForeColor defAttr yellow,
boxLocation = Location '1' 0 (-1),
2022-12-02 18:49:26 -08:00
boxType = Original $
makeWalls [
"▓▓ ▓ ",
" ",
" ▓ ▓▓▓ ",
"",
"▓ ▓▓▓▓",
" ▓▓▓ ",
" ▓ ▓▓▓ ",
" ",
"▓ ▓ ▓"
]
2022-11-30 13:38:12 -08:00
}),
('y', Box {
boxColor = withForeColor defAttr magenta,
boxLocation = Location '1' 0 (-2),
2022-12-02 18:49:26 -08:00
boxType = Original $ makeWalls [
"▓▓ ▓ ",
" ",
"▓▓ ▓▓▓ ",
"▓▓ ",
" ▓▓▓▓",
"▓▓▓▓ ",
"▓▓ ▓▓▓ ",
" ",
"▓ ▓ ▓"
]
2022-12-02 11:26:00 -08:00
}),
('i', Box {
boxColor = withForeColor defAttr black,
boxLocation = Location 'b' 0 (-2),
2022-12-02 15:46:42 -08:00
boxType = Original $ solid 9
2022-12-02 11:26:00 -08:00
}),
('j', Box {
boxColor = withForeColor defAttr black,
boxLocation = Location 'b' 0 (-1),
2022-12-02 15:46:42 -08:00
boxType = Original $ solid 9
2022-12-02 11:26:00 -08:00
}),
('k', Box {
boxColor = withForeColor defAttr black,
boxLocation = Location 'b' 0 0,
2022-12-02 15:46:42 -08:00
boxType = Original $ solid 9
2022-12-02 11:26:00 -08:00
}),
('l', Box {
boxColor = withForeColor defAttr black,
boxLocation = Location 'b' 0 1,
2022-12-02 15:46:42 -08:00
boxType = Original $ solid 9
2022-12-02 15:28:05 -08:00
}),
('₁', Box {
boxColor = withForeColor defAttr green,
boxLocation = Location '1' 2 1,
boxType = Link '1'
2022-11-30 13:38:12 -08:00
})
]
}
main :: IO ()
main =
2022-12-02 20:53:45 -08:00
do args <- getArgs
2022-12-02 20:56:58 -08:00
case args of
x:_ | Just w <- Map.lookup x worldList ->
bracket (mkVty =<< userConfig) shutdown \vty ->
loop vty (pure w)
_ ->
do putStrLn "Usage: parabox <worldname>"
putStrLn ""
putStrLn "Available worlds:"
mapM_ putStrLn (Map.keys worldList)
2022-11-30 13:38:12 -08:00
loop :: Vty -> NonEmpty World -> IO ()
loop vty (world :| history) =
2022-11-30 16:44:30 -08:00
do update vty (picForImage (drawNestedWorld world))
2022-11-30 13:38:12 -08:00
ev <- nextEvent vty
case ev of
EvKey key _modifier ->
case key of
KUp -> loop vty (move world (-1,0) :| world : history)
2022-11-30 23:20:18 -08:00
KDown -> loop vty (move world (1,0) :| world : history)
2022-11-30 13:38:12 -08:00
KLeft -> loop vty (move world (0,-1) :| world : history)
2022-11-30 23:20:18 -08:00
KRight -> loop vty (move world (0,1) :| world : history)
2022-12-02 20:53:45 -08:00
KChar 'r' -> loop vty (pure (NonEmpty.last (world :| history)))
2022-11-30 13:38:12 -08:00
KChar 'z'
| Just worlds <- NonEmpty.nonEmpty history ->
loop vty worlds
KEsc -> pure ()
_ -> loop vty (world :| history)
_ -> loop vty (world :| history)
2022-12-02 18:49:26 -08:00
2022-12-02 20:56:58 -08:00
worldList :: Map.Map String World
worldList = Map.fromList
[ ("world0", world0)
, ("small", smallWorld)
, ("center8", center8)
, ("center13", center13)
, ("clone11", clone11)
, ("transfer14", transfer14)
]
2022-12-02 20:53:45 -08:00
2022-12-02 18:49:26 -08:00
smallWorld :: World
smallWorld =
World
(Map.fromList
[('a',
Box (Location 'a' 0 0)
(Original (makeWalls [
"▓▓▓▓▓▓▓▓▓",
"▓ ▓ ▓",
"▓ ▓ ▓",
"▓▓▓▓ ▓",
"▓ ▓",
"▓ ▓",
"▓ ▓",
"▓ ▓",
"▓▓▓▓▓▓▓▓▓"
]))
(withForeColor defAttr black)),
('1',
Box
(Location 'a' (-3) (-3))
(Original (makeWalls (replicate 9 (replicate 9 ' '))))
(withForeColor defAttr yellow)),
('2',
Box
(Location 'a' (-3) (-2))
(Original (makeWalls (replicate 9 (replicate 9 ' '))))
(withForeColor defAttr magenta)),
('3',
Box
(Location 'a' (-2) (-3))
(Original (makeWalls (replicate 9 (replicate 9 ' '))))
(withForeColor defAttr blue)),
('4',
Box
(Location 'a' (-2) (-2))
(Original (makeWalls (replicate 9 (replicate 9 ' '))))
(withForeColor defAttr green)),
('b',
Box
(Location '1' 0 0)
(Original (solid 9))
(withForeColor defAttr red))
]) 'b'
2022-12-02 20:53:45 -08:00
Set.empty
(Location 'b' 0 0)
2022-12-02 19:57:04 -08:00
center8 :: World
center8 =
World
(Map.fromList
[('a',
Box (Location 'a' 3 (-3))
(Original (makeWalls [
"▓▓▓▓▓▓▓▓▓",
"▓▓▓▓▓▓▓▓▓",
"▓▓ ▓▓",
"▓▓ ▓▓",
"▓ ▓▓",
"▓ ▓▓",
"▓▓▓▓ ▓▓▓▓",
"▓ ▓▓ ▓▓",
"▓▓▓▓▓▓▓▓▓"
]))
(withForeColor defAttr black)),
('1',
Box
(Location 'a' 0 0)
(Original (makeWalls [
" ▓▓",
" ▓▓▓▓▓",
" ",
" ",
" ",
" ",
" ",
" ",
" "
]))
(withForeColor defAttr green)),
('2',
Box
(Location '1' (-4) 0)
(Original (solid 9))
(withForeColor defAttr yellow)),
('b',
Box
(Location 'a' (-1) 0)
(Original (solid 9))
(withForeColor defAttr red))
]) 'b'
2022-12-02 20:53:45 -08:00
Set.empty
(Location 'a' 3 2)
2022-12-02 19:57:04 -08:00
center13 :: World
center13 =
World
(Map.fromList
[('a',
Box (Location 'a' 3 (-3))
(Original (makeWalls [
"▓▓▓▓▓▓▓▓▓",
"▓ ▓",
"▓ ▓",
"▓ ▓",
"▓ ▓",
"▓ ▓▓▓ ▓▓",
"▓ ▓ ▓ ▓▓",
"▓ ▓▓ ▓",
"▓▓▓▓▓▓▓▓▓"
]))
(withForeColor defAttr cyan)),
('1',
Box
(Location 'a' (-1) 1)
(Original (makeWalls [
" ",
" ▓▓▓▓▓▓▓ ",
" ▓▓▓▓▓▓▓ ",
" ▓▓▓▓▓▓▓ ",
" ▓▓▓▓▓▓▓ ",
" ▓▓▓▓▓▓▓ ",
" ▓▓▓▓▓▓▓ ",
" ▓▓▓▓▓▓▓ ",
" "
]))
(withForeColor defAttr green)),
('2',
Box
(Location 'a' (-1) (-1))
(Original (solid 9))
(withForeColor defAttr yellow)),
('b',
Box
(Location 'a' (-3) 0)
(Original (solid 9))
(withForeColor defAttr red))
]) 'b'
2022-12-02 20:53:45 -08:00
Set.empty
(Location 'a' 2 0)
2022-12-02 19:57:04 -08:00
clone11 :: World
clone11 =
World
(Map.fromList
[('a',
Box (Location 'a' (-2) 2)
(Original (makeWalls [
"▓▓▓▓▓▓▓▓▓",
"▓ ▓ ▓",
"▓ ▓ ▓",
"▓ ▓ ▓",
"",
"▓ ▓ ▓",
"▓ ▓ ▓",
"▓▓▓ ▓▓▓",
"▓▓▓▓▓▓▓▓▓"
]))
(withForeColor defAttr green)),
('A',
Box
(Location 'a' 0 2)
(Link 'a')
(withForeColor defAttr green)),
('b',
Box
(Location 'a' 0 (-2))
(Original (solid 9))
(withForeColor defAttr red))
2022-12-02 20:53:45 -08:00
])
'b'
(Set.fromList [Location 'a' (-1) (-3), Location 'a' (-2) (-3)])
(Location 'a' (-3) (-3))
transfer14 :: World
transfer14 =
World
(Map.fromList
[('a',
Box (Location 'a' 1 1)
(Original (makeWalls [
" ",
" ",
" ",
" ",
"",
" ",
" ",
" ",
" "
]))
(withForeColor defAttr cyan)),
('g',
Box
(Location 'a' (-1) (-1))
(Original (makeWalls [
" ▓▓▓ ",
" ▓ ▓ ",
" ",
"",
"▓▓ ▓ ▓▓",
"",
" ",
" ",
""
]))
(withForeColor defAttr green)),
('x',
Box
(Location 'g' 3 (-3))
(Original (makeWalls [
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" "
]))
(withForeColor defAttr magenta)),
('b',
Box
(Location 'a' 1 (-1))
(Original (solid 9))
(withForeColor defAttr red))
])
'b'
(Set.fromList [Location 'g' (-2) 0])
(Location 'g' (-3) 0)