Created
August 15, 2022 19:56
-
-
Save nns2009/777fee06a96bf64d3ab158b8360db6ef to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ---------------------------------------------------------- | |
// ---------------------------------------------------------- | |
// --------------------- 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