From 5ac55557c970b10eb53c20ab0451f5c249770aba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20P=C4=99dzich?= Date: Tue, 27 Jun 2023 10:35:44 +0200 Subject: [PATCH] Implement showing random F1 trivia --- src/composables/useVote.ts | 48 +++++++++++---- src/funFacts.json | 17 ++++++ src/models/index.ts | 1 + src/views/Vote.vue | 121 +++++++++++++++++++++++++++---------- 4 files changed, 145 insertions(+), 42 deletions(-) create mode 100644 src/funFacts.json diff --git a/src/composables/useVote.ts b/src/composables/useVote.ts index 651d0fd..7659caa 100644 --- a/src/composables/useVote.ts +++ b/src/composables/useVote.ts @@ -1,4 +1,4 @@ -import { reactive, ref, toRefs, watchEffect } from 'vue'; +import { computed, reactive, ref, toRefs, watchEffect } from 'vue'; import glicko2 from 'glicko2-lite'; import defaultPhotos from '@/photos.json'; @@ -8,13 +8,34 @@ import { randomNumber } from '@/utils/randomNumber'; const db = reactive( JSON.parse(localStorage.getItem('db') as string) || { photos: defaultPhotos, - votes: [] + votes: [], + shownFactIndexes: [] } ); const photosInCurrentVote = ref([]); +// We need to calculate the number of pairs we can create from a set of n photos. +// // Since the order in which the photos are picked doesn't matter, +// the number of all votes a user can submit equals "n choose 2". +// This can be simplified to: (n * (n - 1)) / 2 +const NUM_POSSIBLE_VOTES = (db.photos.length * (db.photos.length - 1)) / 2; + +const completionPercentage = computed( + () => (db.votes.length / NUM_POSSIBLE_VOTES) * 100 +); + +const userSubmittedAllVotes = computed( + () => completionPercentage.value === 100 +); + +const userReachedTriviaMilestone = computed(() => + [25, 50, 75].includes(completionPercentage.value) +); + const pickPhotosForNewVote = () => { + if (userSubmittedAllVotes.value) return; + const photosForFirstPick = db.photos.filter(({ fileName }) => { const appearanceCount = db.votes.filter((vote) => vote.photos.includes(fileName) @@ -31,12 +52,12 @@ const pickPhotosForNewVote = () => { photos.includes(firstPick.fileName) ); - const fileNamesToExclude = [ + const fileNamesToExclude = new Set([ firstPick.fileName, ...votesWithFirstPick.flatMap(({ photos }) => photos) - ]; + ]); - return !fileNamesToExclude.includes(fileName); + return fileNamesToExclude.has(fileName) === false; }); const secondPick = @@ -46,9 +67,10 @@ const pickPhotosForNewVote = () => { }; const submitVote = (result: 0 | 0.5 | 1) => { - const photos = [...photosInCurrentVote.value].map( - ({ fileName }) => fileName - ) as [string, string]; + const photos = photosInCurrentVote.value.map(({ fileName }) => fileName) as [ + string, + string + ]; db.votes.unshift({ photos, result }); @@ -60,6 +82,8 @@ const submitVote = (result: 0 | 0.5 | 1) => { }; const updateRatings = () => { + // The first vote in the array is the most recent one. + // Therefore calling reverse will order these votes chronologically. const twelveMostRecentVotes = db.votes.slice(0, 12).reverse(); const votesGrouppedByPhotos = twelveMostRecentVotes.reduce((obj, vote) => { @@ -104,10 +128,12 @@ watchEffect(() => localStorage.setItem('db', JSON.stringify(db))); export function useVote() { return { + ...toRefs(db), photosInCurrentVote, + completionPercentage, + userReachedTriviaMilestone, + userSubmittedAllVotes, pickPhotosForNewVote, - submitVote, - updateRatings, - ...toRefs(db) + submitVote }; } diff --git a/src/funFacts.json b/src/funFacts.json new file mode 100644 index 0000000..c3c58bc --- /dev/null +++ b/src/funFacts.json @@ -0,0 +1,17 @@ +[ + "Sebastian Vettel won the 2010 drivers' championship, despite never having led it at any point until the end of the last race of the season.", + "Lewis Hamilton is a British F1 driver who won the 2008 drivers' championship in a McLaren with number 22. The following season it was another Brit, Jenson Button, who claimed the title in his BrawnGP car... with number 22.", + "There are 3 world champions who share the last name \"Hill\": Phil, Graham, and Damon. Only two of them are related - Graham is Damon's father.", + "Even though Nico Rosberg won fewer races than Lewis Hamilton in 2016 (9 and 10 respectively), it's the former who won the drivers' championship that season.", + "Jochen Rindt, a German-born driver from Austria, is the only person who won the drivers' championship posthhumously. His Finnish wife Nina collected the trophy at a ceremony at the end of the season.", + "Niki Lauda beat his McLaren teammate Alain Prost in the drivers' championship in 1984 only by half a point. They scored 72 and 71,5 points respectively.", + "Markus Winkelhock is the only person to start from both last and first place in the same race, and to lead every race he ever competed in (2007 European Grand Prix).", + "Lella Lombardi is the only woman who scored points in F1. She received 0,5 points when the 1975 Spanish GP was cut short when she was running in 6th place.", + "Slim Borgudd was a drummer for ABBA, and was also a formula 1 driver for ATS and Tyrell. The car even had the ABBA logo as an unpaid sponsorship.", + "1997 title showdown in Jerez saw the top 3 drivers (Jacques Villeneuve, Michael Schumacher, and Heinz-Harald Frentzen) qualifying with the exactly same time of 1:21,072. The starting grid was decided upon chronological order for registering the time.", + "Hans Heyer is the only Formula 1 driver to score a DNQ (Did Not Qualify), a DNF (Did Not Finish), and a DSQ (Disqualified) in a single race.", + "The Indianapolis 500 race was part of the Formula One World Drivers' Championship between 1950 and 1960.", + "The first 6 races of the 2012 season were won by 6 different drivers: Jenson Button, Fernando Alonso, Nico Rosberg, Sebastian Vettel, Pastor Maldonado, Mark Webber, and Lewis Hamilton.", + "Alain Prost won the first race Ayrton Senna competed in, whereas the fomer's last race was won by the latter. Ayrton Senna won the first race Michael Schumacher participated in, whereas the former's last race was won by the latter.", + "When the Mexican driver Pedro Rodriguez won the 1967 South African Grand Prix, the organizers didn't have the Mexican national anthem, so they played the \"Mexican hat dance\" instead." +] diff --git a/src/models/index.ts b/src/models/index.ts index ee8b042..cdc8656 100644 --- a/src/models/index.ts +++ b/src/models/index.ts @@ -14,4 +14,5 @@ export interface Vote { export interface Database { photos: Photo[]; votes: Vote[]; + shownFactIndexes: number[]; } diff --git a/src/views/Vote.vue b/src/views/Vote.vue index e8a7559..6f81e8d 100644 --- a/src/views/Vote.vue +++ b/src/views/Vote.vue @@ -1,44 +1,103 @@