Skip to content

Commit

Permalink
beekeeping
Browse files Browse the repository at this point in the history
  • Loading branch information
kostmo committed Nov 8, 2023
1 parent d63e7d8 commit ccbe027
Show file tree
Hide file tree
Showing 5 changed files with 761 additions and 0 deletions.
1 change: 1 addition & 0 deletions data/scenarios/Challenges/Ranching/00-ORDER.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
beekeeping.yaml
capture.yaml
powerset.yaml
gated-paddock.yaml
186 changes: 186 additions & 0 deletions data/scenarios/Challenges/Ranching/_beekeeping/queenbee.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
// 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 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 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 north;
watchForHoneycombRemoval dist;

// Hibernate
wait 2000;

// Alternative method to get rid of honeycomb
make "satisfaction";
};
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 goToHive = \hiveLoc.
currLoc <- whereami;
let depositLoc = (fst hiveLoc - 1, snd hiveLoc) in
let delta = subtractTuple depositLoc currLoc in
moveTuple delta;
turn south;
depositHoneycomb 0;

end;

/**
Harvests an item when reached
*/
def takeStepTowardItem = \item.
direction <- chirp item;
if (direction == down) {
// Need a try block in case
// another bee gets here first
try {
harvest;
return ();
} {};
} {
turn direction;
move;
takeStepTowardItem item;
}
end;

def workerProgram = \hiveIdx. \structureLoc.
foundStructure <- structure "beehive" hiveIdx;
let stillHasStructure = case foundStructure (\_. false) (\fs.
structureLoc == snd fs;
) in

if (stillHasStructure) {

try {make "honeycomb";} {};

hasHoneycomb <- has "honeycomb";
if hasHoneycomb {
goToHive structureLoc;
} {

takeStepTowardItem "wildflower";
return ();
};
workerProgram hiveIdx structureLoc;
} {
selfdestruct;
}
end;

def workerProgramInit = \hiveIdx. \structureLoc.
appear "B";
if (mod hiveIdx 2 == 0) {turn left;} {};
workerProgram hiveIdx structureLoc;
end;

def observeHives = \lastHiveCount.

foundStructure <- structure "beehive" lastHiveCount;
newHiveCount <- case foundStructure (\_. return lastHiveCount) (\fs.
let newHiveCount = fst fs in

if (newHiveCount > lastHiveCount) {
// Build worker bee, assign ID, location
create "wax gland";
create "proboscis";

create "solar panel";
create "treads";
create "detonator";
create "harvester";
create "fast grabber";
create "workbench";
create "GPS receiver";
create "scanner";
create "rolex";
create "beaglepuss";
create "branch predictor";
create "comparator";
create "compass";
create "ADT calculator";
create "dictionary";
create "lambda";
create "strange loop";
create "hourglass";
create "net";

teleport self $ snd fs;
build {
require 1 "wax gland";
workerProgramInit lastHiveCount $ snd fs;
};
return ();
} {};

return newHiveCount;
);

wait 1;
observeHives newHiveCount;
end;

def go =
observeHives 0;
end;

go;
199 changes: 199 additions & 0 deletions data/scenarios/Challenges/Ranching/_beekeeping/solution.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@

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 nextRow = \d.
turn d;
move;
turn d;
end;

def harvestTrees =
turn back;
doN 16 move;
turn left;
doN 5 move;

doN 20 (harvest; move;);
nextRow right;
doN 20 (harvest; move;);
end;

def slatRow =
make "slat";
intersperse 3 move (place "slat");
end;

def buildHive =
// Make 16 boards
doN 4 (make "log"; make "board");

// Make 9 slats
doN 3 $ make "log";
doN 3 (make "board"; make "slat");

doN 4 (intersperse 4 move (place "board"); turn right; move;);
turn right;
move;

slatRow;
nextRow left;
slatRow;
nextRow right;
slatRow;

end;

def moveToNextHive =
turn left;
doN 7 move;
turn left;
doN 3 move;
turn right;
end;

def buildTankSide = \item.
doN 3 (move; place item;);
move;
turn right;
move;
place item;
turn left;
move;
turn right;
end;

def buildBreweryTank =
turn right;
doN 3 (place "copper pipe"; move;);
move;
turn right;
doN 3 move;
turn right;
move;
doN 4 $ buildTankSide "copper wall";
end;

def buildBrewery =
buildBreweryTank;
turn back;
doN 5 move;
turn left;
doN 3 move;

buildBreweryTank;
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.

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 loopHoneycombCollection =

turn west;
doN 20 move;
turn right;
doN 6 move;

finalCount <- collectAllHoneycombs 60;

doN finalCount $ make "honey";
let caskCount = finalCount / 30 in
buildCasks caskCount;
doN caskCount $ make "mead";

end;

def go =
harvestTrees;

doN 5 move;
turn right;
doN 16 move;

intersperse 4 moveToNextHive buildHive;

doN 10 move;
buildBrewery;

loopHoneycombCollection;
end;

go;
Loading

0 comments on commit ccbe027

Please sign in to comment.