mirror of
https://github.com/swarm-game/swarm.git
synced 2024-09-11 14:46:33 +03:00
beekeeping scenario (#1599)
Builds upon #1579 Requires player to constuct beehives to attract bees and make honey, which is then brewed as mead. ## Demo scripts/play.sh -i scenarios/Challenges/Ranching/beekeeping.yaml --autoplay ![image](https://github.com/swarm-game/swarm/assets/261693/f8c5c898-d865-4fe7-954d-c9e5b5f9a5c8) Map: ![map](https://github.com/swarm-game/swarm/assets/261693/9c288edb-e71f-4a59-bd32-e1ecfdb1b60e) ## References Mead hall inspiration: https://cartographyassets.com/assets/13507/the-mead-hall-of-the-clan-ulfgar-50-x-50/ ![Mead-Hal-v1-No-Light-or-Shadow-with-grid-copy-scaled](https://github.com/swarm-game/swarm/assets/261693/a2d276f1-a522-499e-9a4b-7ce1df754107)
This commit is contained in:
parent
44c2e607b3
commit
e03251cc0b
@ -638,7 +638,14 @@
|
||||
attr: blue
|
||||
char: 'B'
|
||||
description:
|
||||
- Locate and analyze structures placed in the world.
|
||||
- This enables the `structure` and `floorplan` commands to
|
||||
locate and analyze structures placed in the world.
|
||||
- |
|
||||
`structure : text -> int -> cmd (unit + (int * (int * int)))`
|
||||
- Gets the x, y coordinates of the southwest corner of a constructed structure, by name and index.
|
||||
- |
|
||||
`floorplan : text -> cmd (int * int)`
|
||||
- Gets the dimensions of a structure template.
|
||||
properties: [portable]
|
||||
capabilities: [structure]
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
beekeeping.yaml
|
||||
capture.yaml
|
||||
powerset.yaml
|
||||
gated-paddock.yaml
|
||||
|
298
data/scenarios/Challenges/Ranching/_beekeeping/queenbee.sw
Normal file
298
data/scenarios/Challenges/Ranching/_beekeeping/queenbee.sw
Normal file
@ -0,0 +1,298 @@
|
||||
// Spawns worker bees when structures are detected
|
||||
|
||||
def doN = \n. \f. if (n > 0) {f; doN (n - 1) f} {}; end;
|
||||
def mod : int -> int -> int = \a. \b. a - (a/b)*b end;
|
||||
def abs = \n. if (n < 0) {-n} {n} end;
|
||||
def min = \x. \y. if (x < y) {x} {y} end;
|
||||
|
||||
def elif = \t. \then. \else. {if t then else} end
|
||||
def else = \t. t end
|
||||
|
||||
def sumTuples = \t1. \t2.
|
||||
(fst t1 + fst t2, snd t1 + snd t2);
|
||||
end;
|
||||
|
||||
def mapTuple = \f. \t.
|
||||
(f $ fst t, f $ snd t)
|
||||
end;
|
||||
|
||||
def negateTuple = \t.
|
||||
mapTuple (\x. -x) t;
|
||||
end;
|
||||
|
||||
def subtractTuple = \t1. \t2.
|
||||
sumTuples t1 $ negateTuple t2;
|
||||
end;
|
||||
|
||||
// Deprecated
|
||||
def moveTuple = \tup.
|
||||
let x = fst tup in
|
||||
let y = snd tup in
|
||||
turn $ if (x > 0) {east} {west};
|
||||
doN (abs x) move;
|
||||
|
||||
turn $ if (y > 0) {north} {south};
|
||||
doN (abs y) move;
|
||||
end;
|
||||
|
||||
def randomDir =
|
||||
r <- random 4;
|
||||
return $ if (r == 1) {north}
|
||||
$ elif (r == 2) {west}
|
||||
$ elif (r == 3) {south}
|
||||
$ else {east};
|
||||
end;
|
||||
|
||||
def moveHorizontal = \maxDirect. \dist.
|
||||
turn $ if (dist > 0) {east} {west};
|
||||
doN (min maxDirect $ abs dist) move;
|
||||
end;
|
||||
|
||||
def moveVertical = \maxDirect. \dist.
|
||||
turn $ if (dist > 0) {north} {south};
|
||||
doN (min maxDirect $ abs dist) move;
|
||||
end;
|
||||
|
||||
def randomStep =
|
||||
randDir <- randomDir;
|
||||
turn randDir;
|
||||
move;
|
||||
end;
|
||||
|
||||
def moveToward = \maxDirect. \goal.
|
||||
|
||||
currLocOrig <- whereami;
|
||||
if (currLocOrig == goal) {} {
|
||||
|
||||
// Include some random motion
|
||||
randomStep;
|
||||
|
||||
currLoc <- whereami;
|
||||
let delta = subtractTuple goal currLoc in
|
||||
let x = fst delta in
|
||||
let y = snd delta in
|
||||
|
||||
moveHorizontal maxDirect x;
|
||||
moveVertical maxDirect y;
|
||||
|
||||
moveToward maxDirect goal;
|
||||
}
|
||||
end;
|
||||
|
||||
def watchForHoneycombRemoval = \dist.
|
||||
if (dist > 0) {
|
||||
move;
|
||||
honeycombHere <- ishere "honeycomb";
|
||||
if honeycombHere {
|
||||
watch down;
|
||||
} {};
|
||||
|
||||
watchForHoneycombRemoval $ dist - 1;
|
||||
} {};
|
||||
end;
|
||||
|
||||
/**
|
||||
Tries to find an open cell to deposit
|
||||
the honeycomb. Gives up when distance
|
||||
threshold exceeded.
|
||||
*/
|
||||
def depositHoneycomb = \dist.
|
||||
if (dist < 5) {
|
||||
emptyHere <- isempty;
|
||||
if emptyHere {
|
||||
place "honeycomb";
|
||||
} {
|
||||
move;
|
||||
depositHoneycomb $ dist + 1;
|
||||
};
|
||||
} {
|
||||
turn back;
|
||||
watchForHoneycombRemoval dist;
|
||||
|
||||
// Hibernate
|
||||
wait 2000;
|
||||
|
||||
// Alternative method to get rid of honeycomb
|
||||
make "buzz";
|
||||
};
|
||||
end;
|
||||
|
||||
def goToHive = \hiveLoc.
|
||||
let depositLoc = (fst hiveLoc - 1, snd hiveLoc) in
|
||||
moveToward 2 depositLoc;
|
||||
turn north;
|
||||
depositHoneycomb 0;
|
||||
end;
|
||||
|
||||
/**
|
||||
Harvests an item when reached
|
||||
*/
|
||||
def takeStepTowardItem = \item.
|
||||
// NOTE: Max radius is hard-coded to 256
|
||||
// (see maxSniffRange in Syntax.hs)
|
||||
direction <- chirp item;
|
||||
if (direction == down) {
|
||||
// Need a try block in case
|
||||
// another bee gets here first
|
||||
try {
|
||||
harvest;
|
||||
return ();
|
||||
} {};
|
||||
} {
|
||||
// Include some random motion
|
||||
r <- random 4;
|
||||
if (r == 0) {
|
||||
randomStep;
|
||||
} {
|
||||
turn direction;
|
||||
move;
|
||||
};
|
||||
|
||||
takeStepTowardItem item;
|
||||
}
|
||||
end;
|
||||
|
||||
/**
|
||||
Searches through the existing instances of
|
||||
a given structure template, starting at a supplied
|
||||
index.
|
||||
Either returns the (potentially new) index of the structure
|
||||
(in the case that more had been built since the last check),
|
||||
or unit. Re-using the newly found index amortizes the "search"
|
||||
within the structure list over many ticks to constant time
|
||||
rather than linear time.
|
||||
*/
|
||||
def findStructureNewIndex = \remainingCount. \structureLoc. \lastIdx.
|
||||
if (remainingCount > 0) {
|
||||
foundStructure <- structure "beehive" lastIdx;
|
||||
case foundStructure (\_. return $ inL ()) (\fs.
|
||||
if (structureLoc == snd fs) {
|
||||
return $ inR lastIdx;
|
||||
} {
|
||||
findStructureNewIndex (remainingCount - 1) structureLoc $ lastIdx + 1;
|
||||
}
|
||||
);
|
||||
} {
|
||||
return $ inL ();
|
||||
}
|
||||
end;
|
||||
|
||||
def workerProgram = \hiveIdx. \structureLoc.
|
||||
eitherFoundStructure <- structure "beehive" hiveIdx;
|
||||
case eitherFoundStructure return (\fs.
|
||||
let hasSameStructure = structureLoc == snd fs in
|
||||
if hasSameStructure {
|
||||
try {make "honeycomb";} {};
|
||||
hasHoneycomb <- has "honeycomb";
|
||||
if hasHoneycomb {
|
||||
goToHive structureLoc;
|
||||
} {
|
||||
takeStepTowardItem "wildflower";
|
||||
return ();
|
||||
};
|
||||
workerProgram hiveIdx structureLoc;
|
||||
} {
|
||||
eitherNewIdx <- findStructureNewIndex (fst fs) structureLoc hiveIdx;
|
||||
case eitherNewIdx
|
||||
(\_. selfdestruct)
|
||||
(\newIdx. workerProgram newIdx structureLoc);
|
||||
}
|
||||
);
|
||||
end;
|
||||
|
||||
def mkBeeName = \structureLoc.
|
||||
"bee" ++ format structureLoc;
|
||||
end;
|
||||
|
||||
def workerProgramInit = \beename. \hiveIdx. \structureLoc.
|
||||
setname beename;
|
||||
appear "B";
|
||||
workerProgram hiveIdx structureLoc;
|
||||
end;
|
||||
|
||||
def createWorkerForStructure = \structureIdx. \fs.
|
||||
// Build worker bee, assign ID, location
|
||||
create "wax gland";
|
||||
create "proboscis";
|
||||
|
||||
create "ADT calculator";
|
||||
create "beaglepuss";
|
||||
create "bitcoin";
|
||||
create "branch predictor";
|
||||
create "comparator";
|
||||
create "compass";
|
||||
create "detonator";
|
||||
create "dictionary";
|
||||
create "fast grabber";
|
||||
create "GPS receiver";
|
||||
create "harvester";
|
||||
create "hourglass";
|
||||
create "lambda";
|
||||
create "net";
|
||||
create "rolex";
|
||||
create "scanner";
|
||||
create "strange loop";
|
||||
create "solar panel";
|
||||
create "treads";
|
||||
create "workbench";
|
||||
|
||||
teleport self $ snd fs;
|
||||
let beename = mkBeeName (snd fs) in
|
||||
build {
|
||||
require 1 "wax gland";
|
||||
workerProgramInit beename structureIdx $ snd fs;
|
||||
};
|
||||
return ();
|
||||
end;
|
||||
|
||||
def associateAllHives = \remainingCount. \idx.
|
||||
if (remainingCount > 0) {
|
||||
|
||||
foundStructure <- structure "beehive" idx;
|
||||
case foundStructure return (\fs.
|
||||
let beename = mkBeeName (snd fs) in
|
||||
try {
|
||||
// Fails if the robot does not exist
|
||||
robotnamed beename;
|
||||
return ();
|
||||
} {
|
||||
createWorkerForStructure idx fs;
|
||||
|
||||
// Give the child robot time to register its new
|
||||
// name so that we don't end up spawning multiple
|
||||
// bees for the same location
|
||||
wait 1;
|
||||
};
|
||||
|
||||
associateAllHives (remainingCount - 1) (idx + 1);
|
||||
);
|
||||
} {}
|
||||
end;
|
||||
|
||||
/**
|
||||
Each tick, iterates through all hives,
|
||||
and makes sure a "bee" robot is associated with
|
||||
their location.
|
||||
If a structure exists without such an association,
|
||||
creates a bee named after the location.
|
||||
*/
|
||||
def observeHives =
|
||||
|
||||
// This invocation is just to get the total structure count.
|
||||
// We will invoke it again once per iteration of 'associateAllHives'.
|
||||
foundStructure <- structure "beehive" 0;
|
||||
case foundStructure return (\fs.
|
||||
associateAllHives (fst fs) 0;
|
||||
);
|
||||
|
||||
// Wait at least 1 tick so that we do not spin infinitely until
|
||||
// we saturate our computation quota for the tick.
|
||||
wait 1;
|
||||
observeHives;
|
||||
end;
|
||||
|
||||
def go =
|
||||
instant $ observeHives;
|
||||
end;
|
||||
|
||||
go;
|
362
data/scenarios/Challenges/Ranching/_beekeeping/solution.sw
Normal file
362
data/scenarios/Challenges/Ranching/_beekeeping/solution.sw
Normal file
@ -0,0 +1,362 @@
|
||||
def doN = \n. \f. if (n > 0) {f; doN (n - 1) f} {}; end;
|
||||
|
||||
def intersperse = \n. \f2. \f1. if (n > 0) {
|
||||
f1;
|
||||
if (n > 1) {
|
||||
f2;
|
||||
} {};
|
||||
intersperse (n - 1) f2 f1;
|
||||
} {};
|
||||
end;
|
||||
|
||||
def abs = \n. if (n < 0) {-n} {n} end;
|
||||
|
||||
def sumTuples = \t1. \t2.
|
||||
(fst t1 + fst t2, snd t1 + snd t2);
|
||||
end;
|
||||
|
||||
def mapTuple = \f. \t.
|
||||
(f $ fst t, f $ snd t)
|
||||
end;
|
||||
|
||||
def negateTuple = \t.
|
||||
mapTuple (\x. -x) t;
|
||||
end;
|
||||
|
||||
def subtractTuple = \t1. \t2.
|
||||
sumTuples t1 $ negateTuple t2;
|
||||
end;
|
||||
|
||||
def moveTuple = \tup.
|
||||
let x = fst tup in
|
||||
let y = snd tup in
|
||||
turn $ if (x > 0) {east} {west};
|
||||
doN (abs x) move;
|
||||
|
||||
turn $ if (y > 0) {north} {south};
|
||||
doN (abs y) move;
|
||||
end;
|
||||
|
||||
def nextRow = \d.
|
||||
intersperse 2 move $ turn d;
|
||||
end;
|
||||
|
||||
def harvestTrees =
|
||||
turn back;
|
||||
doN 14 move;
|
||||
turn left;
|
||||
|
||||
intersperse 4 (nextRow left;) (
|
||||
intersperse 15 move harvest;
|
||||
nextRow right;
|
||||
intersperse 15 move harvest;
|
||||
);
|
||||
end;
|
||||
|
||||
def slatRow =
|
||||
let item = "honey frame" in
|
||||
intersperse 3 move $ place item;
|
||||
end;
|
||||
|
||||
def buildHive =
|
||||
// Make 16 boards
|
||||
doN 4 (make "log"; make "board");
|
||||
|
||||
// Make 9 honey frames
|
||||
doN 3 $ make "log";
|
||||
doN 3 (make "board"; make "honey frame");
|
||||
|
||||
doN 4 (intersperse 4 move (place "board"); turn right; move;);
|
||||
turn right;
|
||||
move;
|
||||
|
||||
slatRow;
|
||||
nextRow left;
|
||||
slatRow;
|
||||
nextRow right;
|
||||
slatRow;
|
||||
end;
|
||||
|
||||
def moveToNextHive =
|
||||
doN 7 move;
|
||||
end;
|
||||
|
||||
/* Makes 8 staves */
|
||||
def makeStaveBatch =
|
||||
// 1 per tree
|
||||
make "log";
|
||||
|
||||
// 4 per log
|
||||
make "board";
|
||||
|
||||
// 2 per board
|
||||
doN 4 $ make "stave";
|
||||
end;
|
||||
|
||||
def buildCasks = \caskCount.
|
||||
// 40 staves
|
||||
doN 5 makeStaveBatch;
|
||||
doN 4 $ make "steel hoop";
|
||||
doN caskCount $ make "cask";
|
||||
end;
|
||||
|
||||
/*
|
||||
Moves forward until finding objective
|
||||
item, stops when a gap is reached.
|
||||
*/
|
||||
def collectContiguous = \maxdist. \item. \hadFound. \dist.
|
||||
if (dist <= maxdist) {
|
||||
honeycombHere <- ishere item;
|
||||
if honeycombHere {
|
||||
grab;
|
||||
move;
|
||||
collectContiguous maxdist item true $ dist + 1;
|
||||
} {
|
||||
if hadFound {
|
||||
return dist;
|
||||
} {
|
||||
move;
|
||||
collectContiguous maxdist item false $ dist + 1;
|
||||
}
|
||||
}
|
||||
} {
|
||||
return dist;
|
||||
}
|
||||
end;
|
||||
|
||||
def collectHoneycomb =
|
||||
distTravelled <- collectContiguous 10 "honeycomb" false 0;
|
||||
turn back;
|
||||
doN distTravelled move;
|
||||
end;
|
||||
|
||||
def collectAllHoneycombs = \targetCount.
|
||||
|
||||
honeycombHere <- ishere "honeycomb";
|
||||
if honeycombHere {} {
|
||||
watch down;
|
||||
wait 2000;
|
||||
};
|
||||
|
||||
intersperse 4 (turn left; doN 9 move; turn left;) collectHoneycomb;
|
||||
|
||||
currentCount <- count "honeycomb";
|
||||
if (currentCount < targetCount) {
|
||||
turn right;
|
||||
doN 27 move;
|
||||
turn right;
|
||||
|
||||
collectAllHoneycombs targetCount;
|
||||
} {
|
||||
return currentCount;
|
||||
};
|
||||
end;
|
||||
|
||||
def moveUntilBlocked =
|
||||
thing <- scan forward;
|
||||
let isBlocked = case thing (\_. false) (\x. x == "lakewater") in
|
||||
if isBlocked {} {
|
||||
move;
|
||||
moveUntilBlocked;
|
||||
}
|
||||
end;
|
||||
|
||||
def getLakewater = \caskCount.
|
||||
turn right;
|
||||
doN 2 move;
|
||||
turn left;
|
||||
doN 5 move;
|
||||
turn right;
|
||||
moveUntilBlocked;
|
||||
|
||||
doN caskCount $ use "siphon" forward;
|
||||
end;
|
||||
|
||||
def pickRock =
|
||||
isRock <- ishere "rock";
|
||||
if isRock {
|
||||
grab;
|
||||
return ();
|
||||
} {};
|
||||
end;
|
||||
|
||||
def collectRocks =
|
||||
doN 22 move;
|
||||
turn right;
|
||||
doN 59 move;
|
||||
turn left;
|
||||
|
||||
doN 7 (
|
||||
intersperse 15 move pickRock;
|
||||
nextRow right;
|
||||
intersperse 15 move pickRock;
|
||||
nextRow left;
|
||||
);
|
||||
end;
|
||||
|
||||
def makeTables =
|
||||
|
||||
doN 18 (make "log"; make "board";);
|
||||
doN 36 $ make "table";
|
||||
|
||||
turn right;
|
||||
move;
|
||||
turn right;
|
||||
doN 2 move;
|
||||
doN 9 (swap "table"; move);
|
||||
doN 8 move;
|
||||
doN 9 (swap "table"; move);
|
||||
turn left;
|
||||
doN 2 move;
|
||||
turn left;
|
||||
move;
|
||||
doN 9 (swap "table"; move);
|
||||
doN 8 move;
|
||||
doN 9 (swap "table"; move);
|
||||
end;
|
||||
|
||||
def buildTavern =
|
||||
|
||||
// x16 per rock =
|
||||
doN 12 $ make "stone tile";
|
||||
|
||||
doN 2 (
|
||||
intersperse 30 move $ place "stone tile";
|
||||
nextRow left;
|
||||
intersperse 30 move $ place "stone tile";
|
||||
nextRow right;
|
||||
);
|
||||
intersperse 30 move $ place "stone tile";
|
||||
|
||||
makeTables;
|
||||
|
||||
// hearth
|
||||
nextRow right;
|
||||
doN 12 move;
|
||||
intersperse 4 move (make "hearth"; swap "hearth");
|
||||
turn right;
|
||||
doN 6 move;
|
||||
turn right;
|
||||
intersperse 4 move (make "archway"; place "archway");
|
||||
nextRow right;
|
||||
intersperse 4 move (make "archway"; place "archway");
|
||||
move;
|
||||
|
||||
// Make enough logs for 70 wall pieces
|
||||
doN 35 (make "log"; make "wall");
|
||||
|
||||
intersperse 14 move (place "wall");
|
||||
turn left;
|
||||
doN 6 (move; place "wall");
|
||||
turn left;
|
||||
doN 31 (move; place "wall";);
|
||||
turn left;
|
||||
doN 6 (move; place "wall");
|
||||
turn left;
|
||||
doN 13 (move; place "wall");
|
||||
end;
|
||||
|
||||
def combCollectionLoop = \targetCount.
|
||||
|
||||
currentCount <- count "honeycomb";
|
||||
if (currentCount < targetCount) {
|
||||
watch down;
|
||||
wait 2000;
|
||||
collectHoneycomb;
|
||||
turn back;
|
||||
combCollectionLoop targetCount;
|
||||
} {}
|
||||
end;
|
||||
|
||||
def buildRobot = \targetCount. \meetingLoc.
|
||||
|
||||
// Unpack the "botkit"
|
||||
make "solar panel";
|
||||
|
||||
build {
|
||||
require 8 "tree";
|
||||
buildHive;
|
||||
|
||||
// Move to northwest corner
|
||||
turn back;
|
||||
doN 3 move;
|
||||
turn left;
|
||||
doN 4 move;
|
||||
turn left;
|
||||
|
||||
combCollectionLoop targetCount;
|
||||
|
||||
currLoc <- whereami;
|
||||
let delta = subtractTuple meetingLoc currLoc in
|
||||
moveTuple delta;
|
||||
|
||||
// Assume that the base has already arrived
|
||||
// at the rendezvous point
|
||||
honeycombCount <- count "honeycomb";
|
||||
doN honeycombCount $ give parent "honeycomb";
|
||||
};
|
||||
end;
|
||||
|
||||
def placeHives = \targetCount. \meetingLoc.
|
||||
buildRobot targetCount meetingLoc;
|
||||
doN 38 move;
|
||||
buildRobot targetCount meetingLoc;
|
||||
doN 56 move;
|
||||
turn right;
|
||||
doN 15 move;
|
||||
turn left;
|
||||
buildRobot targetCount meetingLoc;
|
||||
doN 2 move;
|
||||
turn right;
|
||||
doN 26 move;
|
||||
turn left;
|
||||
buildRobot targetCount meetingLoc;
|
||||
end;
|
||||
|
||||
def acceptHoneyDeliveries =
|
||||
currentCount <- count "honeycomb";
|
||||
if (currentCount < 60) {
|
||||
wait 32;
|
||||
acceptHoneyDeliveries;
|
||||
} {
|
||||
// Use the "honey extractor"
|
||||
doN currentCount $ make "honey";
|
||||
}
|
||||
end;
|
||||
|
||||
def go =
|
||||
harvestTrees;
|
||||
turn east;
|
||||
doN 19 move;
|
||||
|
||||
let meetingLoc = (0, -12) in
|
||||
placeHives 15 meetingLoc;
|
||||
|
||||
turn right;
|
||||
|
||||
buildCasks 2;
|
||||
getLakewater 2;
|
||||
|
||||
turn right;
|
||||
|
||||
collectRocks;
|
||||
|
||||
doN 7 move;
|
||||
turn left;
|
||||
doN 80 move;
|
||||
buildTavern;
|
||||
|
||||
nextRow right;
|
||||
|
||||
currLoc <- whereami;
|
||||
let delta = subtractTuple meetingLoc currLoc in
|
||||
moveTuple delta;
|
||||
|
||||
acceptHoneyDeliveries;
|
||||
doN 4 salvage;
|
||||
|
||||
doN 2 $ make "mead";
|
||||
|
||||
end;
|
||||
|
||||
go;
|
453
data/scenarios/Challenges/Ranching/beekeeping.yaml
Normal file
453
data/scenarios/Challenges/Ranching/beekeeping.yaml
Normal file
@ -0,0 +1,453 @@
|
||||
version: 1
|
||||
name: Beekeeping
|
||||
author: Karl Ostmo
|
||||
description: |
|
||||
Bootstrap an organic *bee*verage industry.
|
||||
creative: false
|
||||
seed: 2
|
||||
attrs:
|
||||
- name: bee
|
||||
fg: '#ffff00'
|
||||
bg: '#000000'
|
||||
- name: water_cask
|
||||
fg: '#4488ff'
|
||||
bg: '#8B4513'
|
||||
- name: mybase
|
||||
fg: '#e0c0e0'
|
||||
- name: iceblue
|
||||
fg: '#ddddff'
|
||||
objectives:
|
||||
- teaser: Apiarist
|
||||
goal:
|
||||
- |
|
||||
Build a `beehive`{=structure}.
|
||||
- |
|
||||
This will attract bees, which will gather
|
||||
`nectar`{=entity} from nearby `wildflower`{=entity}s.
|
||||
- |
|
||||
Do not crowd hives; provide at least one cell margin
|
||||
between them.
|
||||
- |
|
||||
Given that `wildflower`{=entity}s cannot be relocated,
|
||||
judicious placement is essential for efficient
|
||||
`honeycomb`{=entity} production.
|
||||
condition: |
|
||||
foundStructure <- structure "beehive" 0;
|
||||
return $ case foundStructure (\_. false) (\_. true);
|
||||
- teaser: Collect honeycomb
|
||||
goal:
|
||||
- |
|
||||
Collect `honeycomb`{=entity} from the `beehive`{=structure}s.
|
||||
- |
|
||||
After gathering a certain amount of nectar, a bee will return
|
||||
to its hive and place honeycomb alongside it.
|
||||
A finite amount of honeycomb may be accumulated before the
|
||||
bee becomes dormant.
|
||||
condition: |
|
||||
as base {
|
||||
has "honeycomb"
|
||||
}
|
||||
- teaser: Cooper
|
||||
goal:
|
||||
- |
|
||||
Make a `cask`{=entity}.
|
||||
- |
|
||||
Use local timber and your on-hand supply of iron material.
|
||||
- |
|
||||
You may `use "siphon" forward` when positioned in front of
|
||||
a lake to fill a `cask`{=entity} with `lakewater`{=entity}.
|
||||
condition: |
|
||||
as base {
|
||||
has "cask"
|
||||
}
|
||||
- teaser: Brewmeister
|
||||
goal:
|
||||
- |
|
||||
Ferment 2 barrels of `mead`{=entity}.
|
||||
condition: |
|
||||
as base {
|
||||
meadCount <- count "mead";
|
||||
return $ meadCount >= 2;
|
||||
}
|
||||
- teaser: Tavern keeper
|
||||
optional: true
|
||||
goal:
|
||||
- |
|
||||
Construct a `mead hall`{=structure}.
|
||||
condition: |
|
||||
foundStructure <- structure "mead hall" 0;
|
||||
return $ case foundStructure (\_. false) (\_. true);
|
||||
robots:
|
||||
- name: base
|
||||
display:
|
||||
attr: mybase
|
||||
dir: [1, 0]
|
||||
devices:
|
||||
- 3D printer
|
||||
- blueprint
|
||||
- branch predictor
|
||||
- ADT calculator
|
||||
- clock
|
||||
- comparator
|
||||
- compass
|
||||
- counter
|
||||
- dictionary
|
||||
- fast grabber
|
||||
- GPS receiver
|
||||
- harvester
|
||||
- hearing aid
|
||||
- honey extractor
|
||||
- keyboard
|
||||
- lambda
|
||||
- logger
|
||||
- net
|
||||
- rolex
|
||||
- scanner
|
||||
- siphon
|
||||
- strange loop
|
||||
- toolkit
|
||||
- treads
|
||||
- welder
|
||||
- workbench
|
||||
inventory:
|
||||
- [20, iron plate]
|
||||
- [4, botkit]
|
||||
- name: queenbee
|
||||
dir: [1, 0]
|
||||
system: true
|
||||
display:
|
||||
invisible: true
|
||||
char: 'Q'
|
||||
attr: bee
|
||||
program:
|
||||
run "scenarios/Challenges/Ranching/_beekeeping/queenbee.sw"
|
||||
solution: |
|
||||
run "scenarios/Challenges/Ranching/_beekeeping/solution.sw"
|
||||
structures:
|
||||
- name: beehive
|
||||
recognize: true
|
||||
structure:
|
||||
palette:
|
||||
'-': [dirt, honey frame]
|
||||
'b': [dirt, board]
|
||||
map: |
|
||||
bbbbb
|
||||
b---b
|
||||
b---b
|
||||
b---b
|
||||
bbbbb
|
||||
- name: mead hall
|
||||
recognize: true
|
||||
structure:
|
||||
palette:
|
||||
'w': [dirt, wall]
|
||||
't': [dirt, table]
|
||||
'h': [dirt, hearth]
|
||||
'a': [dirt, archway]
|
||||
'.': [stone, stone tile]
|
||||
mask: 'x'
|
||||
map: |
|
||||
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
|
||||
w.............hhhh.............w
|
||||
w..ttttttttt........ttttttttt..w
|
||||
w..............................w
|
||||
w..ttttttttt........ttttttttt..w
|
||||
w..............................w
|
||||
wwwwwwwwwwwwwwaaaawwwwwwwwwwwwww
|
||||
xxxxxxxxxxxxxxaaaaxxxxxxxxxxxxxx
|
||||
entities:
|
||||
- name: wildflower
|
||||
display:
|
||||
attr: flower
|
||||
char: '*'
|
||||
description:
|
||||
- A delicate flower that grows wild in local meadows.
|
||||
Produces `nectar`{=entity} when `harvest`ed.
|
||||
properties: [known, growable]
|
||||
yields: nectar
|
||||
growth: [80, 120]
|
||||
- name: botkit
|
||||
display:
|
||||
attr: device
|
||||
char: 'k'
|
||||
description:
|
||||
- All the essentials to equip your own "worker bee"
|
||||
properties: [known, portable]
|
||||
- name: reed
|
||||
display:
|
||||
attr: plant
|
||||
char: 'r'
|
||||
description:
|
||||
- Reeds, grow near water
|
||||
properties: [known, portable, growable]
|
||||
- name: honeycomb
|
||||
display:
|
||||
char: 'x'
|
||||
attr: gold
|
||||
description:
|
||||
- Product of bees that have consumed nectar
|
||||
properties: [known, portable]
|
||||
- name: proboscis
|
||||
display:
|
||||
char: 'p'
|
||||
attr: device
|
||||
description:
|
||||
- Senses direction to nectar-producing flowers
|
||||
properties: [known, portable]
|
||||
capabilities: [detectdirection, structure]
|
||||
- name: honey
|
||||
display:
|
||||
char: 'h'
|
||||
attr: gold
|
||||
description:
|
||||
- Pure liquid honey
|
||||
properties: [known, portable]
|
||||
- name: mead
|
||||
display:
|
||||
char: 'm'
|
||||
description:
|
||||
- Honey-based alcoholic beverage
|
||||
properties: [known, portable]
|
||||
- name: honey extractor
|
||||
display:
|
||||
char: 'e'
|
||||
attr: device
|
||||
description:
|
||||
- Device for extracting honey from the comb
|
||||
properties: [known, portable]
|
||||
- name: buzz
|
||||
display:
|
||||
char: 'z'
|
||||
description:
|
||||
- Result of discarding surplus honeycomb
|
||||
properties: [known, portable]
|
||||
- name: wax gland
|
||||
display:
|
||||
char: 'g'
|
||||
description:
|
||||
- Required to make honeycomb
|
||||
properties: [known]
|
||||
- name: nectar
|
||||
display:
|
||||
char: 'n'
|
||||
attr: gold
|
||||
description:
|
||||
- Obtained from wildflowers
|
||||
properties: [known, portable]
|
||||
- name: honey frame
|
||||
display:
|
||||
char: '-'
|
||||
attr: iceblue
|
||||
description:
|
||||
- Internal component of a beehive
|
||||
properties: [known, portable]
|
||||
- name: stave
|
||||
display:
|
||||
char: 'l'
|
||||
attr: wood
|
||||
description:
|
||||
- Wooden plank comprising the sides of a cask
|
||||
properties: [known, portable]
|
||||
- name: cask
|
||||
display:
|
||||
char: 'c'
|
||||
attr: wood
|
||||
description:
|
||||
- Wooden barrel for liquids
|
||||
properties: [known, portable]
|
||||
- name: water cask
|
||||
display:
|
||||
char: 'c'
|
||||
attr: water_cask
|
||||
description:
|
||||
- Water-filled cask
|
||||
properties: [known, portable]
|
||||
- name: lakewater
|
||||
display:
|
||||
attr: water
|
||||
char: ' '
|
||||
description:
|
||||
- Potable water from a lake
|
||||
properties: [known, infinite, liquid]
|
||||
- name: siphon
|
||||
display:
|
||||
char: 's'
|
||||
attr: device
|
||||
description:
|
||||
- Used to fill a cask with water
|
||||
properties: [known, portable]
|
||||
- name: steel hoop
|
||||
display:
|
||||
char: 'o'
|
||||
attr: iron
|
||||
description:
|
||||
- Binds staves into a cask
|
||||
properties: [known, portable]
|
||||
- name: wall
|
||||
display:
|
||||
char: 'w'
|
||||
attr: wood
|
||||
description:
|
||||
- Outer walls of the building
|
||||
properties: [known, unwalkable]
|
||||
- name: table
|
||||
display:
|
||||
char: 't'
|
||||
attr: wood
|
||||
description:
|
||||
- A segment of banquet table
|
||||
properties: [known, portable]
|
||||
- name: hearth
|
||||
display:
|
||||
char: 'h'
|
||||
attr: rock
|
||||
description:
|
||||
- Encloses a fire to warm the hall
|
||||
properties: [known, unwalkable]
|
||||
- name: archway
|
||||
display:
|
||||
char: 'a'
|
||||
attr: rock
|
||||
description:
|
||||
- Grand entrance
|
||||
properties: [known, portable]
|
||||
- name: stone tile
|
||||
display:
|
||||
char: '.'
|
||||
attr: rock
|
||||
description:
|
||||
- Refined flooring
|
||||
properties: [known, portable]
|
||||
recipes:
|
||||
- in:
|
||||
- [1, botkit]
|
||||
out:
|
||||
- [1, branch predictor]
|
||||
- [1, ADT calculator]
|
||||
- [1, blueprint]
|
||||
- [1, clock]
|
||||
- [1, comparator]
|
||||
- [1, compass]
|
||||
- [1, counter]
|
||||
- [1, dictionary]
|
||||
- [1, grabber]
|
||||
- [1, GPS receiver]
|
||||
- [1, harvester]
|
||||
- [1, lambda]
|
||||
- [1, logger]
|
||||
- [1, net]
|
||||
- [1, rolex]
|
||||
- [1, scanner]
|
||||
- [1, solar panel]
|
||||
- [1, strange loop]
|
||||
- [1, treads]
|
||||
- [1, welder]
|
||||
- [1, workbench]
|
||||
- in:
|
||||
- [1, board]
|
||||
out:
|
||||
- [3, honey frame]
|
||||
- in:
|
||||
- [1, rock]
|
||||
out:
|
||||
- [16, stone tile]
|
||||
- in:
|
||||
- [2, rock]
|
||||
out:
|
||||
- [1, hearth]
|
||||
- in:
|
||||
- [4, rock]
|
||||
out:
|
||||
- [1, archway]
|
||||
- in:
|
||||
- [2, board]
|
||||
out:
|
||||
- [1, table]
|
||||
- in:
|
||||
- [1, rock]
|
||||
- [1, log]
|
||||
out:
|
||||
- [2, wall]
|
||||
- in:
|
||||
- [1, board]
|
||||
out:
|
||||
- [2, stave]
|
||||
- in:
|
||||
- [2, iron plate]
|
||||
out:
|
||||
- [1, steel hoop]
|
||||
- in:
|
||||
- [20, stave]
|
||||
- [2, steel hoop]
|
||||
out:
|
||||
- [1, cask]
|
||||
- in:
|
||||
- [1, cask]
|
||||
- [1, lakewater]
|
||||
out:
|
||||
- [1, water cask]
|
||||
- [1, lakewater]
|
||||
required:
|
||||
- [1, siphon]
|
||||
- in:
|
||||
- [16, nectar]
|
||||
out:
|
||||
- [1, honeycomb]
|
||||
required:
|
||||
- [1, wax gland]
|
||||
- in:
|
||||
- [1, water cask]
|
||||
- [30, honey]
|
||||
out:
|
||||
- [1, mead]
|
||||
- in:
|
||||
- [1, honeycomb]
|
||||
out:
|
||||
- [1, honey]
|
||||
required:
|
||||
- [1, honey extractor]
|
||||
- in:
|
||||
- [1, honeycomb]
|
||||
out:
|
||||
- [1, buzz]
|
||||
required:
|
||||
- [1, wax gland]
|
||||
known: [tree, rock, board]
|
||||
world:
|
||||
dsl: |
|
||||
let
|
||||
flowerNoise = perlin seed 1 0.15 0.0,
|
||||
stoneNoise = perlin (seed + 1) 1 0.05 0.0,
|
||||
lakeNoise = perlin seed 1 0.02 0.0,
|
||||
forestNoise = perlin seed 2 0.04 1.0,
|
||||
|
||||
flowers = flowerNoise > 0.65,
|
||||
rubble = stoneNoise > 0.8,
|
||||
rock = stoneNoise > 0.9,
|
||||
outerShore = -0.55 <= lakeNoise && lakeNoise < -0.5,
|
||||
innerShore = lakeNoise < -0.55,
|
||||
lakes = lakeNoise < -0.6,
|
||||
trees = forestNoise > 0.8
|
||||
in
|
||||
overlay
|
||||
[ {grass}
|
||||
, mask (flowers && (x + y) % 3 == 0) {wildflower}
|
||||
, mask (rubble && (x + y) % 2 == 0) {rock}
|
||||
, mask rock {rock}
|
||||
, mask trees {tree}
|
||||
, mask (outerShore && (x + y) % 2 == 0) {reed}
|
||||
, mask innerShore {reed}
|
||||
, mask lakes {lakewater}
|
||||
]
|
||||
upperleft: [0, 0]
|
||||
offset: false
|
||||
palette:
|
||||
'B': [grass, erase, base]
|
||||
'Q': [grass, erase, queenbee]
|
||||
'.': [grass, erase]
|
||||
map: |
|
||||
Q....
|
||||
.....
|
||||
..B..
|
||||
.....
|
||||
.....
|
@ -241,6 +241,7 @@ testScenarioSolutions rs ui =
|
||||
, testGroup
|
||||
"Ranching"
|
||||
[ testSolution Default "Challenges/Ranching/capture"
|
||||
, testSolution (Sec 60) "Challenges/Ranching/beekeeping"
|
||||
, testSolution (Sec 10) "Challenges/Ranching/powerset"
|
||||
, testSolution (Sec 30) "Challenges/Ranching/gated-paddock"
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user