CB-WP-0012-T04: cb-render-html — stage 1 draws, and the browser is the toolkit
Delivers ADR-0007 Decision 1: visualization, drag-to-propose and hot-seat
play, at a measured marginal AM-4a cost of zero.
games-ground shipped: 23 third-party crates
cb-render-html: 23 third-party crates
new crates introduced: 0
Measured, not asserted — the survey's own lesson. AM-4a is unmoved at
246,250; own source is 7,636 -> 9,652.
What shipped:
crates/cb-render-html doc.rs (HTML/SVG emission, incl. the relationship
graph), input.rs (pointer facts -> commands),
serve.rs (Guard, Request, loopback bind)
tools/cb-play hotseat.rs + `--serve PORT`
Per ADR-0007 Decision 2 there is NO cb-render-api and NO cb-render-null.
The renderer targets the existing Project trait; the port waits for
stage 2's wgpu implementation to be its second use.
The six controls, all live, all mutation-checked (8 mutations, each red
for its stated reason):
1-3 token / Origin+Sec-Fetch-Site / explicit 127.0.0.1 bind
4 a token-less request is refused, in the unit AND over a real socket
5 JS may not construct commands — the page reports pointer facts, Rust
resolves them against the legal list the aggregate already offered,
and a test asserts the emitted script contains no game vocabulary
6 the coverage gate crosses the language boundary: it walks the
serialized view for leaf paths and requires each token to appear in
the PARSED emitted document, with a test that the parse really is a
parse (script/style contents must not count as rendered)
The gate fired on its author again, on its first run: ground_choices.*.
choice, ground_choices.*.problem and players.*.blame_from were in neither
list. The last is the one worth keeping — an EMPTY vector is a leaf path
of its own, and it now renders as an explicit absence.
Also, a mutation that did not go red: removing the Sec-Fetch-Site arm
alone left the cross-site test green, because the Origin check caught it
independently. Both had to be removed before the control bit. Recorded
because a control that passes for a reason you did not intend has not
been demonstrated.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 04:27:25 +02:00
|
|
|
//! A populated `GroundView`, built for the coverage gate.
|
|
|
|
|
//!
|
|
|
|
|
//! Mid-DARVO, mid-GROUND, scored — **not** a fresh deal. Most of the
|
|
|
|
|
//! fields this gate exists to cover are empty at deal time, and a coverage
|
|
|
|
|
//! test run against a state where the fields are absent is the same lie in
|
|
|
|
|
//! a different costume (CB-WP-0011 T01).
|
|
|
|
|
//!
|
|
|
|
|
//! Built directly rather than projected from a `GroundState`. The
|
|
|
|
|
//! projection's own hiding rules are already asserted by
|
|
|
|
|
//! `games_ground::view` and by `cb-play`'s
|
|
|
|
|
//! `the_inspector_never_widens_the_projection`; re-asserting them here
|
|
|
|
|
//! would be a duplicated fact that drifts. What *this* crate must not do
|
|
|
|
|
//! is invent a hand it was never given, and that is what the renderer test
|
|
|
|
|
//! checks — with `hand: None` supplied deliberately.
|
|
|
|
|
|
|
|
|
|
use std::collections::BTreeMap;
|
|
|
|
|
|
|
|
|
|
use cb_kernel::PlayerId;
|
|
|
|
|
use games_ground::view::{GroundView, OutcomeView, PlayerView, ProblemView, SelectionView};
|
|
|
|
|
use games_ground::{
|
|
|
|
|
Action, Coalition, DarvoStage, DarvoTarget, GroundChoice, GroundMode, Pair, Relation,
|
|
|
|
|
RoundStep, ScoringMode, Selection, SolutionCard, Suit, SupportResponse,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
pub fn seats() -> (PlayerId, PlayerId, PlayerId) {
|
|
|
|
|
(PlayerId(0), PlayerId(1), PlayerId(2))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The fixture, seen by `viewer` (`None` for a spectator).
|
|
|
|
|
pub fn view(viewer: Option<PlayerId>) -> GroundView {
|
|
|
|
|
let (p1, p2, p3) = seats();
|
|
|
|
|
let card = |suit| SolutionCard { suit };
|
|
|
|
|
|
|
|
|
|
let mut players = BTreeMap::new();
|
|
|
|
|
for (id, stress, protection, darvo, ready, lifted, blame) in [
|
|
|
|
|
(p1, 5u8, 2u8, DarvoStage::Reverse, true, true, vec![p3]),
|
|
|
|
|
(p2, 1, 0, DarvoStage::Off, false, false, vec![]),
|
|
|
|
|
(p3, 0, 0, DarvoStage::Deny, true, false, vec![]),
|
|
|
|
|
] {
|
|
|
|
|
let own = viewer == Some(id);
|
|
|
|
|
players.insert(
|
|
|
|
|
id,
|
|
|
|
|
PlayerView {
|
|
|
|
|
stress,
|
|
|
|
|
freedom_ready: ready,
|
|
|
|
|
freedom_gate_lifted: lifted,
|
|
|
|
|
darvo,
|
|
|
|
|
protection,
|
|
|
|
|
blame_from: blame,
|
|
|
|
|
hand: own.then(|| vec![card(Suit::Clarify), card(Suit::Boundary)]),
|
|
|
|
|
hand_size: 2,
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mut problems = BTreeMap::new();
|
|
|
|
|
problems.insert(1, ProblemView::FaceDown);
|
CB-WP-0043: a Problem sits where its Stress lands
The picture had become a lie. A row across the middle says "these are the
table's" — true under the baseline, false under H2, where three of five
cards fall on particular seats.
Global goes to the middle, personal beside its owner, and bond on the mean
midpoint of the owner's Bond edges. A bond Problem whose owner has no Bond
is drawn as personal, because that is the rule — bond_network falls back
to the owner at degree 0 — and the picture must agree with the arithmetic.
The baseline page is untouched: the scoped layout is taken only when a
non-global scope exists, so every prior look at the baseline still holds.
The scope reaches the view as a separate marker rather than a field on
ProblemView, because the delta says "place owner marker on the card" — a
token beside a card — and it is public while the card is face down, which
a ProblemView variant could not express.
The coverage probe forced a real improvement. It demanded a text token for
the new fields and a POSITION is not a token — which is the probe being
right: position alone is invisible to text_of and to a screen reader, and
illegible when two anchors coincide. So each scoped Problem now says whose
it is: everyone's, P1's alone, P2's Bond network, and "P1's alone — no
Bond to share it" at degree 0.
The fixture gained a third Problem. With two, one of the three placement
rules was unexercised and the probe unsatisfiable — a fixture that cannot
reach a branch is how a rule ships untested.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 17:30:14 +02:00
|
|
|
// CB-WP-0043: a third Problem so all three H2 scopes are drawn —
|
|
|
|
|
// global (1), personal (6) and bond (7). Two would leave one
|
|
|
|
|
// placement rule unexercised and the coverage probe unsatisfiable.
|
|
|
|
|
problems.insert(6, ProblemView::FaceDown);
|
CB-WP-0012-T04: cb-render-html — stage 1 draws, and the browser is the toolkit
Delivers ADR-0007 Decision 1: visualization, drag-to-propose and hot-seat
play, at a measured marginal AM-4a cost of zero.
games-ground shipped: 23 third-party crates
cb-render-html: 23 third-party crates
new crates introduced: 0
Measured, not asserted — the survey's own lesson. AM-4a is unmoved at
246,250; own source is 7,636 -> 9,652.
What shipped:
crates/cb-render-html doc.rs (HTML/SVG emission, incl. the relationship
graph), input.rs (pointer facts -> commands),
serve.rs (Guard, Request, loopback bind)
tools/cb-play hotseat.rs + `--serve PORT`
Per ADR-0007 Decision 2 there is NO cb-render-api and NO cb-render-null.
The renderer targets the existing Project trait; the port waits for
stage 2's wgpu implementation to be its second use.
The six controls, all live, all mutation-checked (8 mutations, each red
for its stated reason):
1-3 token / Origin+Sec-Fetch-Site / explicit 127.0.0.1 bind
4 a token-less request is refused, in the unit AND over a real socket
5 JS may not construct commands — the page reports pointer facts, Rust
resolves them against the legal list the aggregate already offered,
and a test asserts the emitted script contains no game vocabulary
6 the coverage gate crosses the language boundary: it walks the
serialized view for leaf paths and requires each token to appear in
the PARSED emitted document, with a test that the parse really is a
parse (script/style contents must not count as rendered)
The gate fired on its author again, on its first run: ground_choices.*.
choice, ground_choices.*.problem and players.*.blame_from were in neither
list. The last is the one worth keeping — an EMPTY vector is a leaf path
of its own, and it now renders as an explicit absence.
Also, a mutation that did not go red: removing the Sec-Fetch-Site arm
alone left the cross-site test green, because the Origin check caught it
independently. Both had to be removed before the control bit. Recorded
because a control that passes for a reason you did not intend has not
been demonstrated.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 04:27:25 +02:00
|
|
|
problems.insert(
|
|
|
|
|
7,
|
|
|
|
|
ProblemView::FaceUp {
|
|
|
|
|
suit: Suit::Change,
|
|
|
|
|
value: 6,
|
|
|
|
|
denied: true,
|
|
|
|
|
claimed_by: Some(p2),
|
|
|
|
|
protected_this_round: true,
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
GroundView {
|
|
|
|
|
viewer,
|
|
|
|
|
round: 3,
|
|
|
|
|
lead: p2,
|
|
|
|
|
step: RoundStep::Select,
|
|
|
|
|
mode: ScoringMode::BondedCoalitions,
|
CB-WP-0047: all four boards, and every mode named on the page
The modes were already implemented; nothing had ever COMPARED them. The
scenarios were not implemented at all: edition::deal has taken a
scenario_id since it was written and the only caller passed the literal
"SCN_01", so 15 of 20 Problem cards had never been dealt by anything.
The seam was the whole mechanism and it sat unused, with nothing red
because nothing asked.
Scenario is now state (serde default SCN_01, so all 26 recordings replay
unchanged), selected by preset `scn-03-4p` with `standard-Np` still
meaning SCN_01, and by --scenario/SCENARIO= accepting ids, numbers or
titles, validated against the edition rather than a pattern.
The threshold now comes off the Scenario card, closing F25's hardcoded
5/7/9. The first version of that control was worthless and mutation said
so: all four scenarios print 5/7/9, so reverting to the bands left it
green. Split threshold_from() so it can be handed a card that disagrees.
The header read `scoring CommonProblem` where the Mode card is titled
COMMON PROBLEM, PERSONAL EDGE -- the defect CB-WP-0034 deleted from the
move buttons, still standing on the line that says what winning means.
The coverage probe was matching that Debug output and went red when it
was fixed: third instance (CB-WP-0024, CB-WP-0034). Page now carries the
premise, the mode's rules text, and the tiebreak.
scenario-panel plays 4x3x3. Findings: SCN_01 and SCN_02 are the same
board (identical cells, pinned by a characterisation test); SCN_04 is
the hard board at 2p (52% vs 67/73%, the only deck needing two Repair);
and group success is EXACTLY equal across all three modes in all 36
cells, because greedy never reads state.mode -- filed F27, the two
competitive modes are scoring lenses over cooperative play.
F28: SHARED GROUND's mastery subtracts penalties from the claimed COUNT
where the mode card's shared score is claimed VALUE. Raised, not fixed;
scoring is ground-game's to rule on.
Also fixes design.py reporting a backticked path as no reproduction.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 20:51:46 +02:00
|
|
|
scenario: "SCN_03".into(),
|
CB-WP-0012-T04: cb-render-html — stage 1 draws, and the browser is the toolkit
Delivers ADR-0007 Decision 1: visualization, drag-to-propose and hot-seat
play, at a measured marginal AM-4a cost of zero.
games-ground shipped: 23 third-party crates
cb-render-html: 23 third-party crates
new crates introduced: 0
Measured, not asserted — the survey's own lesson. AM-4a is unmoved at
246,250; own source is 7,636 -> 9,652.
What shipped:
crates/cb-render-html doc.rs (HTML/SVG emission, incl. the relationship
graph), input.rs (pointer facts -> commands),
serve.rs (Guard, Request, loopback bind)
tools/cb-play hotseat.rs + `--serve PORT`
Per ADR-0007 Decision 2 there is NO cb-render-api and NO cb-render-null.
The renderer targets the existing Project trait; the port waits for
stage 2's wgpu implementation to be its second use.
The six controls, all live, all mutation-checked (8 mutations, each red
for its stated reason):
1-3 token / Origin+Sec-Fetch-Site / explicit 127.0.0.1 bind
4 a token-less request is refused, in the unit AND over a real socket
5 JS may not construct commands — the page reports pointer facts, Rust
resolves them against the legal list the aggregate already offered,
and a test asserts the emitted script contains no game vocabulary
6 the coverage gate crosses the language boundary: it walks the
serialized view for leaf paths and requires each token to appear in
the PARSED emitted document, with a test that the parse really is a
parse (script/style contents must not count as rendered)
The gate fired on its author again, on its first run: ground_choices.*.
choice, ground_choices.*.problem and players.*.blame_from were in neither
list. The last is the one worth keeping — an EMPTY vector is a leaf path
of its own, and it now renders as an explicit absence.
Also, a mutation that did not go red: removing the Sec-Fetch-Site arm
alone left the cross-site test green, because the Origin check caught it
independently. Both had to be removed before the control bit. Recorded
because a control that passes for a reason you did not intend has not
been demonstrated.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 04:27:25 +02:00
|
|
|
players,
|
|
|
|
|
relations: BTreeMap::from([
|
|
|
|
|
(Pair::new(p1, p2), Relation::Rivalry),
|
|
|
|
|
(Pair::new(p2, p3), Relation::Bond),
|
|
|
|
|
]),
|
|
|
|
|
problems,
|
2026-08-09 00:54:34 +02:00
|
|
|
config: games_ground::config::Configuration::default(),
|
CB-WP-0012-T04: cb-render-html — stage 1 draws, and the browser is the toolkit
Delivers ADR-0007 Decision 1: visualization, drag-to-propose and hot-seat
play, at a measured marginal AM-4a cost of zero.
games-ground shipped: 23 third-party crates
cb-render-html: 23 third-party crates
new crates introduced: 0
Measured, not asserted — the survey's own lesson. AM-4a is unmoved at
246,250; own source is 7,636 -> 9,652.
What shipped:
crates/cb-render-html doc.rs (HTML/SVG emission, incl. the relationship
graph), input.rs (pointer facts -> commands),
serve.rs (Guard, Request, loopback bind)
tools/cb-play hotseat.rs + `--serve PORT`
Per ADR-0007 Decision 2 there is NO cb-render-api and NO cb-render-null.
The renderer targets the existing Project trait; the port waits for
stage 2's wgpu implementation to be its second use.
The six controls, all live, all mutation-checked (8 mutations, each red
for its stated reason):
1-3 token / Origin+Sec-Fetch-Site / explicit 127.0.0.1 bind
4 a token-less request is refused, in the unit AND over a real socket
5 JS may not construct commands — the page reports pointer facts, Rust
resolves them against the legal list the aggregate already offered,
and a test asserts the emitted script contains no game vocabulary
6 the coverage gate crosses the language boundary: it walks the
serialized view for leaf paths and requires each token to appear in
the PARSED emitted document, with a test that the parse really is a
parse (script/style contents must not count as rendered)
The gate fired on its author again, on its first run: ground_choices.*.
choice, ground_choices.*.problem and players.*.blame_from were in neither
list. The last is the one worth keeping — an EMPTY vector is a leaf path
of its own, and it now renders as an explicit absence.
Also, a mutation that did not go red: removing the Sec-Fetch-Site arm
alone left the cross-site test green, because the Origin check caught it
independently. Both had to be removed before the control bit. Recorded
because a control that passes for a reason you did not intend has not
been demonstrated.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 04:27:25 +02:00
|
|
|
focus: BTreeMap::from([(p1, p3)]),
|
|
|
|
|
selections: BTreeMap::from([
|
|
|
|
|
(
|
|
|
|
|
p1,
|
|
|
|
|
SelectionView::Shown(Selection {
|
|
|
|
|
action: Action::Attack,
|
|
|
|
|
target: Some(p2),
|
|
|
|
|
problem: Some(7),
|
|
|
|
|
}),
|
|
|
|
|
),
|
|
|
|
|
(p2, SelectionView::Hidden),
|
2026-08-07 17:49:06 +02:00
|
|
|
// CB-WP-0034: P3 offered P2 their Support, revealed. The
|
|
|
|
|
// fixture now carries the case the report was about, so the
|
|
|
|
|
// coverage probe for `support_responses` can name a SEAT
|
|
|
|
|
// rather than a response with nobody attached to it.
|
|
|
|
|
(
|
|
|
|
|
p3,
|
|
|
|
|
SelectionView::Shown(Selection {
|
|
|
|
|
action: Action::Support,
|
|
|
|
|
target: Some(p2),
|
|
|
|
|
problem: None,
|
|
|
|
|
}),
|
|
|
|
|
),
|
CB-WP-0012-T04: cb-render-html — stage 1 draws, and the browser is the toolkit
Delivers ADR-0007 Decision 1: visualization, drag-to-propose and hot-seat
play, at a measured marginal AM-4a cost of zero.
games-ground shipped: 23 third-party crates
cb-render-html: 23 third-party crates
new crates introduced: 0
Measured, not asserted — the survey's own lesson. AM-4a is unmoved at
246,250; own source is 7,636 -> 9,652.
What shipped:
crates/cb-render-html doc.rs (HTML/SVG emission, incl. the relationship
graph), input.rs (pointer facts -> commands),
serve.rs (Guard, Request, loopback bind)
tools/cb-play hotseat.rs + `--serve PORT`
Per ADR-0007 Decision 2 there is NO cb-render-api and NO cb-render-null.
The renderer targets the existing Project trait; the port waits for
stage 2's wgpu implementation to be its second use.
The six controls, all live, all mutation-checked (8 mutations, each red
for its stated reason):
1-3 token / Origin+Sec-Fetch-Site / explicit 127.0.0.1 bind
4 a token-less request is refused, in the unit AND over a real socket
5 JS may not construct commands — the page reports pointer facts, Rust
resolves them against the legal list the aggregate already offered,
and a test asserts the emitted script contains no game vocabulary
6 the coverage gate crosses the language boundary: it walks the
serialized view for leaf paths and requires each token to appear in
the PARSED emitted document, with a test that the parse really is a
parse (script/style contents must not count as rendered)
The gate fired on its author again, on its first run: ground_choices.*.
choice, ground_choices.*.problem and players.*.blame_from were in neither
list. The last is the one worth keeping — an EMPTY vector is a leaf path
of its own, and it now renders as an explicit absence.
Also, a mutation that did not go red: removing the Sec-Fetch-Site arm
alone left the cross-site test green, because the Origin check caught it
independently. Both had to be removed before the control bit. Recorded
because a control that passes for a reason you did not intend has not
been demonstrated.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 04:27:25 +02:00
|
|
|
]),
|
CB-WP-0043: a Problem sits where its Stress lands
The picture had become a lie. A row across the middle says "these are the
table's" — true under the baseline, false under H2, where three of five
cards fall on particular seats.
Global goes to the middle, personal beside its owner, and bond on the mean
midpoint of the owner's Bond edges. A bond Problem whose owner has no Bond
is drawn as personal, because that is the rule — bond_network falls back
to the owner at degree 0 — and the picture must agree with the arithmetic.
The baseline page is untouched: the scoped layout is taken only when a
non-global scope exists, so every prior look at the baseline still holds.
The scope reaches the view as a separate marker rather than a field on
ProblemView, because the delta says "place owner marker on the card" — a
token beside a card — and it is public while the card is face down, which
a ProblemView variant could not express.
The coverage probe forced a real improvement. It demanded a text token for
the new fields and a POSITION is not a token — which is the probe being
right: position alone is invisible to text_of and to a screen reader, and
illegible when two anchors coincide. So each scoped Problem now says whose
it is: everyone's, P1's alone, P2's Bond network, and "P1's alone — no
Bond to share it" at degree 0.
The fixture gained a third Problem. With two, one of the three placement
rules was unexercised and the probe unsatisfiable — a fixture that cannot
reach a branch is how a rule ships untested.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 17:30:14 +02:00
|
|
|
// CB-WP-0043: the fixture carries H2 markers, so the scoped
|
|
|
|
|
// layout is exercised — a fixture with none would leave the new
|
|
|
|
|
// placement untested and the row layout would always be taken.
|
|
|
|
|
problem_markers: BTreeMap::from([
|
|
|
|
|
(
|
|
|
|
|
1,
|
|
|
|
|
games_ground::view::ProblemMarker {
|
|
|
|
|
owner: None,
|
|
|
|
|
scope: Some(games_ground::edition::StressScope::Global),
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
(
|
|
|
|
|
6,
|
|
|
|
|
games_ground::view::ProblemMarker {
|
|
|
|
|
owner: Some(p1),
|
|
|
|
|
scope: Some(games_ground::edition::StressScope::Personal),
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
(
|
|
|
|
|
7,
|
|
|
|
|
games_ground::view::ProblemMarker {
|
|
|
|
|
owner: Some(p2),
|
|
|
|
|
scope: Some(games_ground::edition::StressScope::Bond),
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
]),
|
CB-WP-0012-T04: cb-render-html — stage 1 draws, and the browser is the toolkit
Delivers ADR-0007 Decision 1: visualization, drag-to-propose and hot-seat
play, at a measured marginal AM-4a cost of zero.
games-ground shipped: 23 third-party crates
cb-render-html: 23 third-party crates
new crates introduced: 0
Measured, not asserted — the survey's own lesson. AM-4a is unmoved at
246,250; own source is 7,636 -> 9,652.
What shipped:
crates/cb-render-html doc.rs (HTML/SVG emission, incl. the relationship
graph), input.rs (pointer facts -> commands),
serve.rs (Guard, Request, loopback bind)
tools/cb-play hotseat.rs + `--serve PORT`
Per ADR-0007 Decision 2 there is NO cb-render-api and NO cb-render-null.
The renderer targets the existing Project trait; the port waits for
stage 2's wgpu implementation to be its second use.
The six controls, all live, all mutation-checked (8 mutations, each red
for its stated reason):
1-3 token / Origin+Sec-Fetch-Site / explicit 127.0.0.1 bind
4 a token-less request is refused, in the unit AND over a real socket
5 JS may not construct commands — the page reports pointer facts, Rust
resolves them against the legal list the aggregate already offered,
and a test asserts the emitted script contains no game vocabulary
6 the coverage gate crosses the language boundary: it walks the
serialized view for leaf paths and requires each token to appear in
the PARSED emitted document, with a test that the parse really is a
parse (script/style contents must not count as rendered)
The gate fired on its author again, on its first run: ground_choices.*.
choice, ground_choices.*.problem and players.*.blame_from were in neither
list. The last is the one worth keeping — an EMPTY vector is a leaf path
of its own, and it now renders as an explicit absence.
Also, a mutation that did not go red: removing the Sec-Fetch-Site arm
alone left the cross-site test green, because the Origin check caught it
independently. Both had to be removed before the control bit. Recorded
because a control that passes for a reason you did not intend has not
been demonstrated.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 04:27:25 +02:00
|
|
|
ground_modes: BTreeMap::from([(p3, GroundMode::Gr)]),
|
|
|
|
|
ground_choices: BTreeMap::from([(p3, GroundChoice::ProtectProblem { problem: 7 })]),
|
|
|
|
|
support_responses: BTreeMap::from([(p2, SupportResponse::AcceptBond)]),
|
|
|
|
|
darvo_targets: BTreeMap::from([(
|
|
|
|
|
p3,
|
|
|
|
|
DarvoTarget {
|
|
|
|
|
problem: Some(1),
|
|
|
|
|
player: Some(p2),
|
|
|
|
|
},
|
|
|
|
|
)]),
|
|
|
|
|
solution_deck_len: 17,
|
|
|
|
|
solution_discard: vec![card(Suit::Repair), card(Suit::Change)],
|
|
|
|
|
outcome: Some(OutcomeView {
|
|
|
|
|
total: 9,
|
|
|
|
|
threshold: 12,
|
|
|
|
|
group_success: false,
|
|
|
|
|
personal: BTreeMap::from([(p1, 3), (p2, -1), (p3, 0)]),
|
|
|
|
|
coalitions: vec![Coalition {
|
|
|
|
|
members: vec![p2, p3],
|
|
|
|
|
score: 4,
|
|
|
|
|
}],
|
|
|
|
|
mastery: Some(1),
|
|
|
|
|
winners: vec![p1],
|
|
|
|
|
}),
|
|
|
|
|
}
|
|
|
|
|
}
|