starting to abstract the game
This commit is contained in:
@@ -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 "
|
||||
|
||||
@@ -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%)",
|
||||
},
|
||||
],
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
@@ -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({
|
||||
|
||||
25
packages/shared/games/index.ts
Normal file
25
packages/shared/games/index.ts
Normal 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;
|
||||
@@ -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
|
||||
>;
|
||||
Reference in New Issue
Block a user