Bots that play on alone do it at a pace to watch, a round every two seconds after the first few, and a seat may hurry them to the end

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:19:38 -04:00
co-authored by Claude Opus 5.5
parent 99a0b23f59
commit 403232087d
8 changed files with 120 additions and 3 deletions
+6
View File
@@ -54,6 +54,12 @@
{#each room.view.parting as last, i (i)}<p><em>{room.nameOf(last.id)}</em> {last.text}</p>{/each}
<a class="commit" href="/">Back to the hall</a>
</div>
{:else if room.view.playingOn}
<section class="move">
<h2>The bots play on</h2>
<p class="muted">Nobody else owes a move, so the bots play a round every few seconds for you to watch.</p>
{#if !room.spectating}<button type="button" class="quiet" onclick={() => room.hurry()}>Play the rest at once</button>{/if}
</section>
{:else if room.spectating}
<section class="move">
<h2>You watch from the Peanut Gallery</h2>
+1
View File
@@ -132,6 +132,7 @@ export function makeApi<State, Input>() {
/** The gallery's view: no token, no seat, nothing any player could not see. */
watch: (roomId: string) => call<View>('GET', `/api/rooms/${roomId}`),
turn: (roomId: string, token: string, input: Input, resolved: number) => call<View>('POST', `/api/rooms/${roomId}/turn`, { token, input, resolved }),
hurry: (roomId: string, token: string) => call<View>('POST', `/api/rooms/${roomId}/hurry`, { token }),
rank: (roomId: string, token: string, ranking: string[]) => call<View>('POST', `/api/rooms/${roomId}/rank`, { token, ranking }),
say: (roomId: string, token: string, text: string, to?: SeatId[]) => call<View>('POST', `/api/rooms/${roomId}/say`, { token, text, ...(to?.length ? { to } : {}) }),
/** A word from the gallery, signed with a name, when the host allows it. */
+5
View File
@@ -112,6 +112,11 @@ export class Room {
return this.act(() => api.unseat(this.roomId, this.token, seat), 'The bot could not be sent away.');
}
/** Out of the game, with the bots playing on: play the rest at once. */
hurry(): Promise<boolean> {
return this.act(() => api.hurry(this.roomId, this.token), 'The table did not hear you.');
}
/** This seat's ranking of the table's choices, best first, before the game begins. */
rank(ranking: string[]): Promise<boolean> {
return this.act(() => api.rank(this.roomId, this.token, ranking), 'Your ranking was not kept.');
+2
View File
@@ -46,6 +46,8 @@ export interface RoomView<State> {
chat: ChatLine[];
/** The bots' last words to this seat once the game is over, for a game that gives them some. */
parting: { id: SeatId; text: string }[];
/** The bots are playing on by themselves, a round at a time, with no person owing a move. */
playingOn: boolean;
/** How many watch from the Peanut Gallery. */
audience: number;
/** The host lets the gallery talk. */