Piles near the bot sort, and 20 times faster; burning fuel keeps the slow pace (t21)
- SORTP 0.003 -> 0.06: ore sinks through 8 rows of ash in about 7 s near the bot. - wakeBotPowder(): every 8 ticks, areas with loose grains within 100 grains of the bot get a sorting chance; far away, resting piles still sleep. - Sinking through burning fuel stays at 0.003, so buried burning piles still char and furnace beds behave as tuned. World generation settles at the old rate: seeds are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+38
-18
@@ -24,25 +24,45 @@ ticks(run, 1800);
|
||||
check('digging under a heap makes it fall into the hole', grains('SAND') === 400 && count(run, run('SAND'), 140, 120, 179, 159) > 300,
|
||||
`${count(run, run('SAND'), 140, 120, 179, 159)} of ${grains('SAND')} in the hole`);
|
||||
asleep('sand after digging');
|
||||
// heavy ore works its way down through light ash, slowly, while the pile is being stirred (a
|
||||
// working furnace bed is always awake); a pile left at rest goes to sleep and stays as it is
|
||||
world();
|
||||
rect(run, 150, 100, 151, 119, run('STONE')); rect(run, 170, 100, 171, 119, run('STONE'));
|
||||
rect(run, 152, 112, 169, 119, run('ASH')); rect(run, 152, 108, 169, 111, run('CUORE'));
|
||||
// Supported layers start asleep, just like a pile the bot walks up to.
|
||||
const oreY = (m) => run(`(() => { let s = 0, n = 0; for (let i = 0; i < N; i++) if (mat[i] === ${m}) { s += (i / W) | 0; n++; } return s / n; })()`);
|
||||
const ore0 = oreY(run('CUORE')); ticks(run, 3600); const oreRest = oreY(run('CUORE'));
|
||||
check('a resting pile of ore on ash goes to sleep as it is', Math.abs(oreRest - ore0) < 0.5 && awake() === 0, `ore rows ${ore0.toFixed(1)} -> ${oreRest.toFixed(1)}, ${awake()} awake`);
|
||||
const stir = n => run(`for (let k = 0; k < ${n}; k++) { if (k % 8 === 0) wakeXY(160, 112); simTick(); }`);
|
||||
stir(600); const ore1 = oreY(run('CUORE')); stir(5400); const ore2 = oreY(run('CUORE'));
|
||||
check('stirred, heavy ore sinks down through light ash, slowly', ore1 - oreRest < 2 && ore2 - oreRest > 2 && grains('CUORE') === 72 && grains('ASH') === 144,
|
||||
`ore rows ${oreRest.toFixed(1)} -> ${ore1.toFixed(1)} -> ${ore2.toFixed(1)}`);
|
||||
ticks(run, 1200); asleep('ore after stirring stops');
|
||||
world();
|
||||
rect(run, 150, 100, 151, 119, run('STONE')); rect(run, 170, 100, 171, 119, run('STONE'));
|
||||
rect(run, 152, 112, 169, 119, run('LDIRT')); rect(run, 152, 104, 169, 111, run('SAND'));
|
||||
const sand0 = oreY(run('SAND')); ticks(run, 6000);
|
||||
check('sand on dirt (close in weight) stays where it is', Math.abs(oreY(run('SAND')) - sand0) < 0.5, `sand rows ${sand0.toFixed(1)} -> ${oreY(run('SAND')).toFixed(1)}`);
|
||||
asleep('a pile of similar weights');
|
||||
function sortingPile(near, similar = false) {
|
||||
world(640);
|
||||
rect(run, 150, 100, 151, 119, run('STONE')); rect(run, 170, 100, 171, 119, run('STONE'));
|
||||
rect(run, 152, 112, 169, 119, run(similar ? 'LDIRT' : 'ASH'));
|
||||
rect(run, 152, similar ? 104 : 108, 169, 111, run(similar ? 'SAND' : 'CUORE'));
|
||||
run(`bot.x = ${near ? 158 : 530}; bot.y = 90; awake.fill(0);`);
|
||||
}
|
||||
sortingPile(true);
|
||||
let sortedAt = 0;
|
||||
for (let t = 8; t <= 600; t += 8) {
|
||||
ticks(run, 8);
|
||||
if (!sortedAt && count(run, run('CUORE'), 152, 116, 169, 119) === 72) sortedAt = t;
|
||||
}
|
||||
check('near the bot, resting ore sorts to the bottom of ash within 600 ticks', sortedAt > 0 && grains('CUORE') === 72 && grains('ASH') === 144,
|
||||
`all 72 ore at bottom after ${sortedAt || '>600'} ticks, ${grains('CUORE')} ore + ${grains('ASH')} ash`);
|
||||
ticks(run, 600); asleep('sorted ore near the bot');
|
||||
sortingPile(false);
|
||||
const ore0 = oreY(run('CUORE')); ticks(run, 1200);
|
||||
check('far from the bot, resting ore on ash stays put and sleeps', oreY(run('CUORE')) === ore0 && grains('CUORE') === 72 && grains('ASH') === 144 && awake() === 0,
|
||||
`ore rows ${ore0} -> ${oreY(run('CUORE'))}, ${awake()} awake`);
|
||||
// Visiting an old sleeping pile must work, too (not only freshly placed grains).
|
||||
run('bot.x = 158;'); ticks(run, 600);
|
||||
check('approaching a sleeping pile starts sorting', count(run, run('CUORE'), 152, 116, 169, 119) === 72,
|
||||
`${count(run, run('CUORE'), 152, 116, 169, 119)}/72 ore at bottom`);
|
||||
for (const near of [true, false]) {
|
||||
sortingPile(near, true);
|
||||
const sand0 = oreY(run('SAND')); ticks(run, 6000);
|
||||
check(`sand on dirt (close in weight) stays put and sleeps ${near ? 'near' : 'far from'} the bot`, oreY(run('SAND')) === sand0 && grains('SAND') === 144 && grains('LDIRT') === 144 && awake() === 0,
|
||||
`sand rows ${sand0} -> ${oreY(run('SAND'))}, ${awake()} awake`);
|
||||
}
|
||||
world(); ticks(run, 8); run('wakeBotPowder();');
|
||||
check('nearby areas without powder are skipped after one visit', awake() === 0,
|
||||
`${awake()} awake`);
|
||||
rect(run, 152, 116, 169, 119, run('SAND')); ticks(run, 16);
|
||||
run('wakeBotPowder();');
|
||||
check('processed areas remember powder added after an empty visit', awake() > 0,
|
||||
`${awake()} awake`);
|
||||
// sand dropped into a pond sinks, and the water ends up on top
|
||||
world();
|
||||
rect(run, 150, 90, 151, 119, run('STONE')); rect(run, 190, 90, 191, 119, run('STONE'));
|
||||
|
||||
Reference in New Issue
Block a user