app/hooks/use-scoreboard.ts (41 lines of code) (raw):
/**
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import useFirebaseAuthentication from './use-firebase-authentication';
import useGame from './use-game';
const useScoreboard = () => {
const authUser = useFirebaseAuthentication();
const {game} = useGame();
// create a list of all players
const arraysAreEqual = (a: boolean[], b: boolean[]) => {
return a.every((val, index) => val === b[index]);
};
const playerScoresObject = Object.values(game.questions).reduce((playerScores: { [key: string]: { score: number, displayName: string, uid: string }; }, question) => {
const correctAnswerArray = question.answers.map((answer) => answer.isCorrect);
let newPlayerScores = playerScores;
// for each question, go through every guess
if (question.playerGuesses) {
Object.entries(question.playerGuesses).forEach(([uid, playerGuess]) => {
const previousPlayerScore = playerScores[uid]?.score || 0;
// if a player's guess is correct, add 1 point to their score
const currentQuestionScore = arraysAreEqual(correctAnswerArray, playerGuess) ? 1 : 0;
const score = previousPlayerScore + currentQuestionScore;
newPlayerScores = {
...newPlayerScores,
[uid]: {displayName: game.players[uid], score, uid},
};
});
}
return newPlayerScores;
}, {});
const currentPlayer = {
...playerScoresObject[authUser.uid],
displayName: game.players[authUser.uid],
};
const playerScores = Object.values(playerScoresObject).sort((a, b) => {
// higher score goes first
if (a.score > b.score) return -1;
if (a.score < b.score) return 1;
// put the current player at the top of those with the same score
if (a.uid === authUser.uid) return -1;
if (b.uid === authUser.uid) return 1;
// otherwise, sort alphabetically
return a.displayName.localeCompare(b.displayName);
});
return {
currentPlayer,
playerScores,
};
};
export default useScoreboard;