To run this script:
- Download this gist as a zip file and extract
- Execute the following:
stack run -- --scenario /path/to/goslings.yaml
def hasItemInDirection = \item. \direction. | |
x <- scan direction; | |
case x | |
(\_. return false) | |
(\y. return $ y == item); | |
end; | |
def elifM = \p.\t.\e. {p2 <- p; if p2 t e} end; | |
def getItemDirection : text -> cmd (unit + dir) = \item. | |
isFwd <- hasItemInDirection item forward; | |
if (isFwd) { | |
return $ inr forward; | |
} $ elifM (hasItemInDirection item left) { | |
return $ inr left; | |
} $ elifM (hasItemInDirection item right) { | |
return $ inr right; | |
} $ elifM (hasItemInDirection item back) { | |
return $ inr back; | |
} { | |
return $ inl (); | |
} | |
end; | |
def elif = \p.\t.\e. {if p t e} end; | |
def rememberDirection = \isStranded. \itemToFollow. \prevDir. | |
let goDirection= \d. | |
turn d; | |
f <- grab; | |
move; | |
place f; | |
rememberDirection false itemToFollow $ inl (); | |
in | |
maybeFeather <- getItemDirection itemToFollow; | |
case maybeFeather | |
(\_. case prevDir | |
(\_. | |
if isStranded {} { | |
say $ "Mama! Lost track of " ++ itemToFollow; | |
return (); | |
}; | |
rememberDirection true itemToFollow $ inl (); | |
) | |
(\d. goDirection d) | |
) | |
(\d. | |
if isStranded {say "Reunited!"} {}; | |
rememberDirection false itemToFollow $ inr d; | |
); | |
end; | |
def determineItemToFollow : cmd (unit + text) = | |
x <- scan down; | |
case x (\_. return $ inl ();) (\n. | |
return $ if (n == "feather1") { | |
inr "feather0" | |
} $ elif (n == "feather2") { | |
inr "feather1" | |
} $ elif (n == "feather3") { | |
inr "feather2" | |
} $ elif (n == "feather4") { | |
inr "feather3" | |
} { | |
inl (); | |
} | |
); | |
end; | |
itemToFollow <- determineItemToFollow; | |
case itemToFollow | |
(\_. say "Staying here.") | |
(\item. rememberDirection false item $ inl ()) |
version: 1 | |
name: Goose caravan | |
author: Karl Ostmo | |
description: | | |
Geese | |
creative: false | |
robots: | |
- name: goose | |
description: | |
- mother goose | |
display: | |
invisible: false | |
char: 'G' | |
system: true | |
devices: | |
- logger | |
dir: [0, 1] | |
program: | | |
run "scenarios/Challenges/Ranching/_goslings/mother.sw"; | |
- name: gosling | |
description: | |
- baby goose | |
display: | |
invisible: false | |
char: 'g' | |
system: true | |
dir: [0, 1] | |
program: | | |
run "scenarios/Challenges/Ranching/_goslings/gosling.sw"; | |
entities: | |
- name: feather0 | |
display: | |
char: 'f' | |
description: | |
- Scannable item carried by mother goose | |
properties: [known, portable] | |
- name: feather1 | |
display: | |
char: 'f' | |
description: | |
- Scannable item carried by first baby goose | |
properties: [known, portable] | |
- name: feather2 | |
display: | |
char: 'f' | |
description: | |
- Scannable item carried by second baby goose | |
properties: [known, portable] | |
- name: feather3 | |
display: | |
char: 'f' | |
description: | |
- Scannable item carried by third baby goose | |
properties: [known, portable] | |
- name: feather4 | |
display: | |
char: 'f' | |
description: | |
- Scannable item carried by fourth baby goose | |
properties: [known, portable] | |
known: [mountain, tree, water] | |
seed: 0 | |
world: | |
palette: | |
'.': [grass] | |
'G': [grass, feather0, goose] | |
'g': [grass, feather1, gosling] | |
'h': [grass, feather2, gosling] | |
'i': [grass, feather3, gosling] | |
'j': [grass, feather4, gosling] | |
upperleft: [0, 0] | |
map: |- | |
................. | |
................. | |
................. | |
......Gghij...... | |
................. | |
................. | |
................. |
def elif = \p.\t.\e. {if p t e} end; | |
def decideDirection = | |
let randdir : cmd dir = | |
d <- random 3; | |
return $ if (d == 0) { | |
left | |
} $ elif (d == 1) { | |
right | |
} { | |
forward | |
} | |
in | |
d <- randdir; | |
turn d; | |
end; | |
def blockedByItem = \d. | |
x <- scan d; | |
case x | |
(\_. return false) | |
(\_. return true); | |
end; | |
def moveOneStep = | |
f <- grab; | |
move; | |
place f; | |
wait 12; | |
end; | |
let forever : cmd unit -> cmd unit = \c. c ; forever c in | |
let repeat : int -> cmd unit -> cmd unit = | |
\n. \c. if (n == 0) {} {c ; repeat (n-1) c} in | |
forever ( | |
n <- random 10; | |
wait (16 + n); | |
decideDirection; | |
dist <- random 3; | |
repeat dist ( | |
blockedForward <- blockedByItem forward; | |
if (blockedForward) { | |
blockedLeft <- blockedByItem left; | |
blockedRight <- blockedByItem right; | |
if (blockedLeft && blockedRight) | |
{ | |
blockedBack <- blockedByItem back; | |
if blockedBack { | |
fail "My goose is cooked."; | |
} { | |
say "Let's go back..."; | |
turn back; | |
} | |
} | |
{}; | |
return (); | |
} { | |
moveOneStep | |
} | |
); | |
) |