Skip to content

Commit 0a7f30d

Browse files
committed
Canoe: Stymie roll blank while emulated
1 parent 88c3988 commit 0a7f30d

2 files changed

Lines changed: 38 additions & 2 deletions

File tree

src/games/canoe.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,15 @@ export class CanoeGame extends GameBase {
845845
return used ? `U${slot}` : `D${slot}`;
846846
}
847847

848+
/** Stymie roll preview: local roll values are not authoritative until persisted. */
849+
private showEmulatedStymieRollDice(): boolean {
850+
if (!this.emulated || this.roll === undefined || this.phase !== "play") {
851+
return false;
852+
}
853+
const top = this.stack[this.stack.length - 1];
854+
return top.roll === undefined;
855+
}
856+
848857
private dieSlotIndex(cell?: string, piece?: string): number | undefined {
849858
if (this.roll === undefined) {
850859
return undefined;
@@ -2605,11 +2614,13 @@ export class CanoeGame extends GameBase {
26052614
];
26062615
}
26072616
if (this.phase === "play" && this.roll !== undefined) {
2617+
const emptyDice = this.showEmulatedStymieRollDice();
26082618
for (let idx = 0; idx < this.roll.length && idx < CanoeGame.DICE_CELLS.length; idx++) {
26092619
const val = this.roll[idx];
26102620
const slot = idx + 1;
2611-
legend[`D${slot}`] = {name: `d6-${val}`, opacity: 1};
2612-
legend[`U${slot}`] = {name: `d6-${val}`, opacity: 0.5};
2621+
const dieName = emptyDice ? "d6-empty" : `d6-${val}`;
2622+
legend[`D${slot}`] = {name: dieName, opacity: 1};
2623+
legend[`U${slot}`] = {name: dieName, opacity: 0.5};
26132624
}
26142625
}
26152626

test/games/canoe.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,31 @@ describe("Canoe", () => {
452452
expect(rep.legend?.D2).to.deep.equal({name: "d6-5", opacity: 1});
453453
});
454454

455+
it("emulated stymie roll shows empty dice until roll is persisted", () => {
456+
const g = playFixture([
457+
["c3", {owner: 1, face: 8}],
458+
["c6", {owner: 1, face: 8}],
459+
]);
460+
g.move("roll:1", {emulation: true});
461+
const rep = g.render();
462+
expect(rep.legend?.D1).to.deep.equal({name: "d6-empty", opacity: 1});
463+
expect(rep.legend?.D2).to.equal(undefined);
464+
const [f2Row, f2Col] = clickCell("f2");
465+
const pstr = rep.pieces as string;
466+
expect(pstr.split("\n")[f2Row].split(",")[f2Col]).to.equal("D1");
467+
});
468+
469+
it("emulated stymie roll:2 shows two empty dice", () => {
470+
const g = playFixture([
471+
["c3", {owner: 1, face: 8}],
472+
["c6", {owner: 1, face: 8}],
473+
]);
474+
g.move("roll:2", {emulation: true});
475+
const rep = g.render();
476+
expect(rep.legend?.D1).to.deep.equal({name: "d6-empty", opacity: 1});
477+
expect(rep.legend?.D2).to.deep.equal({name: "d6-empty", opacity: 1});
478+
});
479+
455480
it("partial die selection keeps dice pips visible when emulated", () => {
456481
const g = playFixture([
457482
["e5", {owner: 1, face: 16}],

0 commit comments

Comments
 (0)