A settled move may be taken back as a draft while the round still waits on others
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
af25b672f1
commit
59494aa29f
@@ -62,7 +62,9 @@ describe('rooms', () => {
|
||||
expect(room.resolved).toBe(1);
|
||||
expect(room.state!.rounds[0].picks).toEqual({ A: 3, B: 2 });
|
||||
rooms.submit(room, bo, { pick: 1, final: true }, 1);
|
||||
expect(() => rooms.submit(room, bo, { pick: 2 }, 1)).toThrow(/not your move/);
|
||||
expect(() => rooms.submit(room, bo, { pick: 2, final: true }, 1)).toThrow(/already in/);
|
||||
rooms.submit(room, bo, { pick: 2 }, 1);
|
||||
expect(rooms.waitingOn(room)).toEqual(['A', 'B']);
|
||||
});
|
||||
|
||||
it("shows a seat its own move in waiting and its last move played, and nobody else's", () => {
|
||||
|
||||
@@ -430,7 +430,8 @@ export class Rooms<State, Input> {
|
||||
|
||||
/**
|
||||
* Record a seat's move on the ledger, so a restart keeps it; resolve the round once nobody else is awaited.
|
||||
* A draft (an input the game does not call settled) may be replaced until it is settled.
|
||||
* A draft (an input the game does not call settled) may be replaced, and a settled move taken back
|
||||
* as a draft, until the round resolves.
|
||||
* `resolved` is how many rounds the page had seen played when the move was made: a move that
|
||||
* arrives after its round was played (a slow connection, a second click, a stale tab) is refused
|
||||
* rather than taken as the move for the next round.
|
||||
@@ -442,8 +443,10 @@ export class Rooms<State, Input> {
|
||||
if (typeof resolved !== 'number') throw new RoomError('This page is out of date. Reload it to see the table as it stands.', 409);
|
||||
if (resolved !== room.resolved) throw new RoomError('That move was made for a turn that has already been played. Your page will catch up.', 409);
|
||||
|
||||
if (!this.waitingOn(room).includes(seat.id)) throw new RoomError('It is not your move.', 409);
|
||||
if (!this.game.needsInput(room.state, seat.id)) throw new RoomError('It is not your move.', 409);
|
||||
const input = this.game.cleanInput(raw);
|
||||
// A settled move is final; a draft may replace it while the round still waits on others.
|
||||
if (seat.id in room.pending && this.settled(room.pending[seat.id]) && this.settled(input)) throw new RoomError('Your move is already in.', 409);
|
||||
const why = this.game.validate?.(room.state, seat.id, input);
|
||||
if (why) throw new RoomError(why);
|
||||
this.commit(room, { t: 'input', at: Date.now(), id: seat.id, input });
|
||||
|
||||
Reference in New Issue
Block a user