closer
This commit is contained in:
@@ -6,7 +6,6 @@ import {
|
||||
shuffle,
|
||||
vCard,
|
||||
} from "../../../shared/cards";
|
||||
import hash from "object-hash";
|
||||
import { heq } from "../../../shared/utils";
|
||||
import { Elysia, t } from "elysia";
|
||||
import { prisma } from "../db/db";
|
||||
@@ -14,7 +13,6 @@ import { prisma } from "../db/db";
|
||||
// omniscient game state
|
||||
export type GameState = {
|
||||
prev?: {
|
||||
hash: string;
|
||||
action: Action;
|
||||
};
|
||||
|
||||
@@ -41,14 +39,15 @@ export type PlayerView = {
|
||||
|
||||
export type Action = { type: "draw" } | { type: "discard"; card: Card };
|
||||
|
||||
export const newGame = (players: string[]) =>
|
||||
({
|
||||
export const newGame = (players: string[]) => {
|
||||
console.log("new game called with", JSON.stringify(players));
|
||||
return {
|
||||
deck: shuffle(newDeck()),
|
||||
players: Object.fromEntries(players.map((humanId) => [humanId, []])),
|
||||
} as GameState);
|
||||
} as GameState;
|
||||
};
|
||||
|
||||
export const getKnowledge = (state: GameState, humanId: string) => ({
|
||||
hash: hash(state),
|
||||
humanId,
|
||||
deck: state.deck.map((_) => null),
|
||||
players: Object.fromEntries(
|
||||
@@ -59,23 +58,27 @@ export const getKnowledge = (state: GameState, humanId: string) => ({
|
||||
),
|
||||
});
|
||||
|
||||
export const resolveAction = (state: GameState, action: Action): GameState => {
|
||||
if (action.prevHash != hash(state)) {
|
||||
throw new Error(
|
||||
`action thinks it's applying to ${
|
||||
action.prevHash
|
||||
}, but we're checking it against ${hash(state)}`
|
||||
);
|
||||
}
|
||||
export const resolveAction = (
|
||||
state: GameState,
|
||||
humanId: string,
|
||||
action: Action
|
||||
): GameState => {
|
||||
// if (action.prevHash != hash(state)) {
|
||||
// throw new Error(
|
||||
// `action thinks it's applying to ${
|
||||
// action.prevHash
|
||||
// }, but we're checking it against ${hash(state)}`
|
||||
// );
|
||||
// }
|
||||
|
||||
const playerHand = state.players[action.humanId];
|
||||
const playerHand = state.players[humanId];
|
||||
if (action.type == "draw") {
|
||||
const [drawn, ...rest] = state.deck;
|
||||
return {
|
||||
deck: rest,
|
||||
players: {
|
||||
...state.players,
|
||||
[action.humanId]: [drawn, ...playerHand],
|
||||
[humanId]: [drawn, ...playerHand],
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -86,7 +89,7 @@ export const resolveAction = (state: GameState, action: Action): GameState => {
|
||||
deck: [action.card, ...state.deck],
|
||||
players: {
|
||||
...state.players,
|
||||
[action.humanId]: playerHand
|
||||
[humanId]: playerHand
|
||||
.slice(0, index)
|
||||
.concat(playerHand.slice(index + 1)),
|
||||
},
|
||||
@@ -94,10 +97,18 @@ export const resolveAction = (state: GameState, action: Action): GameState => {
|
||||
};
|
||||
|
||||
export const simpleApi = new Elysia({ prefix: "/simple" })
|
||||
// .guard({ headers: t.Object({ Human: t.String() }) })
|
||||
.post(
|
||||
"/newGame",
|
||||
({ body: { players } }: { body: { players: string[] } }) =>
|
||||
newGame(players)
|
||||
(args: { body: { players: string[] }; headers: { human: string } }) => {
|
||||
return prisma.instance.create({
|
||||
data: {
|
||||
gameState: newGame(args.body.players),
|
||||
gameKey: "simple",
|
||||
createdByKey: args.headers.human,
|
||||
},
|
||||
});
|
||||
}
|
||||
)
|
||||
.group("/:instanceId", (app) =>
|
||||
app
|
||||
@@ -105,33 +116,35 @@ export const simpleApi = new Elysia({ prefix: "/simple" })
|
||||
prisma.instance
|
||||
.findUnique({
|
||||
where: {
|
||||
id: Number(instanceId),
|
||||
id: instanceId,
|
||||
},
|
||||
})
|
||||
.then((game) => game?.gameState)
|
||||
)
|
||||
.post(
|
||||
"/",
|
||||
({ params: { instanceId }, body: { action } }) =>
|
||||
({
|
||||
params: { instanceId },
|
||||
body: { action },
|
||||
headers: { Human: humanId },
|
||||
}) =>
|
||||
prisma.instance
|
||||
.findUniqueOrThrow({
|
||||
where: {
|
||||
id: Number(instanceId),
|
||||
id: instanceId,
|
||||
},
|
||||
})
|
||||
.then((game) => {
|
||||
const newState = resolveAction(
|
||||
game.gameState as GameState,
|
||||
humanId!,
|
||||
action
|
||||
);
|
||||
const knownState = getKnowledge(
|
||||
newState,
|
||||
action.humanId
|
||||
);
|
||||
const knownState = getKnowledge(newState, humanId!);
|
||||
void prisma.instance.update({
|
||||
data: { gameState: newState },
|
||||
where: {
|
||||
id: Number(instanceId),
|
||||
id: instanceId,
|
||||
},
|
||||
});
|
||||
return knownState;
|
||||
|
||||
@@ -10,7 +10,9 @@ const app = new Elysia()
|
||||
.onRequest(({ request }) => {
|
||||
console.log(request.method, request.url);
|
||||
})
|
||||
.onError(({ code, error }) => {
|
||||
.onError(({ code, error, body, headers }) => {
|
||||
console.error("headers", JSON.stringify(headers, null, 2));
|
||||
console.error("body", JSON.stringify(body, null, 2));
|
||||
console.error(code, error);
|
||||
})
|
||||
.get("/ping", () => "pong")
|
||||
|
||||
Reference in New Issue
Block a user