Skip to content

Commit

Permalink
feature() - sort, don't randomize + timer on challenges (#10)
Browse files Browse the repository at this point in the history
* feature() - sort, don't randomize options

* feature() - add challenge duration
  • Loading branch information
vnglst authored May 17, 2020
1 parent 197d474 commit 023a737
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 44 deletions.
107 changes: 105 additions & 2 deletions src/components/Card.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,31 @@
<script>
import { fade } from "svelte/transition";
import { onMount } from "svelte";
export let duration = null;
export let onTimeout = null;
export let completed = false;
let timedOut = false;
</script>

<div class="card">
{#if duration && !timedOut && !completed}
<div
class="progress animated"
on:animationend={() => {
timedOut = true;
setTimeout(() => {
timedOut = false;
}, 200);
onTimeout();
}}
style="animation-duration: {duration}s"
/>
{/if}
{#if timedOut}
<div class="progress ended" />
{/if}
<div class="header">
<slot name="header" />
</div>
Expand All @@ -14,15 +41,91 @@
display: grid;
background-color: var(--white);
color: var(--grey-900);
border-radius: 20px;
border-radius: 10px;
margin: 3rem 1rem 0.5rem 1rem;
padding: 0;
box-shadow: var(--shadow-2);
width: 28rem;
min-height: 35rem;
}
.progress {
margin-top: -10px;
border-bottom: 10px solid var(--blue-300);
border-radius: 20px 0 0 0;
width: 100%;
}
.ended {
border-radius: 20px 20px 0 0;
border-color: var(--red-1000);
}
.animated {
animation: countdown;
animation-duration: 1s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
animation-timing-function: linear;
}
@keyframes countdown {
0% {
width: 0%;
}
70% {
border-color: var(--blue-300);
}
/* start flashing red */
71% {
border-color: var(--red-500);
}
74% {
border-color: var(--red-1000);
}
76% {
border-color: var(--red-500);
}
78% {
border-color: var(--red-1000);
}
81% {
border-color: var(--red-500);
}
84% {
border-color: var(--red-1000);
}
81% {
border-color: var(--red-500);
}
84% {
border-color: var(--red-1000);
}
87% {
border-color: var(--red-500);
}
90% {
border-color: var(--red-1000);
}
93% {
border-color: var(--red-500);
}
96% {
border-color: var(--red-1000);
}
99% {
border-color: var(--red-500);
border-radius: 20px 0 0 0;
}
100% {
width: 100%;
/* end count down with rounded corner */
border-radius: 20px 20px 0 0;
border-color: var(--red-1000);
}
}
.header {
margin: 0;
font-size: 28px;
text-align: center;
}
Expand Down
18 changes: 16 additions & 2 deletions src/components/Game.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
export let challenge;
const DURATION = 10;
let total = challenge.questions.length;
let results = new Array(total);
let currentIdx = 0;
Expand All @@ -18,7 +20,7 @@
$: rights = results.filter(r => r === true).length;
$: wrongs = results.filter(r => r === false).length;
$: flawless = wrongs === 0;
$: passed = wrongs <= 2;
$: passed = wrongs <= Math.round(total * 0.2); // 20% of questions correct
$: isDone = currentIdx === total;
$: if (isDone) {
Expand Down Expand Up @@ -55,11 +57,23 @@
squakk.play();
results[currentIdx] = false;
}
function handleTimeout() {
squakk.play();
results[currentIdx] = false;
setTimeout(() => {
currentIdx++;
}, 200);
}
</script>

<Page>
{#if current}
<Card>
<Card
duration={DURATION}
onTimeout={handleTimeout}
completed={results[currentIdx] === true}
>
<h1 slot="header">{`${current.q} = ?`}</h1>
<Grid>
{#each current.options as option, index (`${current.q}-${option}-${index}`)}
Expand Down
1 change: 1 addition & 0 deletions src/components/GameReport.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
font-size: 20px;
width: max-content;
padding: 0.5em 1em;
min-width: 6em;
}
.again {
Expand Down
12 changes: 6 additions & 6 deletions src/components/PageLoadingBar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
$: inner_style = `background-color: ${color2}`;
</script>

{#if $preloading}
<div class="progress" {style}>
<div class="indeterminate" style={inner_style} />
</div>
{/if}

<style>
.progress {
position: fixed;
Expand Down Expand Up @@ -71,9 +77,3 @@
}
}
</style>

{#if $preloading}
<div class="progress" {style}>
<div class="indeterminate" style={inner_style} />
</div>
{/if}
4 changes: 2 additions & 2 deletions src/routes/add/addQuestions.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { addRandomOptions, removeDups, rnd, prepare, generateChallenges } from '../utils'
import { addRandomOptions, removeDups, rnd, generateChallenges } from '../utils'

function generateAddQuestions(maxValue = 10, total = 10) {
let table = []
Expand Down Expand Up @@ -27,7 +27,7 @@ function generateAddQuestions(maxValue = 10, total = 10) {
})
}

const getQuestions = n => prepare(generateAddQuestions(n))
const getQuestions = n => generateAddQuestions(n)

const definition = {
title: "Additions",
Expand Down
4 changes: 2 additions & 2 deletions src/routes/subtract/subtractQuestions.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { addRandomOptions, removeDups, rnd, prepare, generateChallenges } from '../utils'
import { addRandomOptions, removeDups, rnd, generateChallenges } from '../utils'

function generateQuestions(maxValue = 10, total = 10) {
let table = []
Expand Down Expand Up @@ -28,7 +28,7 @@ function generateQuestions(maxValue = 10, total = 10) {
})
}

const getQuestions = n => prepare(generateQuestions(n))
const getQuestions = n => generateQuestions(n)

const definition = {
title: "Subtractions",
Expand Down
4 changes: 2 additions & 2 deletions src/routes/table/tableQuestions.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { addRandomOptions, prepare, generateChallenges } from '../utils'
import { addRandomOptions, generateChallenges } from '../utils'

function generateTableQuestions(base, maxValue = 10) {
const table = []
Expand All @@ -18,7 +18,7 @@ function generateTableQuestions(base, maxValue = 10) {
})
}

export const getQuestions = n => prepare(generateTableQuestions((n)))
export const getQuestions = n => generateTableQuestions((n))

const definition = {
title: "Multiplications",
Expand Down
34 changes: 6 additions & 28 deletions src/routes/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,18 @@ export const rnd = ({ from = 0, to = 1 }) => {

export const shuffle = arr => arr.sort(() => Math.random() - 0.5);

export function shuffleOptions(table) {
table.forEach(question => {
question.options = shuffle(question.options);
});
return table;
}

export function addRandomOptions({ table, total, min, max }) {
table.forEach(question => {
const newOptions = generateMoreOptions({
total,
existing: question.options,
min,
max
});
question.options = newOptions;
while (question.options.length < total) {
const newOption = rnd({ from: min, to: max });
const exists = question.options.find(option => option === newOption);
if (!exists) question.options.push(newOption);
}
question.options.sort((a, b) => a - b)
});
return table;
}

export function generateMoreOptions({ total, existing, min, max }) {
const choices = [...existing];

while (choices.length < total) {
const newChoice = rnd({ from: min, to: max });
const exists = choices.find(choice => choice === newChoice);
if (!exists) choices.push(newChoice);
}

return choices;
}

export function removeDups(arr, property) {
const newArray = [];
const lookupObject = {};
Expand All @@ -52,8 +32,6 @@ export function removeDups(arr, property) {
return newArray;
}

export const prepare = table => shuffleOptions(shuffle(table));

export function generateChallenges({ initialState, definition, getQuestions }) {
let challenges = {};
for (let n in initialState) {
Expand Down

0 comments on commit 023a737

Please sign in to comment.