Skip to content

Commit

Permalink
Add print + erase commands, and a challenge scenario showing off …
Browse files Browse the repository at this point in the history
…`print` (#2245)

This PR is a complement/follow-up to #2224 .

- Add a new `print : Text -> Cmd Text` command which consumes a `paper` entity and produces an entity named `paper: <text>` where `<text>` is the given text to be printed on the paper
- Add an `erase : Text -> Cmd Unit` command which takes a printed-on paper entity and erases it back to a plain `paper`
- Add a challenge scenario necessitating the use of `print`

Especially eager to hear feedback from anyone who wants to try solving the new scenario!

```
./scripts/play.sh --scenario data/scenarios/Challenges/telephone.yaml
```
  • Loading branch information
byorgey authored Jan 3, 2025
1 parent 78b882d commit c3a83b1
Show file tree
Hide file tree
Showing 18 changed files with 565 additions and 6 deletions.
5 changes: 3 additions & 2 deletions data/entities.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
char: ''
description:
- A flat material made of pressed and dried wood fibers, used as a surface on which to inscribe symbols.
properties: [pickable, combustible]
properties: [pickable, combustible, printable]
combustion:
ignition: 0.5
duration: [10, 20]
Expand Down Expand Up @@ -884,8 +884,9 @@
attr: device
char: 'Д'
description:
- A typewriter is used to inscribe symbols on paper, thus reifying pure, platonic information into a physical form.
- A typewriter is used to inscribe symbols on `paper`{=entity}, thus reifying pure, platonic information into a physical form.
properties: [pickable]
capabilities: [print, erase]
- name: 3D printer
display:
attr: device
Expand Down
3 changes: 2 additions & 1 deletion data/scenarios/Challenges/00-ORDER.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ dna.yaml
friend.yaml
pack-tetrominoes.yaml
dimsum.yaml
telephone.yaml
Mazes
Ranching
Sokoban
Sliding Puzzles
Sliding Puzzles
80 changes: 80 additions & 0 deletions data/scenarios/Challenges/_telephone/judge.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
def forever:a b. {Cmd a} -> Cmd b = \c. force c; forever c end

def x : Int -> Cmd a -> Cmd Unit = \n. \c.
if (n == 0) {} {c; x (n-1) c}
end

def andC : Cmd Bool -> Cmd Bool -> Cmd Bool = \c1. \c2.
b1 <- c1;
if b1 {c2} {return false}
end

tydef List a = rec l. Unit + a * l end

def for : Int -> (Int -> Cmd a) -> Cmd (List a) = \n. \k.
if (n == 0)
{ return $ inl () }
{ x <- k (n-1);
xs <- for (n-1) k;
return (inr (x,xs))
}
end

def readRow : Cmd (List (Unit + Text)) =
r <- for 8 (\_. s <- scan down; move; return s);
turn back; x 8 move; turn right; move; turn right;
return r
end

tydef Rect = List (List (Unit + Text)) end

def readRect : Cmd Rect =
lst <- for 4 (\_. readRow);
turn right; x 4 move; turn left;
return lst
end

def checkCell : Unit + Text -> Cmd Bool = \pat.
actual <- scan down;
move;
return (actual == pat)
end

def checkRow : List (Unit + Text) -> Cmd Bool = \row.
case row
(\_. turn back; x 8 move; turn right; move; turn right; return true)
(\cons. andC (checkCell (fst cons)) (checkRow (snd cons)))
end

def checkRect : Rect -> Cmd Bool = \rect.
case rect
(\_. return true)
(\cons. andC (checkRow (fst cons)) (checkRect (snd cons)))
end

def check : Rect -> Cmd Unit = \rect.
log "check!";
origLoc <- whereami;
teleport self (53, -8);
b <- checkRect rect;
if b {create "X"} {};
teleport self origLoc; turn east;
end

def judge =
instant (
loc <- whereami;
for 4 (\y.
for 8 (\x.
surveil (fst loc + x, snd loc + y)
)
);
);
wait 1024;
instant (
rect <- readRect;
check rect;
)
end

forever {judge};
34 changes: 34 additions & 0 deletions data/scenarios/Challenges/_telephone/photocopier.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
def forever:a b. {Cmd a} -> Cmd b = \c. force c; forever c end

def X : Int -> Cmd Unit -> Cmd Unit = \n. \c.
if (n == 0) {} {c; X (n-1) c}
end

def pixel : (Int * Int) * Text -> Cmd Unit = \instr.
let loc = fst instr in
let x = fst loc in
let y = snd loc in
let ty = snd instr in
turn back; X 5 move; turn right; X 2 move;
turn west; X x move; turn north; X y move;
place ty;
turn south; X y move; turn east; X x move;
X 5 move; turn right; X 2 move; turn east
end

def followInstructions : Text -> Cmd Unit = \paper.
try {
let res = (read paper : ((Int * Int) * Text))
in pixel res
} {}
end

def copy : Cmd Unit =
watch down; wait 1024;
p <- atomic (b <- isempty; if b {return ""} {grab});
if (p == "") {} {followInstructions p}
end

def go = forever {copy} end

go;
47 changes: 47 additions & 0 deletions data/scenarios/Challenges/_telephone/shuttle.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
def ifC:a. Cmd Bool -> {Cmd a} -> {Cmd a} -> Cmd a
= \test. \then. \else.
b <- test;
if b then else
end

def while:a. Cmd Bool -> {Cmd a} -> Cmd Unit
= \test. \body.
ifC test {force body; while test body} {}
end

def forever:a b. {Cmd a} -> Cmd b = \c. force c; forever c end

def notC : Cmd Bool -> Cmd Bool = \c.
b <- c; return (not b)
end

def or : Cmd Bool -> Cmd Bool -> Cmd Bool = \c1. \c2.
ifC c1 {return true} {c2}
end

def followTrack : Cmd Unit =
move;
while (or (isHere "track") (isHere "mountain")) { move };
turn back;
end

def pickup : Cmd Text =
atomic (b <- isempty; if b {return ""} {grab});
end

def dropoff : Text -> Cmd Bool = \thing.
atomic (b <- isempty; if b {place thing} {}; return b)
end

def deliver : Text -> Cmd Unit = \thing.
move;
followTrack;
if (thing == "") {}
{
while (notC (dropoff thing)) { followTrack; followTrack }
};
end

def go = forever {followTrack; thing <- pickup; deliver thing} end

go;
77 changes: 77 additions & 0 deletions data/scenarios/Challenges/_telephone/solution.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
def x : Int -> Cmd a -> Cmd Unit = \n. \c.
if (n == 0) {} {c; x (n-1) c}
end

def ifC:a. Cmd Bool -> {Cmd a} -> {Cmd a} -> Cmd a
= \test. \then. \else.
b <- test;
if b then else
end

def while:a. Cmd Bool -> {Cmd a} -> Cmd Unit
= \test. \body.
ifC test {force body; while test body} {}
end

def for : Int -> (Int -> Cmd a) -> Cmd Unit = \n. \k.
if (n == 0) {} {k n; for (n-1) k}
end

def harvestMay =
e <- isempty;
if e {} {harvest; return ()}
end

def harvestTrees =
turn back; move; turn left; x 5 move;
turn left;
x 5 (x 10 (harvestMay; move); turn back; x 10 move; turn left; move; turn left);
turn left; x 10 move; turn right; move
end

def getWater =
turn back; x 3 move; turn left; move;
x 32 grab;
turn back; move; turn right; x 3 move
end

def getPaper =
harvestTrees;
while (has "tree") {make "log"};
x 2 (make "board"); make "boat"; equip "boat";
getWater; x 4 (make "paper")
end

def scanAt : Int -> Int -> Cmd (Unit + Text) = \h. \v.
x h move; turn right; x v move;
s <- scan down;
turn back; x v move; turn left; x h move; turn back;
return s
end

def atTerminal : Cmd a -> Cmd a = \c.
x 12 move; turn left; x 2 move;
a <- c;
turn back; x 2 move; turn right; x 12 move; turn back;
return a
end

def waitToPlace : Text -> Cmd Unit = \t.
success <- atomic (b <- isempty; if b {place t} {}; return b);
if success {} { watch down; wait 1024; waitToPlace t }
end

def go =
getPaper;
x 2 move; turn left; x 4 move;
for 8 (\h.
for 4 (\v.
res <- scanAt (h-1) (v-1);
case res
(\_. return ())
(\t. atTerminal (p <- print "paper" (format ((h-1,v-1),t)); waitToPlace p))
)
)
end

go;
Loading

0 comments on commit c3a83b1

Please sign in to comment.