[wip] im tired boss

This commit is contained in:
2025-08-30 15:49:55 -04:00
parent 5e33e33cce
commit 782dd738cc
5 changed files with 155 additions and 127 deletions

View File

@@ -1,8 +1,6 @@
import * as renaissance from "./renaissance";
import simple from "./simple";
export type Game<
C extends { game: string } = { game: string },
S = unknown,
A extends { humanKey: string } = { humanKey: string },
E extends { error: any } = { error: any },
@@ -10,16 +8,18 @@ export type Game<
> = {
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;
init: () => S;
resolveAction: (p: { state: S; action: A }) => S | E;
getView: (p: { state: S; humanKey: string }) => V;
resolveQuit: (p: { state: S; humanKey: string }) => S;
};
export const GAMES = {
// renaissance,
simple,
} satisfies { [key: string]: Game<any, any, any, any, any> };
} satisfies {
[key: string]: (config: { game: string; players: string[] }) => Game;
};
export default GAMES;
export type GameKey = keyof typeof GAMES;

View File

@@ -22,7 +22,10 @@ export type SimplePlayerView = {
myHand: Hand<Card>;
};
export type SimpleAction = { type: "draw" } | { type: "discard"; card: Card };
export type SimpleAction = { humanKey: string } & (
| { type: "draw" }
| { type: "discard"; card: Card }
);
export const newSimpleGameState = (
config: SimpleConfiguration
@@ -55,14 +58,13 @@ export const getSimplePlayerView = (
export const resolveSimpleAction = ({
config,
state,
humanKey,
action,
}: {
config: SimpleConfiguration;
state: SimpleGameState;
humanKey: string;
action: SimpleAction;
}): SimpleGameState => {
const { humanKey } = action;
const playerHand = state.playerHands[humanKey];
if (playerHand == null) {
throw new Error(
@@ -105,18 +107,18 @@ 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
>;
export default (config: SimpleConfiguration) =>
({
title: "Simple",
rules: "You can draw, or you can discard. Then your turn is up.",
init: () => newSimpleGameState(config),
resolveAction: (p) => resolveSimpleAction({ ...p, config }),
getView: ({ state, humanKey }) =>
getSimplePlayerView(config, state, humanKey),
resolveQuit: () => null,
} satisfies Game<
SimpleGameState,
SimpleAction,
SimpleError,
SimplePlayerView
>);

View File

@@ -1,12 +1,18 @@
import { merge, Observable } from "kefir";
export const transform = <
T,
Mutations extends [Observable<any, any>, (prev: T, evt: any) => T][]
>(
initValue: T,
...mutations: Mutations
): Observable<T, unknown> =>
export type ValueWithin<O extends Observable<any, any>> = Parameters<
Parameters<O["map"]>[0]
>[0];
type Mutation<A, O extends Observable<any, any>> = [
O,
(prev: A, value: ValueWithin<O>) => A
];
export const multiScan = <A, M extends Mutation<A, any>[]>(
initValue: A,
...mutations: M
): Observable<A, any> =>
merge(
mutations.map(([source, mutation]) =>
source.map((event) => ({ event, mutation }))
@@ -27,3 +33,5 @@ export const partition =
])
);
};
export const isEmpty = (container: { length: number }) => container.length == 0;