diff --git a/.claude/skills/wizwar-duel/SKILL.md b/.claude/skills/wizwar-duel/SKILL.md index b673d5a..3f6c969 100644 --- a/.claude/skills/wizwar-duel/SKILL.md +++ b/.claude/skills/wizwar-duel/SKILL.md @@ -113,6 +113,38 @@ probing legality is free, so when unsure, try it and read the error. - Grab-turn-one openings feel great and prove nothing: deliveries are the only score. He banked quietly both times while I showboated. +## Game-five scars (eliminated by a rule I implemented myself) + +- **THE ELIMINATION CLOCK**: the moment BOTH treasures you protect sit + on living opponents' home bases, you are OUT — points, life, and + position notwithstanding. In multiplayer this clock starts ticking + the instant your second chest is picked up by anyone. From then on, + every turn must either recover a chest or end the game first. I spent + three turns optimizing deliveries while two bots quietly carried my + death certificate. +- **FEAR IS A SELF-CAST AURA** — read the card, not your assumptions: + "no player or monster will move to within 3 spaces of you," walls + irrelevant, and anyone already within 3 MUST flee on their turn. It + is armor for carriers and a hearth-denial tool: a feared wizard + standing 2 from your home makes delivery impossible. I invented an + elaborate theory about enemy goalkeeping instead of reading my own + engine's card text. Check `data/cards.json` when a rule surprises — + it is one grep away and it is verbatim. +- In four-player, Kestrel plays the TABLE, not the duel: his SWAP + yanked a bot off its own doorstep mid-delivery and parked himself by + unclaimed treasures — one card, two tempo hits. Expect every card he + plays to hurt two players at once, and ask which two before deciding + it wasn't aimed at you. +- CREATE WALL can sever your announced return route the turn after you + telegraph it. If your road home is unique, either don't stand at the + far end of it, or carry the picks/doors to re-open it. And CREATE + DOOR makes LOCKED doors — it is a key-cutter, worthless without picks. +- Bot threat model: archmage automatons DO deliver, but their brains + can dither inexplicably (one toured the map for two rounds carrying + my elimination). Never count on bot incompetence — count turns to + their delivery square as if they play perfectly, and treat every + reprieve as a gift, not a pattern. + ## Playing well - Kestrel (Eric) is EXCELLENT: he baited my thief, saved anti-anti for diff --git a/packages/engine/src/automaton.ts b/packages/engine/src/automaton.ts index 30f49be..63e9f3a 100644 --- a/packages/engine/src/automaton.ts +++ b/packages/engine/src/automaton.ts @@ -1541,7 +1541,10 @@ export function automatonCommand( // ends the march); otherwise the gold has its legs for the turn. const strikeLive = !view.turn.attackUsed && !view.turn.attackForbidden && !view.turn.actionsEnded && view.yourHand.some((c) => ATTACKS[c.cardId] != null); - const chasing = thief !== null && strikeLive; + // A carrier never chases: the delivery in hand outranks the gold in + // someone else's. Chasing while laden once marched a bot across the + // whole board, four steps from a winning drop. + const chasing = thief !== null && strikeLive && !self.carriedTreasureId; // BANK GUARD: enemy gold delivered to my home is my scoreboard, and // anyone may snatch it off the floor. A raider nearer my bank than I // am, with the bank stocked, outranks the next grab — run home. @@ -1565,10 +1568,13 @@ export function automatonCommand( const path = pathToward(view, self.position, objectives, { avoidNearEnemies: style === "worrier" && !chasing, canUnlock }) ?? pathToward(view, self.position, objectives, { canUnlock }) ?? + // The true objective, hazards waded, comes before any generic march + // on enemies: one thornbush on the road must not reroute the whole + // campaign toward whoever happens to have a clean corridor. + pathToward(view, self.position, objectives, { canUnlock, throughHazards: true }) ?? pathToward(view, self.position, enemyCells, { canUnlock }) ?? // No clean road to anything: grit the teeth and wade the hazards, // as any wizard would rather than stand in a pocket forever. - pathToward(view, self.position, objectives, { canUnlock, throughHazards: true }) ?? pathToward(view, self.position, enemyCells, { canUnlock, throughHazards: true }); // A shimmering illusion on the best crossing costs nothing to doubt: // roll the free test before spending any card on that wall.