Skip to content

Commit

Permalink
flower count scenario
Browse files Browse the repository at this point in the history
  • Loading branch information
byorgey committed Jan 3, 2025
1 parent b03a19d commit 9ad1c26
Show file tree
Hide file tree
Showing 4 changed files with 327 additions and 0 deletions.
1 change: 1 addition & 0 deletions data/scenarios/Challenges/00-ORDER.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ friend.yaml
pack-tetrominoes.yaml
dimsum.yaml
telephone.yaml
flower-count.yaml
Mazes
Ranching
Sokoban
Expand Down
35 changes: 35 additions & 0 deletions data/scenarios/Challenges/_flower-count/judge.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
def win =
try {
firestarter <- robotNamed "firestarter";
halt firestarter
} {};
try {
fire <- robotNamed "fire";
halt fire; wait 1;
reprogram fire { selfdestruct };
} {};
create "gold"
end

def judgeCount : Int -> Cmd Unit = \actual.
watch down;
wait 1024;
s <- scan down;
case s
(\_. return ())
(\p.
try {
let c = (read p : Int) in
if (c == actual) { win } {}
} {}
)
end

def forever = \c. c; forever c end

def judge =
numFlowers <- resonate "flower" ((-59,-19),(60,20));
forever (judgeCount numFlowers);
end;

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

def abs : Int -> Int = \n.
if (n < 0) {-n} {n}
end

// Go to the given absolute coordinates. End facing east.
def goto : Int * Int -> Cmd Unit = \dest.
cur <- whereami;
let x = fst cur in
let y = snd cur in
let dx = fst dest - x in
let dy = snd dest - y in
if (dx < 0) {turn west} {turn east};
doN (abs dx) move;
if (dy < 0) {turn south} {turn north};
doN (abs dy) move;
turn east;
end

def liftA2 : (a -> b -> c) -> Cmd a -> Cmd b -> Cmd c = \f. \ca. \cb.
a <- ca;
b <- cb;
return (f a b)
end

def add : Cmd Int -> Cmd Int -> Cmd Int = liftA2 (\x. \y. x + y) end

def countCell : Cmd Int =
s <- scan down;
return $ case s
(\_. 0)
(\t. if (t == "flower") {1} {0})
end

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

def sum : List Int -> Int = \l.
case l
(\_. 0)
(\cons. fst cons + sum (snd cons))
end

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

def countRow : Int -> Cmd Int = \w.
ns <- for (w-1) (\_. n <- countCell; move; return n);
last <- countCell;
return (sum ns + last)
end

def isEven : Int -> Bool = \n. (n / 2) * 2 == n end

def around : Dir -> Cmd Unit = \d. turn d; move; turn d end

// countFlowers (w,h) (x,y) counts the number of flowers
// in the w by h rectangle with lower-left corner at (x,y)
def countFlowers : Int * Int -> Int * Int -> Cmd Int = \size. \ll.
goto ll;
let w = fst size in
let h = snd size in
cnts <- for (h-1) (\i.
cnt <- countRow w;
if (isEven i) { around right } { around left };
return cnt
);
last <- countRow w;
return (sum cnts + last)
end

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

def countAndReport : Int * Int -> Int * Int -> Cmd Unit = \size. \ll.
cnt <- countFlowers size ll;
goto (0,0);
paper <- acquire;
let soFar = (read paper : Int) in
erase paper;
newPaper <- print (format (soFar + cnt));
place newPaper;
end

def until : Cmd Bool -> Cmd a -> Cmd Unit = \test. \body.
b <- test; if b {} {body; until test body}
end

def acquireFlower : Cmd Unit =
until (ishere "flower") move; grab; return ()
end

def go =
for 4 (\r.
for 3 (\c.
build {countAndReport (40,10) (-59 + 40*(c-1), -19 + 10*(r-1))}
)
);
print "0";
turn left; move; place "paper: 0";
wait 1024;
acquireFlower;
turn back;
goto (20,0);
res <- meet;
case res (\_. return ()) (\truelove. give truelove "flower")
end;

go;
177 changes: 177 additions & 0 deletions data/scenarios/Challenges/flower-count.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
version: 1
name: Flower Count
author: Brent Yorgey
description: |
Count the flowers quickly... or else!
creative: false
objectives:
- id: count_flowers
teaser: Count the flowers!
goal:
- |
Your evil nemesis, the sadistic supervillain Dr. Nemesis, is
at it again! They have wired up some explosives to your True
Love and lit the fuse, but promised to stop it... IF you can
count all the flowers in time!
- |
Specifically, Dr. Nemesis demands that you count the
total number of flowers in the 120x40 field bounded by walls,
`print` the number on a piece of `paper`{=entity}, and place
the paper at the origin, `(0,0)`. If the number is correct,
the countdown stops and your True Love is saved. If the
number is incorrect... nothing happens, but the fuse continues
to burn!
- |
And don't even think about trying to pick any of the flowers.
condition: |
judge <- robotNamed "judge";
as judge { has "gold" }
- id: pick_flower
hidden: true
optional: true
teaser: You just don't listen, do you
goal:
- |
I told you not to pick any flowers! Now your True Love is
dead... because of YOU!
- |
Perhaps you would like to go back in time and try again.
condition: |
f <- as base { has "flower" };
judge <- robotNamed "judge";
g <- as judge { has "gold" };
return (not g && f)
- id: out_of_time
hidden: true
optional: true
teaser: Not fast enough
goal:
- |
You were not fast enough, and now your True Love is
dead... because of YOU!
- |
Perhaps you would like to go back in time and try again.
condition: |
truelove <- robotNamed "truelove";
as truelove { b <- ishere "fuse"; return (not b) }
- id: joinpoint
hidden: true
teaser: Follow instructions!
prerequisite:
logic:
and:
- count_flowers
- not: pick_flower
- not: out_of_time
condition: |
return true
- id: win
teaser: Give a flower
prerequisite: joinpoint
goal:
- |
Congratulations! You foiled the plan of evil Dr. Nemesis and
saved your True Love! The only thing left is to give your
True Love a flower!
condition: |
truelove <- robotNamed "truelove";
as truelove { has "flower" }
solution: |
run "scenarios/Challenges/_flower-count/solution.sw"
robots:
- name: base
dir: north
devices:
- solar panel
- treads
- antenna
- comparator
- ADT calculator
- workbench
- grabber
- dictionary
- lambda
- logger
- welder
- scanner
- strange loop
- typewriter
- 3D printer
- branch predictor
- clock
- GPS receiver
- compass
inventory:
- [12, solar panel]
- [12, dictionary]
- [12, lambda]
- [12, treads]
- [12, branch predictor]
- [12, comparator]
- [12, hyperloop]
- [12, compass]
- [12, scanner]
- [12, logger]
- [12, GPS receiver]
- [12, string]
- [12, typewriter]
- [12, rubber band]
- [12, grabber]
- [12, parsley]
- [1, paper]
- name: igniter
system: true
dir: east
devices:
- logger
program: 'ignite down'
- name: judge
system: true
dir: east
devices:
- logger
program: |
run "scenarios/Challenges/_flower-count/judge.sw"
- name: truelove
system: true
display:
invisible: false
attr: red
char: ''
description: Your One True Love.
attrs:
- name: fuse
fg: '#cccccc'
bg: '#002f00'
entities:
- name: fuse
display:
attr: fuse
char: '-'
description:
- Slow-burning fuse
properties: [combustible, known, boundary]
combustion:
ignition: 20
duration: [64, 64]
delay: 63
product: ash
known: [flower, wall, ash]
world:
dsl: |
overlay
[ if (hash % 7 <= 2) then {grass, flower} else {grass}
, mask ((x == 61 || x == (-60)) && y <= 21 && y >= -20) {wall, stone}
, mask ((y == 21 || y == (-20)) && x <= 61 && x >= -60) {wall, stone}
]
upperleft: [0, 0]
offset: false
palette:
'B': [grass, null, base]
'J': [grass, erase, judge]
'.': [grass]
'-': [grass, fuse]
'L': [grass, fuse, truelove]
'I': [grass, fuse, igniter]
map: |
JB..I---------------L

0 comments on commit 9ad1c26

Please sign in to comment.