Browse Source

fix(chase): align endgame text and round transition semantics

Made-with: Cursor
master
npmrun 2 weeks ago
parent
commit
fdffd8c3d8
  1. 2
      src/stages/page_chase.ts
  2. 40
      tests/chase/chaseModel.test.ts
  3. 6
      tests/stages/page_chase.test.ts

2
src/stages/page_chase.ts

@ -452,7 +452,7 @@ export default class ChaseScene extends BaseScene {
return;
}
this.resultText.text = loseReason === "trapped" ? "无路可走" : "被抓住";
this.resultText.text = loseReason === "trapped" ? "你已无路可走" : "被抓住";
this.restartButton.visible = false;
this.retryButton.visible = true;
this.newGameButton.visible = true;

40
tests/chase/chaseModel.test.ts

@ -173,6 +173,23 @@ describe("chase game model", () => {
expect(mockedGenerateChaseRound).toHaveBeenCalledTimes(1);
});
it("retryRound keeps exactly same graph and start positions", () => {
mockedGenerateChaseRound.mockReturnValueOnce(makeRound(88, "normal"));
const model = ChaseGameModel.createWithSeed({ seed: 88, difficulty: "normal" });
const initial = model.getState().snapshot;
model.moveThief("A");
model.retryRound();
const retried = model.getState().snapshot;
expect(retried.graph).toEqual(initial.graph);
expect(retried.thiefStartNodeId).toBe(initial.thiefStartNodeId);
expect(retried.guardStartNodeId).toBe(initial.guardStartNodeId);
expect(retried.exitNodeId).toBe(initial.exitNodeId);
expect(retried.thiefNodeId).toBe(initial.thiefNodeId);
expect(retried.guardNodeId).toBe(initial.guardNodeId);
});
it("newRound switches seed/difficulty and keeps winCount", () => {
mockedGenerateChaseRound
.mockReturnValueOnce(makeRound(55, "easy"))
@ -204,6 +221,29 @@ describe("chase game model", () => {
expect(state.snapshot.difficulty).toBe("easy");
});
it("newRound with new seed produces a new round snapshot", () => {
const base = makeRound(300, "normal");
const next = makeRound(301, "normal");
next.snapshot.graph.nodes.E = { id: "E", q: 4, r: 0, neighbors: [] };
next.snapshot.thiefStartNodeId = "A";
next.snapshot.guardStartNodeId = "C";
next.snapshot.exitNodeId = "D";
next.snapshot.thiefNodeId = "A";
next.snapshot.guardNodeId = "C";
mockedGenerateChaseRound.mockReturnValueOnce(base).mockReturnValueOnce(next);
const model = ChaseGameModel.createWithSeed({ seed: 300, difficulty: "normal" });
const before = model.getState().snapshot;
model.newRound(301, "normal");
const after = model.getState().snapshot;
expect(after.seed).toBe(301);
expect(after).not.toEqual(before);
expect(Object.keys(after.graph.nodes)).toContain("E");
expect(after.thiefStartNodeId).toBe("A");
});
it("retryRound resets rng so same move sequence is reproducible", () => {
const easyRound = {
snapshot: {

6
tests/stages/page_chase.test.ts

@ -295,6 +295,7 @@ describe("chase stage skeleton", () => {
model: { getState, moveThief: vi.fn(), newRound, retryRound: vi.fn() } as any,
});
void (scene as any).onSceneLayout();
(scene as any).difficultyButtons.hard.emit("pointerdown");
expect((scene as any).resultOverlay.visible).toBe(true);
expect((scene as any).resultText.text).toContain("成功逃脱");
@ -302,6 +303,7 @@ describe("chase stage skeleton", () => {
(scene as any).restartButton.emit("pointerdown");
(scene as any).restartButton.emit("pointerdown");
expect(newRound).toHaveBeenCalledTimes(1);
expect(newRound.mock.calls[0][1]).toBe("hard");
});
it("shows lose overlay and retry/new buttons call correct model methods", () => {
@ -324,7 +326,7 @@ describe("chase stage skeleton", () => {
} as any,
});
void (retryScene as any).onSceneLayout();
expect((retryScene as any).resultText.text).toContain("无路可走");
expect((retryScene as any).resultText.text).toContain("你已无路可走");
(retryScene as any).retryButton.emit("pointerdown");
(retryScene as any).retryButton.emit("pointerdown");
expect(retryRound).toHaveBeenCalledTimes(1);
@ -339,8 +341,10 @@ describe("chase stage skeleton", () => {
} as any,
});
void (newGameScene as any).onSceneLayout();
(newGameScene as any).difficultyButtons.easy.emit("pointerdown");
(newGameScene as any).newGameButton.emit("pointerdown");
(newGameScene as any).newGameButton.emit("pointerdown");
expect(newRound).toHaveBeenCalledTimes(1);
expect(newRound.mock.calls[0][1]).toBe("easy");
});
});

Loading…
Cancel
Save