game = {
let game_ui_height = size+answers_rows*(padding+answer_height)+padding
let shadow = 4
var ui = svg`
<svg width="${width}" height="${game_ui_height+score_height}">
<style>
text {
font-family: sans-serif;
text-anchor: middle;
pointer-events: none;
fill: #333;
}
.card {
fill: white;
stroke-width: 3px;
stroke: #CCC;
}
.answer_btn:not(.clicked) {
cursor: pointer;
}
.shadow {
fill: #CCC;
}
.question {
font-size: ${ size*0.9 }px;
}
.answer {
font-weight: bold;
font-size: ${ answer_height*0.4 }px;
}
text.correct, text.wrong {
fill: white;
}
path.correct {
fill: #00973c;
stroke: #00973c;
}
path.wrong {
fill: #e2403f;
stroke: #e2403f;
}
.score {
font-size: ${ score_height*0.8 }px;
font-weight: bold;
}
tspan.correct {
fill: #00973c;
}
tspan.wrong {
fill: #e2403f;
}
tspan.total {
font-size: ${ score_height*0.5 }px;
}
</style>
<text
x="${ size/2 }"
y="${ size/2 }"
dy="0.35em"
class="question">
${ card[question] }
</text>
${
d3.range(answers_cols).map(j =>
d3.range(answers_rows).map(i => {
let w = (size-padding)/answers_cols
let h = answer_height
let answer_wrapper = answers[j*answers_rows+i]
let answer_class = answer_wrapper.clicked ? (answer_wrapper.card[answer] == card[answer] ? 'correct' : 'wrong') : ''
return `
<path
transform="translate(${ (w+padding)*j } ${ size + padding + (h+padding)*i })"
class="card shadow"
d="${ rounded_rect(w,h,16) }"/>
<path
transform="translate(${ (w+padding)*j } ${ size + padding + (h+padding)*i })"
class="card answer_btn ${ answer_class } ${ answer_wrapper.clicked ? 'clicked' : '' }"
d="${ rounded_rect(w,h-(answer_wrapper.clicked ? 0 : shadow),16) }"/>
<text
x="${ (w+padding)*(j+0.5) - padding/4 }"
y="${ size + padding/2 + (h+padding)*(i+0.5) }"
dy="0.35em"
class="answer ${ answer_class }">
${ answer_wrapper.card[answer] }
</text>
`})
)
}
<text x="${ size/2 }" y="${ game_ui_height + score_height/2 }" dy="0.35em" class="score">
<tspan class="correct">${ score }✓</tspan>
<tspan class="wrong">${ errors }❌</tspan>
<tspan class="total">${ deck.length }/${ data.length } cards left</tspan>
</text>
</svg>
`
// bind events
d3.select(ui).selectAll('.answer_btn')
.on('click', (_, i) => {
if(ui_locked) {
return;
}
(mutable answers)[i].clicked = true;
mutable answers = mutable answers; // retrigger cell
// update score, then proceed if answer was right
if(answers[i].card[answer] == card[answer]) {
mutable score += 1;
// lock ui to avoid repeated pressing of buttons
mutable ui_locked = true;
setTimeout(() => {
mutable turn += 1;
mutable ui_locked = false;
}, 800);
}
else {
mutable errors += 1;
}
})
return ui
}