From 0ce8ebce5a7d08cb0de31c21a199bf5ee4dcc39d Mon Sep 17 00:00:00 2001 From: hopperelec Date: Thu, 25 Jan 2024 12:56:09 +0000 Subject: [PATCH] Question implementation- player must answer question correctly to move between rooms Created LocalDoor type for improved type safety --- src/lib/types.d.ts | 2 ++ src/routes/(app)/+page.svelte | 25 +++++++++++++++++-- src/routes/(app)/check-answer/+server.ts | 24 ++++++++++++++++++ src/routes/(app)/get-definition/+server.ts | 17 +++++++++++++ .../(app)/teacher/door-mapper/+page.svelte | 7 ++---- .../teacher/door-mapper/add-door/+server.ts | 9 ++++--- .../door-mapper/remove-door/+server.ts | 7 +++--- 7 files changed, 77 insertions(+), 14 deletions(-) create mode 100644 src/lib/types.d.ts create mode 100644 src/routes/(app)/check-answer/+server.ts create mode 100644 src/routes/(app)/get-definition/+server.ts diff --git a/src/lib/types.d.ts b/src/lib/types.d.ts new file mode 100644 index 0000000..bb9db56 --- /dev/null +++ b/src/lib/types.d.ts @@ -0,0 +1,2 @@ +export type Question = { id: number; question: string }; +export type LocalDoor = { room1_id: number; room2_id: number }; diff --git a/src/routes/(app)/+page.svelte b/src/routes/(app)/+page.svelte index ea506be..707e1af 100644 --- a/src/routes/(app)/+page.svelte +++ b/src/routes/(app)/+page.svelte @@ -2,6 +2,7 @@ import type { PageData } from "./$types"; import SVGMap from "$lib/SVGMap.svelte"; import { error } from "@sveltejs/kit"; + import type { Question } from "$lib/types"; export let data: PageData; if (!data.map) throw error(403, "You do not have access to any maps!"); @@ -37,8 +38,28 @@ return doors[room1_id] && doors[room1_id].includes(room2_id); } - function onClickRoom(clickedRoom: number) { - if (canMoveTo(clickedRoom)) position = clickedRoom; + async function askQuestion(question: Question): Promise { + const answer = prompt(question.question); + const res = await fetch(`/check-answer?id=${question.id}&answer=${answer}`); + console.log(res); + return (await res.json()).correct; + } + + async function getNextQuestion(): Promise { + const res: { id: number; definition: string } = await (await fetch("/get-definition")).json(); + return {id: res.id, question: "What vocabulary is being defined: "+res.definition} + } + + async function onClickRoom(clickedRoom: number) { + if (canMoveTo(clickedRoom)) { + const question = await getNextQuestion(); + let askAgain = true; + while (askAgain) { + console.log(2); + if (await askQuestion(question)) askAgain = false; + } + position = clickedRoom; + } } function onSuccess() { diff --git a/src/routes/(app)/check-answer/+server.ts b/src/routes/(app)/check-answer/+server.ts new file mode 100644 index 0000000..d5a304e --- /dev/null +++ b/src/routes/(app)/check-answer/+server.ts @@ -0,0 +1,24 @@ +import { error, type RequestHandler } from "@sveltejs/kit"; +import prisma from "$lib/prisma"; + +export const GET: RequestHandler = async ({ url }) => { + const id = url.searchParams.get("id"); + if (!id) throw error(400, "Question ID not provided"); + const answer = url.searchParams.get("answer"); + if (!answer) throw error(400, "Answer not provided"); + const res = await prisma.definition.findUnique({ + where: { + id: +id, + }, + select: { + answer_regex: true, + }, + }); + if (!res) throw error(400, "Invalid question ID"); + const correct = new RegExp("^" + res.answer_regex + "$").test(answer); + return new Response(JSON.stringify({ correct }), { + headers: { + "Content-Type": "application/json", + }, + }); +}; diff --git a/src/routes/(app)/get-definition/+server.ts b/src/routes/(app)/get-definition/+server.ts new file mode 100644 index 0000000..2c300a6 --- /dev/null +++ b/src/routes/(app)/get-definition/+server.ts @@ -0,0 +1,17 @@ +import prisma from "$lib/prisma"; +import type { RequestHandler } from "@sveltejs/kit"; + +export const GET: RequestHandler = async () => { + const definition: { id: bigint; definition: string }[] = + await prisma.$queryRaw`SELECT id,definition FROM Definition ORDER BY rand() LIMIT 1`; + return new Response( + JSON.stringify(definition[0], (_, v) => + typeof v === "bigint" ? Number(v) : v, + ), + { + headers: { + "Content-Type": "application/json", + }, + }, + ); +}; diff --git a/src/routes/(app)/teacher/door-mapper/+page.svelte b/src/routes/(app)/teacher/door-mapper/+page.svelte index 95138a2..c3d0526 100644 --- a/src/routes/(app)/teacher/door-mapper/+page.svelte +++ b/src/routes/(app)/teacher/door-mapper/+page.svelte @@ -3,6 +3,7 @@ import SVGMap from "$lib/SVGMap.svelte"; import { SVG_NS } from "$lib/constants"; import { error } from "@sveltejs/kit"; + import type { LocalDoor } from "$lib/types"; export let data: PageData; if (!data.map) throw error(403, "You do not have access to any maps!"); @@ -11,11 +12,7 @@ let firstRoom: number; let firstRoomCenter: DOMPoint | undefined; - function drawLine( - door: { room1_id: number; room2_id: number }, - firstRoomCenter?: DOMPoint, - secondRoomCenter?: DOMPoint, - ) { + function drawLine(door: LocalDoor, firstRoomCenter?: DOMPoint, secondRoomCenter?: DOMPoint) { if (firstRoomCenter && secondRoomCenter) { const line = map .getSVG() diff --git a/src/routes/(app)/teacher/door-mapper/add-door/+server.ts b/src/routes/(app)/teacher/door-mapper/add-door/+server.ts index 934e95b..551a8a1 100644 --- a/src/routes/(app)/teacher/door-mapper/add-door/+server.ts +++ b/src/routes/(app)/teacher/door-mapper/add-door/+server.ts @@ -1,12 +1,13 @@ import { error, type RequestHandler } from "@sveltejs/kit"; import prisma from "$lib/prisma"; import { getMapFor } from "$lib/get-map-for"; +import type { LocalDoor } from "$lib/types"; export const POST: RequestHandler = async ({ request, locals }) => { const map_id = (await getMapFor(locals.user))?.id; if (!map_id) throw error(403, "You do not have access to any maps!"); - const params = await request.json(); - if (params.room1_id === params.room2_id) + const door: LocalDoor = await request.json(); + if (door.room1_id === door.room2_id) throw error(400, "Cannot add a door between a room and itself!"); await prisma.door.create({ data: { @@ -18,7 +19,7 @@ export const POST: RequestHandler = async ({ request, locals }) => { room1: { connect: { id_map_id: { - id: Math.min(params.room1_id, params.room2_id), + id: Math.min(door.room1_id, door.room2_id), map_id, }, }, @@ -26,7 +27,7 @@ export const POST: RequestHandler = async ({ request, locals }) => { room2: { connect: { id_map_id: { - id: Math.max(params.room1_id, params.room2_id), + id: Math.max(door.room1_id, door.room2_id), map_id, }, }, diff --git a/src/routes/(app)/teacher/door-mapper/remove-door/+server.ts b/src/routes/(app)/teacher/door-mapper/remove-door/+server.ts index 44fd957..1d06705 100644 --- a/src/routes/(app)/teacher/door-mapper/remove-door/+server.ts +++ b/src/routes/(app)/teacher/door-mapper/remove-door/+server.ts @@ -1,17 +1,18 @@ import { error, type RequestHandler } from "@sveltejs/kit"; import prisma from "$lib/prisma"; import { getMapFor } from "$lib/get-map-for"; +import type { LocalDoor } from "$lib/types"; export const POST: RequestHandler = async ({ request, locals }) => { - const params = await request.json(); + const door: LocalDoor = await request.json(); const map_id = (await getMapFor(locals.user))?.id; if (!map_id) throw error(403, "You do not have access to any maps!"); await prisma.door.delete({ where: { map_id_room1_id_room2_id: { map_id, - room1_id: params.room1_id, - room2_id: params.room2_id, + room1_id: door.room1_id, + room2_id: door.room2_id, }, }, });