A seat's view carries its own move in waiting and its move in the last round it played

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
This commit is contained in:
Eric Wagoner
2026-09-29 12:15:05 -04:00
co-authored by Claude Opus 5.5
parent 927e49cf79
commit 8e35d3a3a6
4 changed files with 28 additions and 2 deletions
+7 -1
View File
@@ -48,6 +48,8 @@ export interface Room<State> {
state: State | null;
/** Inputs received for the round in progress, by seat. */
pending: Record<SeatId, unknown>;
/** Each seat's input in the last round it played, kept through rounds it had no part in; each seat is shown only its own. */
played: Record<SeatId, unknown>;
chat: ChatLine[];
/** Rounds played so far; a move names the count it was made against. */
resolved: number;
@@ -192,7 +194,7 @@ export class Rooms<State, Input> {
/** A table with nobody seated yet. */
private blank(id: string, size: number, createdAt: number, rematchOf: string | null, expected: string[], options: TableOptions, seq = 0): Room<State> {
return { id, size, createdAt, seats: [], galleryTalk: false, challenge: null, expected, rematch: null, rematchOf, options, over: false, state: null, pending: {}, chat: [], resolved: 0, seq, updatedAt: createdAt };
return { id, size, createdAt, seats: [], galleryTalk: false, challenge: null, expected, rematch: null, rematchOf, options, over: false, state: null, pending: {}, played: {}, chat: [], resolved: 0, seq, updatedAt: createdAt };
}
/** Open a table with its first seat taken; a rematch names the table it follows and holds seats for its players. */
@@ -418,6 +420,7 @@ export class Rooms<State, Input> {
/** The view for a seat, or for the gallery when the seat is SPECTATOR. */
view(room: Room<State>, seatId: SeatId): RoomView<State> {
const seated = seatId !== SPECTATOR;
return {
roomId: room.id,
seq: room.seq,
@@ -430,6 +433,8 @@ export class Rooms<State, Input> {
resolved: room.resolved,
over: room.state ? this.game.over(room.state) : null,
state: room.state ? this.game.view(room.state, seatId) : null,
yourInput: seated && seatId in room.pending ? room.pending[seatId] : null,
yourLastInput: seated && seatId in room.played ? room.played[seatId] : null,
chat: room.chat,
audience: this.gallery.get(room.id) ?? 0,
galleryTalk: room.galleryTalk,
@@ -512,6 +517,7 @@ export class Rooms<State, Input> {
case 'turn':
if (!room.state) return;
room.state = this.game.resolve(room.state, line.inputs as Record<SeatId, Input>);
room.played = { ...room.played, ...(line.inputs as Record<SeatId, unknown>) };
room.pending = {};
room.resolved += 1;
break;