diff --git a/src/lib/components/Hall.svelte b/src/lib/components/Hall.svelte index b57f3bc..1635fba 100644 --- a/src/lib/components/Hall.svelte +++ b/src/lib/components/Hall.svelte @@ -32,6 +32,20 @@ }); async function playBot() { + busy = true; + error = ''; + try { + rememberName(name); + const remote = await Duel.createBotRoom(name.trim()); + await goto(`/join/${remote.roomId}`); + } catch (e) { + error = e instanceof Error ? e.message : 'The duel could not be opened.'; + } finally { + busy = false; + } + } + + async function playOffline() { rememberName(name); await goto('/play'); } @@ -66,7 +80,7 @@ const g = games[held.roomId]; if (g === undefined) return 'looking'; if (g === null) return 'unreachable'; - const others = g.seats.filter((s) => s.id !== held.seat).map((s) => s.name); + const others = g.seats.filter((s) => s.id !== held.seat).map((s) => (s.bot ? `${s.name} (the bot)` : s.name)); if (!g.state) return `waiting to start${g.seats.length ? ` · ${g.seats.map((s) => s.name).join(', ')}` : ''}`; if (g.state.over) { if (g.state.over.winner === held.seat) return 'you won'; @@ -105,12 +119,14 @@ Your wizard's name - - {#if local} -

Or start afresh from the board's "New duel".

- {/if} + +

+ {#if local} + + {:else} + + {/if} +

@@ -149,8 +165,8 @@ {#if local} {/if} diff --git a/src/lib/game/duel.svelte.ts b/src/lib/game/duel.svelte.ts index 1049c94..507180c 100644 --- a/src/lib/game/duel.svelte.ts +++ b/src/lib/game/duel.svelte.ts @@ -794,6 +794,13 @@ export class Duel { return remoteFrom(seated.view, seated.token); } + /** A room with the bot already seated: a duel the server keeps, so it can be replayed and seen. */ + static async createBotRoom(name: string): Promise { + const seated = await api.create(name, 2); + rememberSeat(seated.view.roomId, { seat: seated.seat, token: seated.token }); + return remoteFrom(await api.addBot(seated.view.roomId, seated.token), seated.token); + } + static async joinRoom(roomId: string, name: string): Promise { const seated = await api.join(roomId, name); rememberSeat(roomId, { seat: seated.seat, token: seated.token });