Skip to content

Commit

Permalink
solved conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
Geen-19 committed Oct 15, 2024
2 parents 29e4ba7 + 95d554e commit 3bc3c12
Show file tree
Hide file tree
Showing 11 changed files with 248 additions and 10 deletions.
9 changes: 9 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
This is a community project for my discord, so please join if you want to participate.

You can still contribute without being part of discord, but it would be nice.

## Join the community

Want to help build on this project?

- Join the [WDC Discord](https://discord.gg/N2uEyp7Rfu)
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Before you can run the project, you'll need to setup a
1. `npm i`
2. `npm run dev`
3. `use http://localhost:3000 for SITE_URL when prompted`
4. `Y for cofigure GitHub OAuth`
4. `Y for configure GitHub OAuth`
5. `create a github OAuth app at https://github.com/settings/applications/new`
6. `paste client id when prompted`
7. `paste client secret when prompted`
Expand Down
4 changes: 3 additions & 1 deletion app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import MapTester from "@/components/MapTester";
import { Map } from "./map";

const hardCodedMapTemp = [
Expand All @@ -14,8 +15,9 @@ const hardCodedMapTemp = [

export default function MainPage() {
return (
<div className="min-h-screen flex items-center justify-center">
<div className="min-h-screen flex flex-col items-center justify-center">
<Map map={hardCodedMapTemp} />
<MapTester map={hardCodedMapTemp} />
</div>
);
}
85 changes: 85 additions & 0 deletions components/MapTester.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"use client";

import { Map } from "@/app/map";
import { api } from "@/convex/_generated/api";
import { useAction } from "convex/react";
import React, { useState } from "react";

function convertStringMapToNumberGrid(map: string[][]): number[][] {
return map.map((row) =>
row.map((cell) => {
switch (cell) {
case "P":
return 3; // Player
case "Z":
return 1; // Zombie
case "R":
return 2; // Rocks
case "B":
return 4; // Block
case " ":
return 0; // Empty Space
default:
return 0; // Default to empty space
}
}),
);
}

function convertNumberGridToStringMap(grid: number[][]): string[][] {
return grid.map((row) =>
row.map((cell) => {
switch (cell) {
case 3:
return "P"; // Player
case 1:
return "Z"; // Zombie
case 2:
return "R"; // Rocks
case 4:
return "B"; // Block
case 0:
return " "; // Empty Space
default:
return " "; // Default to empty space
}
}),
);
}

const MapTester = ({ map }: { map: string[][] }) => {
const getPlayerMap = useAction(api.openai.playerMap);
const [resMap, setResMap] = useState<null | number[][]>();
const [loading, setLoading] = useState(false);

const handleClick = async () => {
setLoading(true);
try {
const res = await getPlayerMap({
level: 1,
mapId: "zombiemap",
map: convertStringMapToNumberGrid(map),
});

// type safe resulting object
console.log(res);
setResMap(res?.map);
} catch (error) {
console.error(error);
} finally {
setLoading(false);
}
};

return (
<div>
<button onClick={handleClick} disabled={loading}>
Test Output
</button>
{loading && <p>Loading result map...</p>}
{resMap && <Map map={convertNumberGridToStringMap(resMap)} />}
</div>
);
};

export default MapTester;
2 changes: 2 additions & 0 deletions convex/_generated/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import type * as auth from "../auth.js";
import type * as http from "../http.js";
import type * as messages from "../messages.js";
import type * as saveRound from "../saveRound.js";
import type * as openai from "../openai.js";
import type * as users from "../users.js";

/**
Expand All @@ -34,6 +35,7 @@ declare const fullApi: ApiFromModules<{
http: typeof http;
messages: typeof messages;
saveRound: typeof saveRound;
openai: typeof openai;
users: typeof users;
}>;
export declare const api: FilterApi<
Expand Down
23 changes: 23 additions & 0 deletions convex/games/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { v } from "convex/values";
import { internal } from "../_generated/api";
import { internalAction } from "../_generated/server";

export const playMapAction = internalAction({
args: {
mapId: v.id("maps"),
gameId: v.id("games"),
modelId: v.string(),
level: v.number(),
},
handler: async (ctx, args) => {
await ctx.runMutation(internal.games.mutations.insertScore, {
modelId: args.modelId,
gameId: args.gameId,
level: args.level,
});

console.log(
`Playing map ${args.mapId} for game ${args.gameId} at level ${args.level}`,
);
},
});
49 changes: 49 additions & 0 deletions convex/games/mutations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { v } from "convex/values";
import { internal } from "../_generated/api";
import { internalMutation } from "../_generated/server";

export const createNewGame = internalMutation({
args: { modelId: v.string() },
handler: async (ctx, args) => {
const gameId = await ctx.db.insert("games", {
modelId: args.modelId,
currentLevel: 1,
status: "in_progress",
});

const firstMap = await ctx.db
.query("maps")
.withIndex("by_level", (q) => q.eq("level", 1))
.first();

if (!firstMap) {
throw new Error("No map found for level 1");
}

// not sure if this is the way to do this
await ctx.scheduler.runAfter(0, internal.games.actions.playMapAction, {
mapId: firstMap._id,
gameId,
modelId: args.modelId,
level: 1,
});

return gameId;
},
});

export const insertScore = internalMutation({
args: {
modelId: v.string(),
gameId: v.id("games"),
level: v.number(),
},
handler: async ({ db }, args) => {
await db.insert("scores", {
modelId: args.modelId,
gameId: args.gameId,
score: 0,
level: args.level,
});
},
});
58 changes: 58 additions & 0 deletions convex/openai.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import OpenAI from "openai";
import { action, query } from "./_generated/server";
import { v } from "convex/values";
import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";

const openai = new OpenAI();

const ResponseSchema = z.object({
map: z.array(z.array(z.number())),
reasoning: z.string(),
playerCoordinates: z.array(z.number()),
BoxCoordinates: z.array(z.array(z.number())),
});

export const playerMap = action({
args: {
map: v.array(v.array(v.number())),
mapId: v.string(),
level: v.number(),
},
handler: async (_, args) => {
try {
const completion = await openai.beta.chat.completions.parse({
model: "gpt-4o-2024-08-06",
messages: [
{
role: "system",
content: `You're given a 2d grid of nums such that.
0 represents an empty space.
1 represents a zombie. Zombies move one Manhattan step every turn and aim to reach the player.
2 represents rocks, which players can shoot over but zombies cannot pass through or break.
3 represents the player, who cannot move. The player's goal is to shoot and kill zombies before they reach them.
4 represents blocks that can be placed before the round begins to hinder the zombies. You can place up to two blocks on the map.
Your goal is to place the player (3) and two blocks (4) in locations that maximize the player's survival by delaying the zombies' approach while allowing the player clear lines of sight to shoot them before they get too close.
Returning a 2d grid with the player and blocks placed in the optimal locations, with the coordinates player (3) and the blocks (4), also provide reasoning for the choices.`,
},
{
role: "user",
content: JSON.stringify(args.map),
},
],
response_format: zodResponseFormat(ResponseSchema, "game_map"),
});

const map_response = completion.choices[0].message;
if (map_response.parsed) {
return map_response.parsed;
} else if (map_response.refusal) {
const refusal_res = map_response.refusal;
throw new Error(`Refusal: ${refusal_res}`);
}
} catch (error) {
// todo: handle error
console.log(error);
}
},
});
1 change: 1 addition & 0 deletions convex/saveRound.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export const saveRoundMutation = mutation({
updatedScore = await ctx.db.insert("scores", {
modelId: game.modelId,
score: 1,
...args,
});
}
}
Expand Down
21 changes: 14 additions & 7 deletions convex/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,23 @@ export default defineSchema({
userId: v.id("users"),
body: v.string(),
}),

games: defineTable({
modelId: v.string(),
// Other fields can be added as needed
currentLevel: v.number(),
status: v.union(v.literal("in_progress"), v.literal("completed")),
}),

maps: defineTable({
level: v.number(),
grid: v.array(v.array(v.string())),
width: v.number(),
height: v.number(),
}).index("by_level", ["level"]),
scores: defineTable({
modelId: v.string(),
gameId: v.id("games"),
score: v.number(),
level: v.number(),
}).index("by_game_and_level", ["gameId", "level"]),
results: defineTable({
gameId: v.id("games"),
roundId: v.string(),
Expand All @@ -24,8 +35,4 @@ export default defineSchema({
reasoning: v.string(),
}),

scores: defineTable({
modelId: v.string(),
score: v.number(),
}),
});
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@
"convex": "^1.16.0",
"next": "14.2.5",
"next-themes": "^0.3.0",
"openai": "^4.67.3",
"react": "^18",
"react-dom": "^18",
"tailwind-merge": "^2.4.0",
"tailwindcss-animate": "^1.0.7"
"tailwindcss-animate": "^1.0.7",
"zod": "^3.23.8"
},
"devDependencies": {
"@types/node": "^20",
Expand Down

0 comments on commit 3bc3c12

Please sign in to comment.