end to end!
This commit is contained in:
@@ -62,31 +62,6 @@ const api = new Elysia({ prefix: "/api" })
|
||||
)
|
||||
.get("/games", () => [{ key: "simple", name: "simple" }])
|
||||
.ws("/ws/:tableKey", {
|
||||
response: WsOut,
|
||||
body: WsIn,
|
||||
|
||||
message(
|
||||
{
|
||||
data: {
|
||||
humanKey,
|
||||
params: { tableKey },
|
||||
},
|
||||
},
|
||||
body
|
||||
) {
|
||||
const {
|
||||
inputs: { gameProposals, gameStarts, gameActions },
|
||||
} = liveTable(tableKey);
|
||||
|
||||
if ("proposeGame" in body) {
|
||||
gameProposals.emit(body);
|
||||
} else if ("startGame" in body) {
|
||||
gameStarts.emit(body);
|
||||
} else if ("action" in body) {
|
||||
gameActions.emit(body);
|
||||
}
|
||||
},
|
||||
|
||||
async open({
|
||||
data: {
|
||||
params: { tableKey },
|
||||
@@ -108,6 +83,32 @@ const api = new Elysia({ prefix: "/api" })
|
||||
);
|
||||
table.inputs.presenceChanges.emit({ humanKey, presence: "joined" });
|
||||
},
|
||||
|
||||
response: WsOut,
|
||||
body: WsIn,
|
||||
|
||||
message(
|
||||
{
|
||||
data: {
|
||||
humanKey,
|
||||
params: { tableKey },
|
||||
},
|
||||
},
|
||||
body
|
||||
) {
|
||||
const {
|
||||
inputs: { gameProposals, gameStarts, gameActions },
|
||||
} = liveTable(tableKey);
|
||||
|
||||
if ("proposeGame" in body) {
|
||||
gameProposals.emit(body);
|
||||
} else if ("startGame" in body) {
|
||||
gameStarts.emit(body);
|
||||
} else if ("action" in body) {
|
||||
gameActions.emit({ humanKey, ...body.action });
|
||||
}
|
||||
},
|
||||
|
||||
async close({
|
||||
data: {
|
||||
params: { tableKey },
|
||||
|
||||
@@ -71,9 +71,16 @@ export const resolveAction = (
|
||||
humanId: string,
|
||||
action: SimpleAction
|
||||
): SimpleGameState => {
|
||||
console.log("attempting to resolve action", JSON.stringify(action));
|
||||
if (!(humanId in state.players)) {
|
||||
throw Error(
|
||||
`${humanId} is not a player in this game; they cannot perform actions`
|
||||
);
|
||||
}
|
||||
const playerHand = state.players[humanId];
|
||||
if (action.type == "draw") {
|
||||
const [drawn, ...rest] = state.deck;
|
||||
console.log("drew card", JSON.stringify(drawn));
|
||||
return {
|
||||
deck: rest,
|
||||
players: {
|
||||
|
||||
@@ -21,15 +21,16 @@ export const WsIn = t.Union([
|
||||
]);
|
||||
export type TWsIn = typeof WsIn.static;
|
||||
|
||||
type Attributed = { humanKey: string };
|
||||
type TablePayload<GameState, GameAction> = {
|
||||
inputs: {
|
||||
presenceChanges: TBus<
|
||||
{ humanKey: string; presence: "joined" | "left" },
|
||||
Attributed & { presence: "joined" | "left" },
|
||||
never
|
||||
>;
|
||||
gameProposals: TBus<{ proposeGame: string }, never>;
|
||||
gameStarts: TBus<{ startGame: true }, never>;
|
||||
gameActions: TBus<GameAction, never>;
|
||||
gameActions: TBus<Attributed & GameAction, never>;
|
||||
};
|
||||
outputs: {
|
||||
playersPresent: Property<string[], never>;
|
||||
@@ -63,26 +64,22 @@ export const liveTable = <GameState, GameAction>(key: string) => {
|
||||
}, [] as string[]);
|
||||
|
||||
const gameState = transform(
|
||||
null as GameState | null,
|
||||
null as SimpleGameState | null,
|
||||
[
|
||||
gameStarts.thru((Evt) =>
|
||||
combine([Evt], [playersPresent], (evt, players) => ({
|
||||
...evt,
|
||||
players,
|
||||
}))
|
||||
),
|
||||
combine([gameStarts], [playersPresent], (evt, players) => ({
|
||||
...evt,
|
||||
players,
|
||||
})),
|
||||
(prev, evt: { players: string[] }) =>
|
||||
prev == null ? (newGame(evt.players) as GameState) : prev,
|
||||
prev == null
|
||||
? (newGame(evt.players) as SimpleGameState)
|
||||
: prev,
|
||||
],
|
||||
[
|
||||
gameActions,
|
||||
(prev, evt: GameAction) =>
|
||||
(prev, evt: Attributed & SimpleAction) =>
|
||||
prev != null
|
||||
? (resolveAction(
|
||||
prev as unknown as SimpleGameState,
|
||||
"evt",
|
||||
evt as SimpleAction
|
||||
) as GameState)
|
||||
? resolveAction(prev, evt.humanKey, evt)
|
||||
: prev,
|
||||
]
|
||||
).toProperty();
|
||||
|
||||
Reference in New Issue
Block a user