-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
1,485 additions
and
411 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
{-# LANGUAGE DerivingVia #-} | ||
{-# LANGUAGE OverloadedStrings #-} | ||
|
||
module Swarm.Game.Scenario.Cells where | ||
|
||
import Control.Lens hiding (from, (.=), (<.>)) | ||
import Control.Monad (when) | ||
import Control.Monad.Extra (mapMaybeM) | ||
import Data.Maybe (catMaybes, listToMaybe) | ||
import Data.Text (Text) | ||
import Data.Vector qualified as V | ||
import Data.Yaml as Y | ||
import Swarm.Game.Entity | ||
import Swarm.Game.Scenario.EntityFacade | ||
import Swarm.Game.Scenario.ScenarioUtil | ||
import Swarm.Game.Terrain | ||
import Swarm.Util.Yaml | ||
|
||
------------------------------------------------------------ | ||
-- World cells | ||
------------------------------------------------------------ | ||
|
||
data ProtoCell e = Cell | ||
{ cellTerrain :: TerrainType | ||
, cellEntity :: Maybe e | ||
, cellRobots :: [IndexedTRobot] | ||
} | ||
deriving (Eq, Show) | ||
|
||
-- | A single cell in a world map, which contains a terrain value, | ||
-- and optionally an entity and robot. | ||
type Cell = ProtoCell Entity | ||
|
||
-- Note: This is used only for the purpose of WorldPalette | ||
instance ToJSON Cell where | ||
toJSON x = | ||
toJSON $ | ||
catMaybes | ||
[ Just $ toJSON $ getTerrainWord $ cellTerrain x | ||
, toJSON . (^. entityName) <$> cellEntity x | ||
, listToMaybe [] | ||
] | ||
|
||
-- | Parse a tuple such as @[grass, rock, base]@ into a 'Cell'. The | ||
-- entity and robot, if present, are immediately looked up and | ||
-- converted into 'Entity' and 'TRobot' values. If they are not | ||
-- found, a parse error results. | ||
instance FromJSONE (EntityMap, RobotMap) Cell where | ||
parseJSONE = withArrayE "tuple" $ \v -> do | ||
let tup = V.toList v | ||
when (null tup) $ fail "palette entry must nonzero length (terrain, optional entity and then robots if any)" | ||
|
||
terr <- liftE $ parseJSON (head tup) | ||
|
||
ent <- case tup ^? ix 1 of | ||
Nothing -> return Nothing | ||
Just e -> do | ||
meName <- liftE $ parseJSON @(Maybe Text) e | ||
traverse (localE fst . getEntity) meName | ||
|
||
let name2rob r = do | ||
mrName <- liftE $ parseJSON @(Maybe Text) r | ||
traverse (localE snd . getRobot) mrName | ||
|
||
robs <- mapMaybeM name2rob (drop 2 tup) | ||
|
||
return $ Cell terr ent robs | ||
|
||
------------------------------------------------------------ | ||
-- World editor | ||
------------------------------------------------------------ | ||
|
||
type CellPaintDisplay = ProtoCell EntityFacadeData | ||
|
||
-- Note: This instance is used only for the purpose of WorldPalette | ||
instance ToJSON CellPaintDisplay where | ||
toJSON x = | ||
toJSON $ | ||
catMaybes | ||
[ Just $ toJSON $ getTerrainWord $ cellTerrain x | ||
, toJSON <$> cellEntity x | ||
, listToMaybe [] | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{-# LANGUAGE DerivingVia #-} | ||
|
||
module Swarm.Game.Scenario.EntityFacade where | ||
|
||
import Control.Lens hiding (from, (.=), (<.>)) | ||
import Data.Text (Text) | ||
import Data.Yaml as Y | ||
import Swarm.Game.Display (Display) | ||
import Swarm.Game.Entity qualified as E | ||
|
||
type EntityName = Text | ||
|
||
data EntityFacadeData = EntityFacadeData EntityName Display | ||
deriving (Eq) | ||
|
||
-- Note: This instance is used only for the purpose of WorldPalette | ||
instance ToJSON EntityFacadeData where | ||
toJSON (EntityFacadeData eName _display) = toJSON eName | ||
|
||
mkPaint :: E.Entity -> EntityFacadeData | ||
mkPaint e = | ||
EntityFacadeData | ||
(e ^. E.entityName) | ||
(e ^. E.entityDisplay) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
{-# LANGUAGE DerivingVia #-} | ||
{-# LANGUAGE OverloadedStrings #-} | ||
|
||
module Swarm.Game.Scenario.ScenarioUtil where | ||
|
||
import Data.Map (Map) | ||
import Data.Map qualified as M | ||
import Data.Text (Text) | ||
import Swarm.Game.Entity | ||
import Swarm.Game.Robot (TRobot) | ||
import Swarm.Util.Yaml | ||
|
||
------------------------------------------------------------ | ||
-- Robot map | ||
------------------------------------------------------------ | ||
|
||
-- | A robot template paired with its definition's index within | ||
-- the Scenario file | ||
type IndexedTRobot = (Int, TRobot) | ||
|
||
-- | A map from names to robots, used to look up robots in scenario | ||
-- descriptions. | ||
type RobotMap = Map Text IndexedTRobot | ||
|
||
------------------------------------------------------------ | ||
-- Lookup utilities | ||
------------------------------------------------------------ | ||
|
||
-- | Look up a thing by name, throwing a parse error if it is not | ||
-- found. | ||
getThing :: String -> (Text -> m -> Maybe a) -> Text -> ParserE m a | ||
getThing thing lkup name = do | ||
m <- getE | ||
case lkup name m of | ||
Nothing -> fail $ "Unknown " <> thing <> " name: " ++ show name | ||
Just a -> return a | ||
|
||
-- | Look up an entity by name in an 'EntityMap', throwing a parse | ||
-- error if it is not found. | ||
getEntity :: Text -> ParserE EntityMap Entity | ||
getEntity = getThing "entity" lookupEntityName | ||
|
||
-- | Look up a robot by name in a 'RobotMap', throwing a parse error | ||
-- if it is not found. | ||
getRobot :: Text -> ParserE RobotMap IndexedTRobot | ||
getRobot = getThing "robot" M.lookup |
Oops, something went wrong.