Skip to content

Commit

Permalink
hooking all mutations and actions together
Browse files Browse the repository at this point in the history
  • Loading branch information
webdevcody committed Oct 16, 2024
1 parent 7956e3b commit b8bc586
Show file tree
Hide file tree
Showing 13 changed files with 380 additions and 269 deletions.
34 changes: 34 additions & 0 deletions app/games/[gameId]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"use client";

import { Map } from "@/app/map";
import { api } from "@/convex/_generated/api";
import { Id } from "@/convex/_generated/dataModel";
import { useQuery } from "convex/react";
import { Result } from "./result";

export default function GamePage({ params }: { params: { gameId: string } }) {
const game = useQuery(api.games.getGame, {
gameId: params.gameId as Id<"games">,
});
const results = useQuery(api.results.getResults, {
gameId: params.gameId as Id<"games">,
});

return (
<div className="container mx-auto min-h-screen flex flex-col items-center pt-12 gap-8">
<h1>Game {params.gameId}</h1>
<h2>Model: {game?.modelId}</h2>

<div className="flex flex-col gap-12">
{results === undefined || results.length === 0 ? (
<div className="flex flex-col justify-center items-center gap-8">
<div className="animate-spin rounded-full h-16 w-16 border-b-2 border-gray-900"></div>
<p className="ml-4">Game starting...</p>
</div>
) : (
results.map((result) => <Result result={result} key={result._id} />)
)}
</div>
</div>
);
}
30 changes: 30 additions & 0 deletions app/games/[gameId]/result.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"use client";

import { Map } from "@/app/map";
import { api } from "@/convex/_generated/api";
import { Doc } from "@/convex/_generated/dataModel";
import { useQuery } from "convex/react";

export const Result = ({ result }: { result: Doc<"results"> }) => {
const map = useQuery(api.maps.getMapByLevel, {
level: result.level,
});

if (!map) return null;

if (result.status === "inProgress") {
return <div>Game in progress...</div>;
}

return (
<div className="flex items-center gap-8" key={map._id}>
<div>Level {map.level}</div>
<Map map={map.grid} />
<div
className={`font-bold ${result.isWin ? "text-green-500" : "text-red-500"}`}
>
{result.isWin ? "Won" : "Lost"}
</div>
</div>
);
};
114 changes: 24 additions & 90 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
"use client";

import { CELL_SIZE, Map } from "./map";
import { api } from "@/convex/_generated/api";
import { useAction } from "convex/react";
import { useAction, useMutation } from "convex/react";
import React, { useState } from "react";
import { Button } from "@/components/ui/button";
import {
Expand All @@ -12,105 +11,40 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { AI_MODELS } from "@/app/constants";
import { Loader2 } from "lucide-react";

const hardCodedMapTemp = [
[" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " ", "R", " ", " "],
["R", "R", "R", "R", " ", " ", " ", "R", " ", " "],
[" ", " ", " ", " ", " ", " ", " ", "R", "Z", " "],
[" ", " ", " ", " ", " ", " ", " ", "R", " ", " "],
[" ", "Z", " ", " ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
];
import { AI_MODELS } from "@/convex/constants";
import { useRouter } from "next/navigation";

export default function MainPage() {
const getPlayerMap = useAction(api.openai.playMapAction);
const [resMap, setResMap] = useState<null | string[][]>(null);
const [loading, setLoading] = useState(false);
const startNewGame = useMutation(api.games.startNewGame);
const [model, setModel] = useState(AI_MODELS[0].model);
const router = useRouter();

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

console.log(res);
setResMap(res?.map || []);
} catch (error) {
console.error(error);
} finally {
setLoading(false);
}
await startNewGame({
modelId: model,
}).then((gameId) => {
router.push(`/games/${gameId}`);
});
};

const mapWidth = hardCodedMapTemp[0].length * CELL_SIZE;
const mapHeight = hardCodedMapTemp.length * CELL_SIZE;
console.log(mapWidth, mapHeight);

return (
<div className="container mx-auto min-h-screen flex flex-col items-center pt-12 gap-8">
<h1 className="text-4xl font-bold mb-8">Zombie Map Simulator</h1>

<div className="flex gap-8 items-start w-full">
<div className="flex flex-col items-center flex-grow">
<h2 className="text-2xl font-semibold mb-4">Initial Map</h2>
<Map map={hardCodedMapTemp} />
</div>

<div className="flex flex-col items-center justify-between h-full pt-12">
<div className="flex flex-col items-center gap-4">
<Select value={model} onValueChange={(value) => setModel(value)}>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Select model" />
</SelectTrigger>
<SelectContent>
{AI_MODELS.map((model) => (
<SelectItem key={model.model} value={model.model}>
{model.name}
</SelectItem>
))}
</SelectContent>
</Select>
<Button onClick={handleClick} disabled={loading}>
Run Simulation
</Button>
</div>
</div>

<div className="flex flex-col items-center justify-center flex-grow">
<h2 className="text-2xl font-semibold mb-4">AI Result</h2>
{loading ? (
<div
style={{
width: `${mapWidth}px`,
height: `${mapHeight}px`,
}}
className={`flex items-center justify-center`}
>
<Loader2 className="h-8 w-8 animate-spin" />
</div>
) : resMap ? (
<Map map={resMap} />
) : (
<div
style={{
width: `${mapWidth}px`,
height: `${mapHeight}px`,
}}
className={`border-2 border-dashed border-gray-300 flex items-center justify-center text-gray-400`}
>
Run simulation to see results
</div>
)}
</div>
<div className="flex justify-center gap-4">
<Select value={model} onValueChange={(value) => setModel(value)}>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Select model" />
</SelectTrigger>
<SelectContent>
{AI_MODELS.map((model) => (
<SelectItem key={model.model} value={model.model}>
{model.name}
</SelectItem>
))}
</SelectContent>
</Select>
<Button onClick={handleClick}>Test Model</Button>
</div>
</div>
);
Expand Down
123 changes: 64 additions & 59 deletions components/MapTester.tsx
Original file line number Diff line number Diff line change
@@ -1,69 +1,74 @@
"use client";

import { Map } from "@/app/map";
import { api } from "@/convex/_generated/api";
import { useAction } from "convex/react";
import React, { useState } from "react";
import { Button } from "./ui/button";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "./ui/select";
import { AI_MODELS } from "@/app/constants";
// import { Map } from "@/app/map";
// import { api } from "@/convex/_generated/api";
// import { useAction } from "convex/react";
// import React, { useState } from "react";
// import { Button } from "./ui/button";
// import {
// Select,
// SelectContent,
// SelectItem,
// SelectTrigger,
// SelectValue,
// } from "./ui/select";
// import { AI_MODELS } from "@/convex/constants";
// import { Id } from "@/convex/_generated/dataModel";

const MapTester = ({ map }: { map: string[][] }) => {
const getPlayerMap = useAction(api.openai.playMapAction);
const [resMap, setResMap] = useState<null | string[][]>();
const [loading, setLoading] = useState(false);
const [model, setModel] = useState(AI_MODELS[0].model);
return null;

const handleClick = async () => {
setLoading(true);
try {
const res = await getPlayerMap({
level: 1,
mapId: "zombiemap",
map,
});
// const getPlayerMap = useAction(api.openai.playMapAction);
// const [resMap, setResMap] = useState<null | string[][]>();
// const [loading, setLoading] = useState(false);
// const [model, setModel] = useState(AI_MODELS[0].model);

// type safe resulting object
console.log(res);
setResMap(res?.map);
} catch (error) {
console.error(error);
} finally {
setLoading(false);
}
};
// const handleClick = async () => {
// setLoading(true);
// try {
// const res = await getPlayerMap({
// level: 1,
// mapId: "zombiemap",
// map,
// modelId: model,
// gameId: "zombiegame" as Id<"games">,
// });

return (
<>
<div className="flex gap-4">
<Select value={model} onValueChange={(value) => setModel(value)}>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Select model" />
</SelectTrigger>
<SelectContent>
{AI_MODELS.map((model) => (
<SelectItem key={model.model} value={model.model}>
{model.name}
</SelectItem>
))}
</SelectContent>
</Select>
<Button onClick={handleClick} disabled={loading}>
Run Simulation
</Button>
</div>
<div className="flex flex-col gap-4">
{loading && <p>Loading result map...</p>}
{resMap && <Map map={resMap} />}
</div>
</>
);
// // type safe resulting object
// console.log(res);
// setResMap(res?.map);
// } catch (error) {
// console.error(error);
// } finally {
// setLoading(false);
// }
// };

// return (
// <>
// <div className="flex gap-4">
// <Select value={model} onValueChange={(value) => setModel(value)}>
// <SelectTrigger className="w-[180px]">
// <SelectValue placeholder="Select model" />
// </SelectTrigger>
// <SelectContent>
// {AI_MODELS.map((model) => (
// <SelectItem key={model.model} value={model.model}>
// {model.name}
// </SelectItem>
// ))}
// </SelectContent>
// </Select>
// <Button onClick={handleClick} disabled={loading}>
// Run Simulation
// </Button>
// </div>
// <div className="flex flex-col gap-4">
// {loading && <p>Loading result map...</p>}
// {resMap && <Map map={resMap} />}
// </div>
// </>
// );
};

export default MapTester;
10 changes: 8 additions & 2 deletions convex/_generated/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ import type {
FunctionReference,
} from "convex/server";
import type * as auth from "../auth.js";
import type * as constants from "../constants.js";
import type * as games from "../games.js";
import type * as http from "../http.js";
import type * as maps from "../maps.js";
import type * as openai from "../openai.js";
import type * as saveRound from "../saveRound.js";
import type * as results from "../results.js";
import type * as scores from "../scores.js";
import type * as users from "../users.js";

/**
Expand All @@ -32,10 +35,13 @@ import type * as users from "../users.js";
*/
declare const fullApi: ApiFromModules<{
auth: typeof auth;
constants: typeof constants;
games: typeof games;
http: typeof http;
maps: typeof maps;
openai: typeof openai;
saveRound: typeof saveRound;
results: typeof results;
scores: typeof scores;
users: typeof users;
}>;
export declare const api: FilterApi<
Expand Down
2 changes: 2 additions & 0 deletions app/constants.ts → convex/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export const AI_MODELS = [
name: "OpenAI - 4o Mini",
},
];

export const AI_MODEL_IDS = AI_MODELS.map((model) => model.model);
Loading

0 comments on commit b8bc586

Please sign in to comment.