SpellGrid capstone: Part I's card engine and Part II's grid engine joined at three seams (rules -> aura data, hazard victims -> one destroy Sequence, Sequence end -> write text, remove the dead, reparse). Three levels with scripted solutions, a naive-timing test via a harness-only hook that reverses the END_OF_PHASE list, CLIs in both tracks, the BATTLECRY IS DOUBLE Expansion Drop, SpellGrid cards and words in course/cards and the catalog, level schema cards/hand, and tools staging/copying of module levels. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
44 lines
1.1 KiB
Rust
44 lines
1.1 KiB
Rust
// Module 10 Expansion Drop: BATTLECRY IS DOUBLE. The scenario is in ../../README.md.
|
|
use engine::harness::*;
|
|
|
|
#[test]
|
|
fn test_10x_battlecry_is_double() {
|
|
let words = [("BATTLECRY", 0), ("IS", 1), ("DOUBLE", 2)];
|
|
let mut g = new_spell_grid(
|
|
LevelDef {
|
|
width: 5,
|
|
height: 3,
|
|
objects: words
|
|
.iter()
|
|
.map(|&(w, x)| LevelObject {
|
|
kind: format!("text:{w}"),
|
|
x,
|
|
y: 0,
|
|
})
|
|
.collect(),
|
|
cards: vec![],
|
|
hand: vec!["Town Crier".to_string()],
|
|
},
|
|
vec![],
|
|
);
|
|
|
|
assert!(g.active_rules().iter().any(|r| r == "BATTLECRY IS DOUBLE"));
|
|
|
|
g.clear_log();
|
|
let crier = g.play("Town Crier", 0, 2);
|
|
|
|
let battlecries = g
|
|
.log()
|
|
.into_iter()
|
|
.filter(|e| {
|
|
*e == GameEvent::Triggered {
|
|
source: crier,
|
|
trigger: "battlecry".to_string(),
|
|
}
|
|
})
|
|
.count();
|
|
assert_eq!(battlecries, 2);
|
|
assert_eq!(g.health(g.hero(1)), 28);
|
|
assert_eq!(g.kinds_at(0, 2), vec!["crier"]);
|
|
}
|