fix: Task 10 review round 1 (Module 13 table rows in hand-made order, DEFEAT before HOT/MELT explained, one survivor count)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
78862d1a1f
commit
e5cde8a556
2 files changed
+13
-13
No files matched your search
@@ -16,7 +16,7 @@ Three bugs, all in the reference engines, all with every test passing.
|
||||
|
||||
**An object that moved twice.** A key that was `YOU` and `PULL`, standing behind Baba, was dragged one tile by Baba's move and then took its own step ([Module 8](../08-push-chains/lesson.md), Expansion Drop). The lesson told learners to "make sure a YOU object that is also PUSH doesn't move twice"; the reference did that with an ordering trick that only worked for PUSH.
|
||||
|
||||
And one that wasn't a bug but could have become one at any time: six different changes to the *order* in which the engines do things (two phases of the turn swapped, a parse dropped, the hazards reversed, the aura snapshot replaced by a live scan) left every test green.
|
||||
And one that wasn't a bug but could have become one at any time: five different changes to the *order* in which the engines do things (a parse dropped in two places, two phases of the turn swapped, the hazards reversed, the aura snapshot replaced by a live scan) left every test green.
|
||||
|
||||
Notice what the three bugs have in common. None is in a hard algorithm. Each is the meeting of two features that were each tested alone: simultaneous death and summon position; group nouns and conversion; pull and several `YOU` objects. This course is about systems whose parts combine freely, and the price of that is that the number of combinations grows much faster than anyone can write tests by hand.
|
||||
|
||||
@@ -57,14 +57,14 @@ The list is now data, and a tool runs it. `tools/mutants.json` holds one entry p
|
||||
| Turn: hazards before conversion | `test_09_conversion_before_hazards`, `test_09_conversion_reparses_before_hazards`, `test_09_undo_restores_everything` |
|
||||
| Turn: no last parse | `test_09_last_parse_matches_board` |
|
||||
| Hazards in reverse order | `test_09_hazard_order_melt_before_defeat`, `test_09_hazard_order_sink_before_melt`, `test_10_level_6_solution`, `test_11_condition_rechecked_between_hazards` |
|
||||
| Hazards: DEFEAT before HOT/MELT | `test_09_hazard_order_melt_before_defeat`, `test_10_level_6_solution` |
|
||||
| Auras read live from the board, no snapshot | `test_05_own_aura_misses_own_battlecry`, `test_10_level_3_naive_would_differ` |
|
||||
| Hazards: DEFEAT before HOT/MELT | `test_09_hazard_order_melt_before_defeat`, `test_10_level_6_solution` |
|
||||
| Damage: Armor before redirect | `test_04_redirect_before_armor` |
|
||||
| Conditions decided at parse time | `test_11_condition_rechecked_between_hazards` |
|
||||
| Combat: no defender priority | `test_12_defender_triggers_first` |
|
||||
| SpellGrid: a summoned minion without a noun enters the grid | `test_10_summon_without_noun_stays_off_grid` |
|
||||
|
||||
No row is empty. The first eight are the hand-made table. The last five are the decisions added since: the order of the damage steps ([Module 4](../04-interceptors/lesson.md)), conditions checked when a rule is used and not when it is parsed ([Module 11](../11-conditions/lesson.md)), the defender's triggers first ([Module 12](../12-combat/lesson.md)), and the noun check in SpellGrid's fourth seam ([Module 10](../10-spellgrid/lesson.md)). Several rows have one killer. Delete that test and the decision is unpinned again; the tool would say so.
|
||||
No row is empty. The first eight are the hand-made table. The last five were added with the tool. One is a hazard order the hand-made table left out, DEFEAT before HOT/MELT: `test_09_hazard_order_melt_before_defeat` pins it ([Module 9](../09-turn-pipeline/lesson.md), Predict question 11), and so does level 6, whose idea it is. The other four are decisions added since: the order of the damage steps ([Module 4](../04-interceptors/lesson.md)), conditions checked when a rule is used and not when it is parsed ([Module 11](../11-conditions/lesson.md)), the defender's triggers first ([Module 12](../12-combat/lesson.md)), and the noun check in SpellGrid's fourth seam ([Module 10](../10-spellgrid/lesson.md)). Several rows have one killer. Delete that test and the decision is unpinned again; the tool would say so.
|
||||
|
||||
Killing a mutant is a design exercise. You have to find the smallest situation in which the two orders give different results, and sometimes you learn that there isn't one. With one property per object, the order of SINK and HOT/MELT can't be observed at all ([Module 9](../09-turn-pipeline/lesson.md), Stress it question 2), until a condition lets one hazard change what another hazard's victim is ([Module 11](../11-conditions/lesson.md), Stress it question 1). The live-aura mutant survived because three separate mechanisms guard the same behaviour ([Module 4](../04-interceptors/lesson.md), Stress it questions 2 and 3). A surviving mutant means one of three things: a missing test, a decision that isn't observable yet, or redundant machinery. All three are worth knowing.
|
||||
|
||||
|
||||
+10
-10
@@ -72,16 +72,6 @@
|
||||
"test_11_condition_rechecked_between_hazards"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Hazards: DEFEAT before HOT/MELT",
|
||||
"file": "src/content/hazards.ts",
|
||||
"find": "return [sink, hotMelt, defeat];",
|
||||
"replace": "return [sink, defeat, hotMelt];",
|
||||
"expect": [
|
||||
"test_09_hazard_order_melt_before_defeat",
|
||||
"test_10_level_6_solution"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Auras read live from the board, no snapshot",
|
||||
"file": "src/engine/world.ts",
|
||||
@@ -92,6 +82,16 @@
|
||||
"test_10_level_3_naive_would_differ"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Hazards: DEFEAT before HOT/MELT",
|
||||
"file": "src/content/hazards.ts",
|
||||
"find": "return [sink, hotMelt, defeat];",
|
||||
"replace": "return [sink, defeat, hotMelt];",
|
||||
"expect": [
|
||||
"test_09_hazard_order_melt_before_defeat",
|
||||
"test_10_level_6_solution"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Damage: Armor before redirect",
|
||||
"file": "src/engine/queue.ts",
|
||||
|
||||
Reference in new issue
Block a user