From 2e6b5ad63c3274330f6444f7176e10333dd98830 Mon Sep 17 00:00:00 2001 From: Mawoka Date: Sun, 25 Sep 2022 12:22:50 +0200 Subject: [PATCH] :sparkles: Added scoreboard --- classquiz/socket_server/__init__.py | 32 +++--- frontend/src/lib/admin.svelte | 57 +++------- frontend/src/lib/helpers.ts | 4 + frontend/src/lib/play/admin/results.svelte | 109 ++++++++++++++++++++ frontend/src/lib/play/join.svelte | 2 +- frontend/src/lib/play/question.svelte | 2 +- frontend/src/lib/play/results_kahoot.svelte | 54 ++++++++++ frontend/src/routes/play/+page.svelte | 12 ++- 8 files changed, 209 insertions(+), 63 deletions(-) create mode 100644 frontend/src/lib/play/admin/results.svelte create mode 100644 frontend/src/lib/play/results_kahoot.svelte diff --git a/classquiz/socket_server/__init__.py b/classquiz/socket_server/__init__.py index ffb4f5a..2778107 100644 --- a/classquiz/socket_server/__init__.py +++ b/classquiz/socket_server/__init__.py @@ -109,7 +109,6 @@ async def join_game(sid: str, data: dict): room=redis_res.admin, ) lol = fernet.encrypt(datetime.now().isoformat().encode("utf-8")).decode("utf-8") - print(lol) await sio.emit("time_sync", lol, room=sid) sio.enter_room(sid, data.game_pin) @@ -220,6 +219,7 @@ class _AnswerData(BaseModel): answer: str right: bool time_taken: float # In milliseconds + score: int class _AnswerDataList(BaseModel): @@ -257,7 +257,17 @@ async def submit_answer(sid: str, data: dict): time_q_started = datetime.fromisoformat(await redis.get(f"game:{session['game_pin']}:current_time")) answers = await redis.get(f"game_session:{session['game_pin']}:{data.question_index}") diff = (time_q_started - now).total_seconds() * 1000 # - timedelta(milliseconds=latency) + # print(abs(diff) - latency, latency, abs(diff)) + def calculate_score(z: float, t: int) -> int: + t = t * 1000 + res = (t - z) / t + return int(res * 1000) + + score = 0 + if answer_right: + score = calculate_score(abs(diff) - latency, int(game_data.questions[int(data.question_index)].time)) + if answers is None: await redis.set( f"game_session:{session['game_pin']}:{data.question_index}", @@ -268,6 +278,7 @@ async def submit_answer(sid: str, data: dict): answer=data.answer, right=answer_right, time_taken=abs(diff) - latency, + score=score, ) ] ).json(), @@ -277,7 +288,11 @@ async def submit_answer(sid: str, data: dict): answers = _AnswerDataList.parse_raw(answers) answers.__root__.append( _AnswerData( - username=session["username"], answer=data.answer, right=answer_right, time_taken=abs(diff) - latency + username=session["username"], + answer=data.answer, + right=answer_right, + time_taken=abs(diff) - latency, + score=score, ) ) await redis.set( @@ -297,7 +312,6 @@ async def get_final_results(sid: str, _data: dict): if not session["admin"]: return results = await generate_final_results(game_data, session["game_pin"]) - print(results) await sio.emit("final_results", results, room=session["game_pin"]) @@ -328,17 +342,5 @@ async def echo_time_sync(sid: str, data: str): then = datetime.fromisoformat(then_dec) now = datetime.now() delta = now - then - print( - "delta:", - delta, - "then:", - then, - "now:", - now, - "seconds delay:", - delta.seconds, - "microseconds delay", - delta.microseconds / 1000, - ) async with sio.session(sid) as session: session["ping"] = delta.microseconds / 1000 diff --git a/frontend/src/lib/admin.svelte b/frontend/src/lib/admin.svelte index dab8090..8af24af 100644 --- a/frontend/src/lib/admin.svelte +++ b/frontend/src/lib/admin.svelte @@ -12,6 +12,7 @@ import { QuizQuestionType } from '$lib/quiz_types'; import { kahoot_icons } from './play/kahoot_mode_assets/kahoot_icons'; import CircularTimer from '$lib/play/circular_progress.svelte'; + import Spinner from '$lib/Spinner.svelte'; export let game_token: string; export let quiz_data: QuizData; @@ -26,7 +27,7 @@ let shown_question_now: number; let final_results_clicked = false; - console.log(quiz_data); + let player_scores = {}; export const set_question_number = (q_number: number) => { question_results = null; @@ -143,7 +144,7 @@ {/if} {/if}
- {#if timer_res !== undefined && !final_results_clicked} + {#if timer_res !== undefined && !final_results_clicked && !question_results}

{quiz_data.questions[selected_question].question} @@ -205,49 +206,15 @@

{/if} {:else} -
-
- - - - - - - - - - {#each question_results as result} - - - - - - {/each} - -
- {$t('words.username')} - - {$t('words.answer')} - - {$t('words.correct')}? -
- {result.username} - - {result.answer} - - {#if result.right} - ✅ - {:else} - ❌ - {/if} -
-
-
+ {#await import('$lib/play/admin/results.svelte')} + + {:then c} + + {/await} {/if} {:else if timer_res !== undefined} {#if game_mode === 'normal'} diff --git a/frontend/src/lib/helpers.ts b/frontend/src/lib/helpers.ts index 975662a..f314bbc 100644 --- a/frontend/src/lib/helpers.ts +++ b/frontend/src/lib/helpers.ts @@ -14,3 +14,7 @@ export const invertColor = (hexTripletColor: string): string => { color = '#' + color; // prepend # return color; }; + +export const calculate_score = (q_time: number, time_taken: number): number => { + return q_time / time_taken; +}; diff --git a/frontend/src/lib/play/admin/results.svelte b/frontend/src/lib/play/admin/results.svelte new file mode 100644 index 0000000..11d776a --- /dev/null +++ b/frontend/src/lib/play/admin/results.svelte @@ -0,0 +1,109 @@ + + + +
+ +
+
+ + + + + {#if show_new_score_clicked} + + {/if} + + {#each player_names as player, i (player)} + + + + {#if show_new_score_clicked} + + {/if} + + {/each} +
NamePointsPoints added
3} class="p-2 border-r border-r-black">{player} 3} class="p-2">{data[player]} 3} + class="p-2" + class:text-red-600={score_by_username[player] === 0} + > + +{score_by_username[player]} +
+
+
+
diff --git a/frontend/src/lib/play/join.svelte b/frontend/src/lib/play/join.svelte index 5ca64dc..d004c8e 100644 --- a/frontend/src/lib/play/join.svelte +++ b/frontend/src/lib/play/join.svelte @@ -15,7 +15,7 @@ export let game_pin: string; export let game_mode; - let username = ''; + export let username; let hcaptchaSitekey = import.meta.env.VITE_HCAPTCHA; let hcaptcha = { diff --git a/frontend/src/lib/play/question.svelte b/frontend/src/lib/play/question.svelte index 22f7af2..be8eac3 100644 --- a/frontend/src/lib/play/question.svelte +++ b/frontend/src/lib/play/question.svelte @@ -103,7 +103,7 @@
-{#if question.image !== null} +{#if question.image !== null && game_mode !== 'kahoot'}
+ + +
+
+
+

+ +{score_by_username[username]} +

+

Total score: {scores[username]}

+
+
+
diff --git a/frontend/src/routes/play/+page.svelte b/frontend/src/routes/play/+page.svelte index b759194..be0b848 100644 --- a/frontend/src/routes/play/+page.svelte +++ b/frontend/src/routes/play/+page.svelte @@ -8,6 +8,7 @@ import ShowResults from '$lib/play/show_results.svelte'; import { navbarVisible } from '$lib/stores'; import ShowEndScreen from '$lib/play/end.svelte'; + import KahootResults from '$lib/play/results_kahoot.svelte'; import { getLocalization } from '$lib/i18n'; const { t } = getLocalization(); @@ -38,6 +39,8 @@ let answer_results: Array; let gameData; let solution: QuestionType; + let username = ''; + let scores = {}; let gameMeta: GameMeta = { started: false }; @@ -122,7 +125,7 @@
{#if !gameMeta.started && gameData === undefined} - + {:else if JSON.stringify(final_results) !== JSON.stringify([null])} {:else if gameData !== undefined && question_index === ''} @@ -140,6 +143,13 @@

{$t('admin_page.no_answers')}

+ {:else if game_mode === 'kahoot'} +
+

{$t('words.result', { count: 2 })}

+
+ {#key unique} + + {/key} {:else} {#key unique}