Skip to content

Commit

Permalink
subworlds (#1353)
Browse files Browse the repository at this point in the history
Closes #144.

This builds upon portals support (#1356)

# Demo

    scripts/play.sh --scenario data/scenarios/Testing/144-subworlds/subworld-mapped-robots.yaml --autoplay --speed 2

[![asciicast](https://asciinema.org/a/vC13dW8M1S8t2b1J4XkW80U1q.svg)](https://asciinema.org/a/vC13dW8M1S8t2b1J4XkW80U1q)

# Future work
* Augment portal definitions with an optional "relative orientation" attribute, that can turn the player around when passing through the portal (#1379)
* Specify whether portal performs instant transportation or whether `move down` is required (#1368)
  • Loading branch information
kostmo authored Jul 22, 2023
1 parent d1a8242 commit f9c2263
Show file tree
Hide file tree
Showing 48 changed files with 1,824 additions and 315 deletions.
8 changes: 5 additions & 3 deletions bench/Benchmark.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import Control.Monad.Except (runExceptT)
import Control.Monad.State (evalStateT, execStateT)
import Criterion.Main (Benchmark, bench, bgroup, defaultConfig, defaultMainWith, whnfAppIO)
import Criterion.Types (Config (timeLimit))
import Data.Map qualified as M
import Swarm.Game.CESK (emptyStore, initMachine)
import Swarm.Game.Display (defaultRobotDisplay)
import Swarm.Game.Location
import Swarm.Game.Robot (TRobot, mkRobot)
import Swarm.Game.State (GameState, addTRobot, creativeMode, world)
import Swarm.Game.State (GameState, addTRobot, creativeMode, multiWorld)
import Swarm.Game.Step (gameTick)
import Swarm.Game.Terrain (TerrainType (DirtT))
import Swarm.Game.Universe (Cosmic (..), SubworldName (DefaultRootSubworld))
import Swarm.Game.World (WorldFun (..), newWorld)
import Swarm.Language.Context qualified as Context
import Swarm.Language.Pipeline (ProcessedTerm)
Expand Down Expand Up @@ -73,7 +75,7 @@ circlerProgram =

-- | Initializes a robot with program prog at location loc facing north.
initRobot :: ProcessedTerm -> Location -> TRobot
initRobot prog loc = mkRobot () Nothing "" [] (Just loc) north defaultRobotDisplay (initMachine prog Context.empty emptyStore) [] [] False False 0
initRobot prog loc = mkRobot () Nothing "" [] (Just $ Cosmic DefaultRootSubworld loc) north defaultRobotDisplay (initMachine prog Context.empty emptyStore) [] [] False False 0

-- | Creates a GameState with numRobot copies of robot on a blank map, aligned
-- in a row starting at (0,0) and spreading east.
Expand All @@ -85,7 +87,7 @@ mkGameState robotMaker numRobots = do
(mapM addTRobot robots)
( (initAppState ^. gameState)
& creativeMode .~ True
& world .~ newWorld (WF $ const (fromEnum DirtT, Nothing))
& multiWorld .~ M.singleton DefaultRootSubworld (newWorld (WF $ const (fromEnum DirtT, Nothing)))
)

-- | Runs numGameTicks ticks of the game.
Expand Down
1 change: 1 addition & 0 deletions data/scenarios/Testing/00-ORDER.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@
1295-density-command.yaml
1138-structures
1356-portals
144-subworlds
5 changes: 5 additions & 0 deletions data/scenarios/Testing/144-subworlds/00-ORDER.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
basic-subworld.yaml
subworld-shared-structures.yaml
subworld-mapped-robots.yaml
subworld-located-robots.yaml
spatial-consistency-enforcement.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

def doN = \n. \f. if (n > 0) {f; doN (n - 1) f} {}; end;

doN 8 move;
f <- grab;
doN 7 move;
place f;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

def doN = \n. \f. if (n > 0) {f; doN (n - 1) f} {}; end;

doN 3 move;
f <- grab;

doN 5 move;
r <- meet;
case r return $ \j. give j f;

Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

def getRobotNumber = \n.
r <- robotnumbered n;
if (r == self) {
return n;
} {getRobotNumber $ n + 1};
end;

def amLowestRecursive = \targetName. \idx.
r <- robotnumbered idx;
thisName <- as r {whoami};
if (thisName == targetName) {
return $ r == self;
} {amLowestRecursive targetName $ idx + 1};
end;

/**
Iterates through robots by increasing index.
If we encounter a robot, fetched by index,
with the same name as me, but I am not that robot,
then we return false.
*/
def amFirstOfMyName =
myName <- whoami;
amLowestRecursive myName 0;
end;

def waitToGiveThing = \thing.
r <- meet;
case r (\_. wait 1; waitToGiveThing thing) $ \b. give b thing;
end;

def waitToGive =
let thing = "bitcoin" in
create thing;
waitToGiveThing thing;
end;

def waitToReceive =
noop;
end;

def go =
myNumber <- getRobotNumber 0;
log $ "My number: " ++ format myNumber;
amFirst <- amFirstOfMyName;
log $ "Am first with this name? " ++ format amFirst;

if amFirst {waitToReceive} {waitToGive};
end;

go;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

def doN = \n. \f. if (n > 0) {f; doN (n - 1) f} {}; end;

doN 16 move;

r <- meet;
case r return $ \j. give j "bitcoin";

108 changes: 108 additions & 0 deletions data/scenarios/Testing/144-subworlds/basic-subworld.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
version: 1
name: Subworlds demo
description: |
Surface and underground with portals.
objectives:
- goal:
- |
`place` the "flower" on the white cell.
condition: |
j <- robotnamed "judge";
as j {ishere "flower"}
solution: |
run "scenarios/Testing/144-subworlds/_basic-subworld/solution.sw"
attrs:
- name: portal_in
fg: "#ff9a00"
bg: "#ff5d00"
- name: portal_out
fg: "#00a2ff"
bg: "#0065ff"
entities:
- name: telepad entrance
display:
attr: portal_in
char: "o"
description:
- Portal entrance
properties: [known]
- name: telepad exit
display:
attr: portal_out
char: "o"
description:
- Portal exit
properties: [known]
robots:
- name: base
dir: [1, 0]
devices:
- ADT calculator
- branch predictor
- comparator
- compass
- dictionary
- GPS receiver
- grabber
- lambda
- lodestone
- logger
- strange loop
- treads
- name: judge
dir: [1, 0]
system: true
display:
char: 'J'
invisible: true
known: [flower, boulder]
subworlds:
- name: underground
default: [blank]
palette:
'.': [dirt]
'f': [dirt, flower]
'b': [dirt, boulder]
'p':
cell: [dirt, telepad exit]
waypoint:
name: portal_out2
'P':
cell: [dirt, telepad entrance]
waypoint:
name: portal_in2
portals:
- entrance: portal_in2
exitInfo:
exit: portal_out1
subworldName: root
upperleft: [-1, 1]
map: |
b..b..b..b
.p..f...P.
b..b..b..b
world:
name: root
default: [blank]
palette:
'.': [grass]
'B': [grass, null, base]
't': [ice, null, judge]
'p':
cell: [grass, telepad exit]
waypoint:
name: portal_out1
'P':
cell: [grass, telepad entrance]
waypoint:
name: portal_in1
upperleft: [-1, 1]
portals:
- entrance: portal_in1
exitInfo:
exit: portal_out2
subworldName: underground
map: |
..........
.p.Bt...P.
..........
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
version: 1
name: Subworld spatial consistency enforcement
description: |
Portals annotated to enforce spatial consistency between subworlds
attrs:
- name: portal_in
fg: "#ff9a00"
bg: "#ff5d00"
- name: portal_out
fg: "#00a2ff"
bg: "#0065ff"
entities:
- name: telepad entrance
display:
attr: portal_in
char: "o"
description:
- Portal entrance
properties: [known]
- name: telepad exit
display:
attr: portal_out
char: "o"
description:
- Portal exit
properties: [known]
robots:
- name: base
dir: [1, 0]
devices:
- ADT calculator
- branch predictor
- comparator
- compass
- dictionary
- GPS receiver
- grabber
- lambda
- lodestone
- logger
- strange loop
- treads
known: [boulder]
subworlds:
- name: underground
default: [blank]
palette:
'.': [dirt]
'b': [dirt, boulder]
'p':
cell: [dirt, telepad exit]
waypoint:
name: portal_out2
'P':
cell: [dirt, telepad entrance]
waypoint:
name: portal_in2
portals:
- entrance: portal_in2
exitInfo:
exit: portal_out1
subworldName: root
consistent: true
upperleft: [-1, 1]
map: |
b..b..b..b
.P......p.
b..b..b..b
world:
name: root
default: [blank]
palette:
'.': [grass]
'B': [grass, null, base]
'p':
cell: [grass, telepad exit]
waypoint:
name: portal_out1
'P':
cell: [grass, telepad entrance]
waypoint:
name: portal_in1
upperleft: [-1, 1]
portals:
- entrance: portal_in1
exitInfo:
exit: portal_out2
subworldName: underground
consistent: true
map: |
..........
.p.B....P.
..........
Loading

0 comments on commit f9c2263

Please sign in to comment.