CB-WP-0008-T03: prove the 2-6 player range
GR-O01 states 2-6 players; every scenario in the corpus was 3-player. Now all five counts play to GameEnded under both policies and reproduce at the same seed, with scenarios at both boundaries and the CLI transcript run at 2p, 3p and 6p. Nothing broke — the rules are seat-count-generic. What the boundaries exposed is arithmetic: with the standard preset's placeholder Problem values (value = priority), the best total any game can reach is 3 at 2p, 6 at 3-4p, 10 at 5-6p, against GR-E01 thresholds of 5, 7 and 9. Group success is unreachable below five seats regardless of play, and no scenario noticed because none had played to scoring with everything claimed. GR-S01 calls the fixture a stand-in for scenario Problem data, so this is evidence the stand-in is not neutral, not that GR-E01 is wrong. It is pinned by a passing scenario, an arithmetic test, and a provisional marker owned by ground-game so it ages in `make coverage`. The test states its own delete-by: it is expected to fail when Problem values become real data, and that failure is the signal to delete it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
25531e9d01
commit
d97e8e825d
7 changed files with 289 additions and 28 deletions
|
|
@ -820,4 +820,74 @@ mod tests {
|
|||
);
|
||||
}
|
||||
}
|
||||
/// GR-O01 says 2–6 players. Every scenario in the corpus was
|
||||
/// 3-player until CB-WP-0008 T03, so the range was stated and tested
|
||||
/// at one point. This plays all five counts with both policies.
|
||||
#[test]
|
||||
fn every_seat_count_in_gr_o01_plays_to_the_end() {
|
||||
for players in 2..=6u8 {
|
||||
for kind in ["random", "greedy"] {
|
||||
let game = play(setup(players, 42), &mut policies(kind, players, 42))
|
||||
.unwrap_or_else(|e| panic!("{players}p {kind}: {e}"));
|
||||
let outcome = game
|
||||
.state
|
||||
.outcome
|
||||
.as_ref()
|
||||
.unwrap_or_else(|| panic!("{players}p {kind}: no outcome"));
|
||||
assert_eq!(game.state.round, 5, "{players}p {kind}: GR-R09");
|
||||
assert_eq!(
|
||||
outcome.personal.len(),
|
||||
usize::from(players),
|
||||
"{players}p {kind}: every seat must be scored"
|
||||
);
|
||||
// K8 at each boundary, not only at three seats.
|
||||
let again =
|
||||
play(setup(players, 42), &mut policies(kind, players, 42)).expect("second run");
|
||||
assert_eq!(
|
||||
cb_events::state_hash_hex(&game.state),
|
||||
cb_events::state_hash_hex(&again.state),
|
||||
"{players}p {kind}: same seed must reproduce"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// **A recorded finding, not a desired property.** With the standard
|
||||
/// preset's placeholder Problem values (value = priority), the total
|
||||
/// a game can possibly reach is below GR-E01's threshold at 2, 3 and
|
||||
/// 4 players — group success is unreachable regardless of play. Only
|
||||
/// 5–6p can clear its 9.
|
||||
///
|
||||
/// This test pins the arithmetic so the gap cannot close silently.
|
||||
/// **It is expected to fail** when Problem values become scenario
|
||||
/// data (GR-S01 calls the current fixture a stand-in); the failure is
|
||||
/// the signal to delete it, not to re-tune it.
|
||||
#[test]
|
||||
fn the_standard_preset_cannot_reach_the_threshold_below_five_seats() {
|
||||
let mut report = Vec::new();
|
||||
for players in 2..=6u8 {
|
||||
let initial = setup(players, 42);
|
||||
let best: u32 = initial.problems.values().map(|p| u32::from(p.value)).sum();
|
||||
let threshold = play(initial, &mut policies("greedy", players, 42))
|
||||
.expect("game")
|
||||
.state
|
||||
.outcome
|
||||
.expect("outcome")
|
||||
.threshold;
|
||||
report.push(format!("{players}p best {best} vs threshold {threshold}"));
|
||||
if players < 5 {
|
||||
assert!(
|
||||
best < threshold,
|
||||
"{players}p: best {best} now reaches threshold {threshold} — \
|
||||
the fixture changed, delete this test"
|
||||
);
|
||||
} else {
|
||||
assert!(
|
||||
best >= threshold,
|
||||
"{players}p: best {best} cannot reach threshold {threshold}"
|
||||
);
|
||||
}
|
||||
}
|
||||
println!("GR-E01 reachability: {}", report.join(", "));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue