#10 #18 Fix parsing

This commit is contained in:
Tibo De Peuter 2022-12-22 22:05:25 +01:00
parent 5cc96cbdba
commit f3bce99120
18 changed files with 289 additions and 103 deletions

View file

@ -9,7 +9,7 @@ import RPGEngine.Config ( bgColor, winDimensions, winOffsets )
import RPGEngine.Render ( initWindow, render )
import RPGEngine.Input ( handleAllInput )
import RPGEngine.Input.Playing ( checkPlaying, spawnPlayer )
import RPGEngine.Data (Game (..), State (..), Layout, Level (..), Physical (..))
import RPGEngine.Data (Game (..), State (..), Layout, Level (..), Physical (..), Entity(..), Direction(..), Player(..))
import RPGEngine.Data.Default (defaultLevel, defaultPlayer)
import Graphics.Gloss ( play )
@ -27,22 +27,15 @@ playRPGEngine title fps = do
-- TODO revert this
-- Initialize the game
initGame :: Game
-- initGame = Game {
-- state = Menu{ base = StateBase{
-- renderer = renderMenu,
-- inputHandler = handleInputMenu
-- }}
-- }
initGame = Game{
state = initState
}
where initState = Playing{
levels = [defaultLevel, otherLevel],
count = 0,
level = defaultLevel,
player = spawnPlayer defaultLevel defaultPlayer,
restart = initState
}
initGame = Game { state = Menu }
-- initGame = Game{ state = initState }
-- where initState = Playing{
-- levels = [defaultLevel, otherLevel],
-- count = 0,
-- level = defaultLevel,
-- player = spawnPlayer defaultLevel defaultPlayer,
-- restart = initState
-- }
-- TODO remove this
otherLayout :: Layout
@ -50,6 +43,8 @@ otherLayout = [
[Blocked, Blocked, Blocked],
[Blocked, Entrance, Blocked],
[Blocked, Walkable, Blocked],
[Blocked, Walkable, Blocked],
[Blocked, Walkable, Blocked],
[Blocked, Exit, Blocked],
[Blocked, Blocked, Blocked]
]
@ -69,12 +64,30 @@ otherLevel = Level {
(1, 2, Walkable),
(2, 2, Blocked),
(0, 3, Blocked),
(1, 3, Exit),
(1, 3, Walkable),
(2, 3, Blocked),
(0, 4, Blocked),
(1, 4, Blocked),
(2, 4, Blocked)
(1, 4, Walkable),
(2, 4, Blocked),
(0, 5, Blocked),
(1, 5, Exit),
(2, 5, Blocked),
(0, 6, Blocked),
(1, 6, Blocked),
(2, 6, Blocked)
],
items = [],
entities = []
entities = [
Entity{
entityId = "door",
entityX = 1,
entityY = 3,
entityName = "Epic door",
entityDescription = "epic description",
entityActions = [],
entityValue = Nothing,
entityHp = Nothing,
direction = North
}
]
}

View file

@ -12,7 +12,7 @@ import RPGEngine.Render.Core ( Renderer )
-- A game is the base data container.
data Game = Game {
state :: State
}
} deriving (Eq, Show)
------------------------------- State --------------------------------
@ -33,6 +33,7 @@ data State = Menu
| Win
-- Lost a level
| Lose { restart :: State }
deriving (Eq, Show)
------------------------------- Level --------------------------------

View file

@ -64,9 +64,30 @@ defaultLevel = Level {
defaultPlayer :: Player
defaultPlayer = Player {
playerHp = Prelude.Nothing, -- Compares to infinity
inventory = [],
position = (0, 0)
-- playerHp = Prelude.Nothing, -- Compares to infinity
playerHp = Just 50,
inventory = [ Item{
itemId = "key",
itemX = 0,
itemY = 0,
itemName = "Epic key",
itemDescription = "MyKey",
itemActions = [],
itemValue = Nothing,
useTimes = Nothing
}, Item{
itemId = "dagger",
itemX = 0,
itemY = 0,
itemName = "My dagger",
itemDescription = "dagger",
itemActions = [],
itemValue = Nothing,
useTimes = Nothing
}],
position = (0, 0),
showInventory = False,
showHp = True
}
defaultSelector :: ListSelector

View file

@ -20,7 +20,7 @@ type InputHandler a = Event -> (a -> a)
data ListSelector = ListSelector {
selection :: Int,
selected :: Bool
}
} deriving (Eq, Show)
------------------------------ Exported ------------------------------

View file

@ -2,6 +2,7 @@ module RPGEngine.Input.Playing
( handleInputPlaying
, checkPlaying
, spawnPlayer
, putCoords
) where
import RPGEngine.Input.Core (InputHandler, handle, handleKey, composeInputHandlers)
@ -32,6 +33,8 @@ handleInputPlaying = composeInputHandlers [
handleKey (Char 's') Down $ movePlayer South,
handleKey (Char 'a') Down $ movePlayer West,
handleKey (Char 'r') Down restartGame,
handleKey (Char 'i') Down $ toggleInventoryShown True,
handleKey (Char 'i') Up $ toggleInventoryShown False
]
@ -58,13 +61,15 @@ pauseGame g@Game{ state = playing@Playing{} } = pausedGame
where pausedGame = g{ state = Paused playing }
pauseGame g = g
restartGame :: Game -> Game
restartGame g@Game{ state = playing@Playing{ restart = restarted } } = g{ state = restarted }
-- Go to next level if there is a next level, otherwise, initialize win state.
goToNextLevel :: State -> State
goToNextLevel s@Playing{ levels = levels, level = current, count = count, player = player } = nextState
where -- Either the next level or winState
nextState | (count + 1) < length levels = nextLevelState
where nextState | (count + 1) < length levels = nextLevelState
| otherwise = Win
nextLevelState = s{ level = nextLevel, count = count + 1, player = movedPlayer }
nextLevelState = s{ level = nextLevel, count = count + 1, player = movedPlayer, restart = nextLevelState }
nextLevel = levels !! (count + 1)
movedPlayer = spawnPlayer nextLevel player
goToNextLevel s = s

View file

@ -6,13 +6,11 @@ import RPGEngine.Data ( Game )
import RPGEngine.Parse.StructureToGame ( structureToGame )
import GHC.IO (unsafePerformIO)
import Text.Parsec.String (parseFromFile)
import RPGEngine.Parse.TextToStructure (structure)
import RPGEngine.Parse.TextToStructure ( gameFile )
------------------------------ Exported ------------------------------
parse :: FilePath -> Game
parse filename = structureToGame struct
where (Right struct) = unsafePerformIO io
io = parseFromFile structure filename
tempParse = parseFromFile
io = parseFromFile gameFile filename

View file

@ -10,26 +10,25 @@ import RPGEngine.Data
entityActions, entityValue, entityHp, direction),
Item(itemId, itemX, itemY, itemName, itemDescription, itemValue,
itemActions, useTimes),
Level(layout, items, entities),
Level(layout, items, entities, index),
Game (..), State (..) )
import RPGEngine.Parse.TextToStructure
( Value(Infinite, Action, Layout, String, Direction, Integer),
Key(Tag, ConditionList),
Structure(..) )
import RPGEngine.Data.Default (defaultPlayer, defaultLevel, defaultItem, defaultEntity)
import RPGEngine.Input.Playing (putCoords, spawnPlayer)
------------------------------ Exported ------------------------------
structureToGame :: Structure -> Game
-- structureToGame [Entry(Tag "player") playerBlock, Entry(Tag "levels") levelsBlock] = game
structureToGame (Entry (Tag "player") playerBlock) = game
where game = Game{ state = newState }
newState = Playing{ levels = newLevels, level = currentLevel, player = newPlayer, restart = newState }
-- newLevels = structureToLevels levelsBlock
-- currentLevel = head newLevels
newLevels = [defaultLevel]
currentLevel = defaultLevel
newPlayer = structureToPlayer playerBlock
structureToGame :: [Structure] -> Game
structureToGame [Entry (Tag "player") playerBlock, Entry (Tag "levels") levelsBlock] = game
where game = Game newState
newState = Playing newLevels 0 currentLevel newPlayer newState
newLevels = structureToLevels levelsBlock
currentLevel = head newLevels
newPlayer = spawnPlayer currentLevel $ structureToPlayer playerBlock
structureToGame _ = Game Menu
------------------------------- Player -------------------------------
@ -60,7 +59,9 @@ structureToLevels (Block struct) = structureToLevel <$> struct
structureToLevels _ = [defaultLevel]
structureToLevel :: Structure -> Level
structureToLevel (Block entries) = structureToLevel' entries defaultLevel
structureToLevel (Block entries) = indexIsSet
where indexIsSet = level{ index = putCoords level }
level = structureToLevel' entries defaultLevel
structureToLevel _ = defaultLevel
structureToLevel' :: [Structure] -> Level -> Level

View file

@ -18,9 +18,13 @@ import Text.Parsec
notFollowedBy,
sepBy,
many,
try )
try, spaces, endOfLine )
import qualified Text.Parsec as P ( string )
import Text.Parsec.String ( Parser )
import Text.Parsec.Combinator (lookAhead)
gameFile :: Parser [Structure]
gameFile = try $ do many1 $ ignoreWS structure
-------------------------- StructureElement --------------------------
@ -111,7 +115,7 @@ data Value = String String
----------------------------------------------------------------------
value :: Parser Value
value = choice [layout, string, integer, infinite, action, direction]
value = choice [layout, string, integer, infinite, direction, action]
string :: Parser Value
string = try $ String <$> between (char '\"') (char '\"') reading
@ -149,7 +153,7 @@ direction = try $ do
ignoreWS $ P.string "left",
ignoreWS $ P.string "right"
]
notFollowedBy alphaNum
-- lookAhead $ char ','
return $ Direction $ make value
where make "up" = North
make "right" = East
@ -160,15 +164,12 @@ direction = try $ do
layout :: Parser Value
layout = try $ do
open <- ignoreWS $ oneOf openingBrackets
ignoreWS $ char '|'
list <- ignoreWS $ ignoreWS strip `sepBy` ignoreWS (char '|')
let closing = getMatchingClosingBracket open
ignoreWS $ char closing
return $ Layout list
value <- many1 strip <* ignoreWS (char closing)
return $ Layout value
strip :: Parser Strip
strip = try $ do
physical `sepBy` char ' '
strip = try $ do ignoreWS (char '|') *> ignoreWS (physical `sepBy` char ' ')
physical :: Parser Physical
physical = try $ do