Skip to content

Instantly share code, notes, and snippets.

@nns2009
Created August 15, 2022 19:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nns2009/777fee06a96bf64d3ab158b8360db6ef to your computer and use it in GitHub Desktop.
Save nns2009/777fee06a96bf64d3ab158b8360db6ef to your computer and use it in GitHub Desktop.
// ----------------------------------------------------------
// ----------------------------------------------------------
// --------------------- Farm with Code ---------------------
// ----------------------------------------------------------
// ----------------------------------------------------------
// In this game you need to code your drone(s) in JavaScript to farm for you.
// Here is a sample code to do some farming.
// Read game page for more instructions.
const anyJob = (...jobs) => drone => {
const jobObjects = jobs.map(j => j(drone));
//console.info('any', jobObjects);
return {
update() {
for (const jobObject of jobObjects) {
jobObject.update();
}
},
get finished() {
return jobObjects.some(jobObject => jobObject.finished);
}
}
}
const allJob = (...jobs) => drone => {
const jobObjects = jobs.map(j => j(drone));
return {
update() {
for (const jobObject of jobObjects) {
jobObject.update();
}
},
get finished() {
return jobObjects.every(jobObject => jobObject.finished);
}
}
}
const sequenceJob = (...jobs) => {
let jobIndex = 0;
return drone => ({
reset() { jobIndex = 0; },
update() {
//console.log('loop', jobIndex, jobs[jobIndex]);
if (jobIndex >= jobs.length)
return;
const job = jobs[jobIndex](drone);
job.update();
if (job.finished) {
jobIndex++;
}
},
get finished() { return jobIndex >= jobs.length; },
});
}
const loopJob = (...jobs) => {
let jobIndex = 0;
return drone => ({
update() {
// console.log('loop', jobIndex, jobs.length);
const job = jobs[jobIndex](drone);
job.update();
if (job.finished) {
jobIndex = (jobIndex + 1) % jobs.length;
const nextJobObject = jobs[jobIndex](drone); // Dirty hack to get to inner closure
if (nextJobObject.reset)
nextJobObject.reset();
}
},
get finished() { return false; },
});
}
const flyToJob = (tx, ty) => drone => {
if (tx.x !== undefined) {
// We passed Point instead of individual coordinates
ty = tx.y;
tx = tx.x;
}
const arriveEps = 3;
const dx = tx - drone.gps.position.x;
const dy = ty - drone.gps.position.y;
const closeEnough = dx * dx + dy * dy < arriveEps ** 2;
return {
update() {
drone.motor.force = {
x: dx * 50,
y: dy * 50,
};
},
get finished() { return closeEnough; },
}
}
const patrolJob = (...points) => loopJob(
...points.map(p => flyToJob(p.x, p.y))
);
const buyMaxJob = (itemKey) => drone => {
const complete = drone.inventory.money === 0
|| drone.inventory.totalWeight >= drone.inventory.maxWeight;
return {
update() {
if (complete)
return;
const weightLeft = drone.inventory.maxWeight - drone.inventory.totalWeight;
const item = drone.market.availableItems[itemKey];
const requestedAmound = weightLeft / item.density;
drone.market.buyUpTo(itemKey, requestedAmound);
},
get finished() { return complete; },
}
};
const buyUpToJob = (itemKey, maxAmount) => drone => {
return {
update() {
drone.market.buyUpTo(itemKey, maxAmount);
},
get finished() { return true; },
}
}
const sellMaxJob = (itemKey) => drone => {
const complete = !drone.inventory.content[itemKey]
|| drone.inventory.content[itemKey].quantity < 0.01;
return {
update() {
if (complete)
return;
drone.market.sellUpTo(itemKey, 10 ** 10);
},
get finished() { return complete; },
}
}
const intakeWaterJob = drone => {
return {
update() {
drone.pump.intake();
//console.log(drone.waterContainer.currentAmount);
},
get finished() {
return drone.waterContainer.currentAmount === drone.waterContainer.volume;
},
}
}
const outtakeWaterJob = drone => {
return {
update() {
drone.pump.outtake();
//console.log(drone.waterContainer.currentAmount);
},
get finished() {
return drone.waterContainer.currentAmount === 0;
},
}
}
const waterLineJob = (p1, p2) =>
sequenceJob(
flyToJob(p1),
anyJob(
patrolJob(p1, p2),
outtakeWaterJob,
),
);
const plantJob = seedKey => drone => {
let complete = false;
return {
reset() { complete = false; },
update() {
if (complete)
return;
complete = drone.shovel.plant(seedKey);
},
get finished() { return complete; }
}
}
const performAtJob = (job, x, y) => {
const destJob = flyToJob(x, y);
return sequenceJob(destJob, allJob(destJob, job));
}
const plantAtJob = (seedKey, x, y) => performAtJob(plantJob(seedKey), x, y);
const extractJob = drone => {
let complete = false;
return {
reset() { complete = false; },
update() {
if (complete)
return;
complete = drone.shovel.extract();
},
get finished() { return complete; },
}
}
const extractAtJob = (x, y) => performAtJob(extractJob, x, y);
const intakeWaterAtJob = (x, y) => performAtJob(intakeWaterJob, x, y);
const jobList = [
buyUpToJob('orangeSeed', 5),
plantAtJob('orangeSeed', 905, 355),
plantAtJob('orangeSeed', 905, 385),
plantAtJob('orangeSeed', 905, 415),
plantAtJob('orangeSeed', 905, 445),
plantAtJob('orangeSeed', 905, 475),
intakeWaterAtJob(945, 165),
waterLineJob(new Point(905, 355), new Point(905, 475)),
extractAtJob(305, 205),
extractAtJob(325, 205),
// extractAtJob(345, 205),
// extractAtJob(365, 205),
sellMaxJob('grass'),
sellMaxJob('soil'),
extractAtJob(905, 355),
extractAtJob(905, 385),
extractAtJob(905, 415),
extractAtJob(905, 445),
extractAtJob(905, 475),
sellMaxJob('orange'),
sellMaxJob('soil'),
];
const rootJob = loopJob(...jobList);
// --------------------- Lifecycle methods ---------------------
// These functions MUST be present, even if empty
// Called once right after every patch
function start(drone) {
// Memory usage example, memory can contain any object
drone.memory = drone.memory ?? {};
drone.memory.patchNumber = (drone.memory.patchNumber ?? 0) + 1;
console.log(`Drone patched ${drone.memory.patchNumber} times`);
}
// Called once every frame
function update(drone) {
// Uncomment this line to take a look at what 'drone' object has
// (although it might be easier to read the game page description)
// console.log(drone);
drone.motor.force = new Point();
rootJob(drone).update();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment