Diagonal screw tubes, laid by a 45° drag (t35)

- Tubes run in eight directions: a drag at about 45° lays a diagonal run, R cycles all eight.
- Diagonal runs carry grains at the straight rate (120 grains/s), join straight tubes and belts,
  keep grains in at the corners, pass water, and carry bars level.
- New part ids 11-14 (saved ids are never renumbered); tube checks use an IS_TUBE table.
- New test/t_diag_tubes.js (85 checks).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-25 17:37:30 -04:00
co-authored by Claude Opus 5.5
parent 381019b7aa
commit 8087c28cb5
26 changed files with 348 additions and 65 deletions
+14 -5
View File
@@ -10,7 +10,7 @@ let nextPowerBuild = 0;
function rebuildPower() {
powerDirty = false;
for (const i of pcells) netId[i] = 0;
nets = [null]; beltL = []; beltR = []; tubeLists = [[], [], [], [], []];
nets = [null]; beltL = []; beltR = []; tubeLists = Array.from({ length: IS_TUBE.length }, () => []);
const stack = [];
for (const s of pcells) {
if (netId[s]) continue;
@@ -23,8 +23,13 @@ function rebuildPower() {
const i = stack.pop();
const m = mat[i], p = part[i];
if (m === BELTL) { net.nb++; beltL.push(i); } else if (m === BELTR) { net.nb++; beltR.push(i); }
if (p >= P_TU && p <= P_TR) { net.nt++; tubeLists[p].push(i); }
const x = i % W;
if (IS_TUBE[p]) { net.nt++; tubeLists[p].push(i); }
const x = i % W, y = (i / W) | 0;
// Corner-touching screws share power, without connecting unrelated diagonal machinery.
if (IS_TUBE[p] && TDX[p] && TDY[p]) for (let d = -1; d <= 1; d += 2) {
const xx = x + d * TDX[p], yy = y + d * TDY[p], j = yy * W + xx;
if (xx >= 0 && xx < W && yy >= 0 && yy < H && part[j] === p && isPow[j] && !netId[j]) { netId[j] = id; stack.push(j); }
}
let j;
if (x > 0) { j = i - 1; if (isPow[j] && !netId[j]) { netId[j] = id; stack.push(j); } }
if (x < W - 1) { j = i + 1; if (isPow[j] && !netId[j]) { netId[j] = id; stack.push(j); } }
@@ -40,8 +45,12 @@ function rebuildPower() {
if (mm.type === 'fan') net.fans.push(mm); else if (mm.type === 'wheel' || mm.type === 'engine') net.prods.push(mm);
}
beltL.sort((a, b) => a - b); beltR.sort((a, b) => b - a);
tubeLists[P_TU].sort((a, b) => a - b); tubeLists[P_TD].sort((a, b) => b - a);
tubeLists[P_TL].sort((a, b) => a - b); tubeLists[P_TR].sort((a, b) => b - a);
for (const p of TUBE_PARTS) {
tubeLists[p].sort((a, b) => {
if (TDX[p] && TDY[p]) return ((b % W) - (a % W)) * TDX[p];
return (TDY[p] || TDX[p]) < 0 ? a - b : b - a;
});
}
}
function netSat(i) { if (POWER_FREE) return 1; const n = nets[netId[i]]; return n ? n.sat : 0; }