starting to abstract the game

This commit is contained in:
2025-08-28 22:20:24 -04:00
parent d69336027a
commit 0d6d3d6d32
8 changed files with 59 additions and 21 deletions

View File

@@ -14,6 +14,7 @@ import { createObservable, createObservableWithInit, cx } from "~/fn";
import { me, mePromise } from "~/profile";
import Game from "./Game";
import Player from "./Player";
import games from "@games/shared/games/index";
export const TableContext = createContext<{
view: Accessor<any>;
@@ -110,7 +111,14 @@ export default (props: { tableKey: string }) => {
}}
>
<Show when={view() == null}>
<div class="absolute center">
<div class="absolute tc mt-8 flex gap-4">
<select>
<For each={Object.entries(games)}>
{([gameId, game]) => (
<option value={gameId}>{game.title}</option>
)}
</For>
</select>
<button
onClick={() => setReady((prev) => !prev)}
class="button p-1 "

View File

@@ -25,20 +25,16 @@ export default defineConfig({
"bc",
{
bottom: 0,
left: 0,
right: 0,
"margin-left": "auto",
"margin-right": "auto",
left: "50%",
transform: "translateX(-50%)",
},
],
[
"tc",
{
top: 0,
left: 0,
right: 0,
"margin-left": "auto",
"margin-right": "auto",
left: "50%",
transform: "translateX(-50%)",
},
],

View File

@@ -4,7 +4,7 @@ import {
SimpleAction,
SimpleConfiguration,
SimpleGameState,
} from "./games/simple";
} from "@games/shared/games/simple";
import { human } from "./human";
import dayjs from "dayjs";
import db from "./db";

View File

@@ -1,10 +0,0 @@
import * as renaissance from "./renaissance";
import * as simple from "./simple";
const games = {
renaissance,
simple,
};
export default games;
export type Game = keyof typeof games;

View File

@@ -7,7 +7,7 @@ import {
SimpleAction,
SimpleConfiguration,
SimpleGameState,
} from "./games/simple";
} from "@games/shared/games/simple";
import { transform } from "./kefir-extension";
export const WsOut = t.Object({

View File

@@ -0,0 +1,25 @@
import * as renaissance from "./renaissance";
import simple from "./simple";
export type Game<
C extends { game: string },
S,
A,
E extends { error: any },
V
> = {
title: string;
rules: string;
init: (config: C) => S;
resolveAction: (p: { config: C; state: S; action: A }) => S | E;
getView: (p: { config: C; state: S; humanKey: string }) => V;
resolveQuit: (p: { config: C; state: S; humanKey: string }) => S;
};
const games = {
// renaissance,
simple,
} satisfies { [key: string]: Game<any, any, any, any, any> };
export default games;
export type GameId = keyof typeof games;

View File

@@ -1,5 +1,6 @@
import { Card, Hand, newDeck, Pile, shuffle, vCard } from "@games/shared/cards";
import { heq } from "@games/shared/utils";
import type { Game } from ".";
export type SimpleConfiguration = {
game: "simple";
@@ -101,3 +102,21 @@ export const resolveSimpleAction = ({
};
}
};
type SimpleError = { error: "whoops!" };
export default {
title: "Simple",
rules: "You can draw, or you can discard. Then your turn is up.",
init: newSimpleGameState,
resolveAction: resolveSimpleAction,
getView: ({ config, state, humanKey }) =>
getSimplePlayerView(config, state, humanKey),
resolveQuit: () => null,
} satisfies Game<
SimpleConfiguration,
SimpleGameState,
SimpleAction,
SimpleError,
SimplePlayerView
>;