Add p4, the one close anchor — the wild night is now winnable (gate 1)
SPRINT6 gate 1's anchor lever, placed by measurement rather than by guess. The wild night had no winnable line for a geometric reason: every anchor near the bed (p1/p2/p3) is SOUTH of it, and nothing stands north short of the house 10 m away. So covering rigs had to span the yard and died, while rigs small enough to survive sat beside the bed rather than over it. p4 supplies the missing north-west corner. Its position is swept, not chosen. Against the smallest quad covering 90% of the bed: (-2.2,-1.2) → 44.4 m², (-3.2,-1.2) → 48.6, (-3.2,-2.0) → 51.7, beyond z=-4 → no effect at all. Pulling it inward to 44.4 would put full coverage INSIDE the survivable band and collapse DESIGN.md's central tension — covering the bed has to cost risk. a.test.js's >45 m² floor is what shouts if anyone moves it in. With the 8° rake the top anchor lands at (-3.72, -1.40), and full coverage costs 51.6 m² against 63.5 before: a real new option, 19% cheaper, still bigger than the 23-38 m² rigs that survive unaided. Measured through the real $80 shop: t2+p3+p4+t2b, four shackles and a spare ($75), ends hp 58 with 1 corner lost — a WIN, where before every covering rig lost 2-3 corners and ended at 36%. Hail damage falls 51 → 34 HP versus an uncovered rig, so decision 13 is visibly doing its job. Selftest 244/0/0; both yard tensions still green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
c3967d98e8
commit
2af4662cd7
@ -234,11 +234,11 @@ export default async function run(t) {
|
|||||||
|
|
||||||
// --- anchors -------------------------------------------------------------
|
// --- anchors -------------------------------------------------------------
|
||||||
|
|
||||||
t.test('yard offers 11 anchors: 3 house, 5 tree, 3 post', () => {
|
t.test('yard offers 12 anchors: 3 house, 5 tree, 4 post', () => {
|
||||||
const by = (type) => world.anchors.filter((a) => a.type === type).length;
|
const by = (type) => world.anchors.filter((a) => a.type === type).length;
|
||||||
assertEq(by('house'), 3, 'house anchors');
|
assertEq(by('house'), 3, 'house anchors');
|
||||||
assertEq(by('tree'), dressed ? 5 : 2, 'tree anchors (branch_anchor_* arrive with dress())');
|
assertEq(by('tree'), dressed ? 5 : 2, 'tree anchors (branch_anchor_* arrive with dress())');
|
||||||
assertEq(by('post'), 3, 'post anchors — p3 added, SPRINT3 decision 2');
|
assertEq(by('post'), 4, 'post anchors — p3 (SPRINT3 dec 2), p4 (SPRINT6 gate 1)');
|
||||||
const ids = world.anchors.map((a) => a.id);
|
const ids = world.anchors.map((a) => a.id);
|
||||||
assertEq(new Set(ids).size, ids.length, `anchor ids not unique: ${ids}`);
|
assertEq(new Set(ids).size, ids.length, `anchor ids not unique: ${ids}`);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -270,10 +270,32 @@ export function createWorld(scene, opts = {}) {
|
|||||||
// 6 m bed with it costs you a sail the storm will take. Full shade is meant to
|
// 6 m bed with it costs you a sail the storm will take. Full shade is meant to
|
||||||
// be the expensive answer; the small quads buy survival and pay in patchy
|
// be the expensive answer; the small quads buy survival and pay in patchy
|
||||||
// shade. That IS the design (DESIGN.md, "big flat low vs small twisted steep").
|
// shade. That IS the design (DESIGN.md, "big flat low vs small twisted steep").
|
||||||
|
// SPRINT6 gate 1: p4 is the ONE close anchor the balance pass allows, and its
|
||||||
|
// position is measured rather than guessed.
|
||||||
|
//
|
||||||
|
// The wild night had no winnable line because every anchor near the bed —
|
||||||
|
// p1/p2/p3 — is SOUTH of it, and nothing stands north short of the house 10 m
|
||||||
|
// away. So covering rigs had to span the yard and died, while rigs small
|
||||||
|
// enough to survive sat beside the bed instead of over it.
|
||||||
|
//
|
||||||
|
// p4 supplies the missing north-west corner. Swept its position against the
|
||||||
|
// smallest quad that covers 90% of the bed:
|
||||||
|
// (-2.2, -1.2) → 44.4 m² ← breaks the tradeoff (see below)
|
||||||
|
// (-3.2, -1.2) → 48.6 m² ← here
|
||||||
|
// (-3.2, -2.0) → 51.7 m²
|
||||||
|
// (-4.2, -3.0) → 60.0 m²
|
||||||
|
// beyond ~z=-4 → 63.5 m², i.e. too far away to matter at all
|
||||||
|
// Full coverage costs 63.5 m² without it. At (-3.2,-1.2) that drops to 48.6 —
|
||||||
|
// a real new option, 23% cheaper — while still costing you a bigger sail than
|
||||||
|
// the 23-38 m² rigs that survive on their own. Pulling it in to (-2.2,-1.2)
|
||||||
|
// would put full coverage at 44.4 m², INSIDE the survivable band, which
|
||||||
|
// collapses DESIGN.md's central tension: covering the bed has to cost risk.
|
||||||
|
// a.test.js asserts that >45 m² floor, so moving this post inward goes red.
|
||||||
const postSpecs = [
|
const postSpecs = [
|
||||||
{ id: 'p1', x: -4.5, z: 5.5, h: 4.0 },
|
{ id: 'p1', x: -4.5, z: 5.5, h: 4.0 },
|
||||||
{ id: 'p2', x: 4.0, z: 6.0, h: 4.0 },
|
{ id: 'p2', x: 4.0, z: 6.0, h: 4.0 },
|
||||||
{ id: 'p3', x: 0, z: 7.0, h: 4.0 },
|
{ id: 'p3', x: 0, z: 7.0, h: 4.0 },
|
||||||
|
{ id: 'p4', x: -3.2, z: -1.2, h: 4.0 },
|
||||||
];
|
];
|
||||||
const RAKE = (8 * Math.PI) / 180;
|
const RAKE = (8 * Math.PI) / 180;
|
||||||
for (const spec of postSpecs) {
|
for (const spec of postSpecs) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user