Adds course/12-combat: lesson, scenarios, nine test_12 tests in both tracks, the cumulative reference (Module 11's plus combat) and the drop. The Damage action carries per-target hits with a priority; react stable-sorts its Queue by priority before order of play, so the triggers answering the defender's Damage Event go first. orderAttack/canAttack/endTurn join the harness (orderAttack because attack(id) already reads Attack). endOfTurn triggers fire, so Drakkari Enchanter's data is live. Test Bell is scoped to Module 12's cards. Harness contract, catalog, research notes and earlier lessons' forward pointers follow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
23 lines
2.0 KiB
Markdown
23 lines
2.0 KiB
Markdown
# Module 12 Expansion Drop: Bonechewer Brawler
|
|
|
|
The lesson's [Expansion Drop](../lesson.md#expansion-drop) beat explains the task. This file holds the scenario, the test locations and the check.
|
|
|
|
- Card: Bonechewer Brawler, 2-mana 2/3 Neutral minion, "Taunt. Whenever this minion takes damage, gain +2 Attack." ([Bonechewer Brawler, hearthstone.wiki.gg](https://hearthstone.wiki.gg/wiki/Bonechewer_Brawler)).
|
|
- Tests: `tests/rust/test_12x.rs` and `tests/ts/test_12x.test.ts`. Copy the one for your track into your workspace's `tests/`.
|
|
- Reference answer: `solution/cards/bonechewer-brawler.json`, one card file for both tracks. Copy it into your workspace's `cards/`. Nothing under `src/engine/` changes, and neither does the harness. It is not in `course/cards/`, so `start-module` doesn't hand it to you.
|
|
- Check: commit your workspace before you start, then run `node tools/expansion-check.mjs <your-workspace> <that-commit>` from the course repository. It fails if any file under `src/engine/` changed.
|
|
|
|
Every clause of the card is a word the course already has: the keyword `taunt` (Unstable Ghoul has it), the trigger `selfDamaged` (Acolyte of Pain) and the effect `gainAttack` on `self` (Frothing Berserker). Before this module the engine kept `taunt` and did nothing with it. Now combat reads it.
|
|
|
|
## Scenario
|
|
|
|
### test_12x_bonechewer_brawler
|
|
|
|
- Setup: `newGame` with a deck of 5 `Test Filler` for each player. Summon `Bonechewer Brawler` for player 1 (id W), then `Loot Hoarder` for player 1 (id H), then `Harvest Golem` for player 0 (id A). Call `clearLog()`.
|
|
- Assertions 1: `canAttack(A, H)` is a string containing `Taunt`: the Brawler protects the Hoarder.
|
|
- Action: `orderAttack(A, W)`.
|
|
- Assertions 2:
|
|
- The log is exactly, in this order: `Damaged{target: W, amount: 2}`, `Damaged{target: A, amount: 2}`, `Triggered{source: W, trigger: "damaged"}`, `StatsChanged{id: W, attack: 4, health: 1}`.
|
|
- `health(A)` is 1: the Golem took 2, the Brawler's Attack when the damage was dealt. The +2 Attack comes from a trigger, after the simultaneous damage.
|
|
- `attack(W)` is 4.
|