Skip to content

Commit

Permalink
New game mode
Browse files Browse the repository at this point in the history
  • Loading branch information
nayakrujul committed Aug 17, 2024
1 parent 260fd2a commit 681d903
Show file tree
Hide file tree
Showing 7 changed files with 236 additions and 120 deletions.
2 changes: 1 addition & 1 deletion folders/latin/entry-level/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@
tandem at last/finally
timeo, timere, timui fear/be afraid
tu, tui you (singular)
ubi where?/where/when
ubi where(?)/when
urbs, urbis, f. city/town
venio, venire, veni come
via, viae, f. street/road/way
Expand Down
11 changes: 8 additions & 3 deletions help/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,21 @@ <h3 class="faq-header">Classic Mode</h3>
sets will come up, and you have to <strong>type the definition</strong> and press <kbd>ENTER</kbd>.
</p>
<p class="faq-answer">
You can <strong>keep playing for as long as you want</strong>, as the terms will keep reshuffling.
When you are finished, <strong>press the finish button</strong>, and the site will show you a
<strong>list of mistakes</strong> that you made.
You can keep playing <strong>until the selected terms run out</strong>, or you can finish the game
early using the finish button. At the end, you can <strong>retry your mistakes</strong>.
</p>
<p class="faq-answer">
VTP6 is supported by a <strong>superior typo detection algorithm</strong> which can prompt you to
retry a question if it thinks you made a typo. Furthermore, the algorithm <strong>ignores case and
punctuation</strong> to make it easier for mobile users (where the first letter is usually
auto-capitalised).
</p>
<h3 class="faq-header">Classic Infinite Mode</h3>
<p class="faq-answer">
Classic Infinite Mode is an extension of Classic Mode where the <strong>terms keep reshuffling
forever</strong>. To exit, you can <strong>press the finish button</strong> and you can see your
mistakes in a table, just like with Classic Mode.
</p>
<h3 class="faq-header">Match Mode</h3>
<p class="faq-answer">
The aim of Match Mode is to <strong>pair up the six terms</strong> on the left <strong>with the six
Expand Down
224 changes: 219 additions & 5 deletions scripts/folders-classic.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// NOTE: because Quick Fire and Classic share a lot of features,
// the code behind Quick Fire mode was added to this file instead
// of a separate folders-quickfire.js
// NOTE: this file contains the code behind the Classic, Classic Infinite, and
// Quick Fire modes on VTP6. They were bundled together because they share a lot of
// features with each other, and so some code can be reused.

// NOTE: this is going to be very confusing, but whenever the code mentions
// `classic` mode, this means "Classic Infinite" mode. "Classic" mode is referred to
// as `legacy` mode in the code. This is because what is now "Classic Infinite" mode
// was originally called "Classic" mode, and what is now "Classic" mode was added
// in later at the request of a VTP6 user.

let full_terms_list = [];
let randomised_terms = [];
Expand All @@ -27,7 +33,9 @@ function set_progress_bar_background(val) {
.style.width = `${100 - val}%`;
}

function new_question() {
function new_question(reload=true) {
if (randomised_terms.length === 0 && !reload) return false;

[question, answer] = randomised_terms.shift();
document.getElementById("classic-question-text").innerHTML = sanitise(question);

Expand All @@ -38,9 +46,10 @@ function new_question() {
if (OPTIONS["all"]) document.getElementById("classic-question-text").innerHTML +=
` (<span id="classic-all-num">0</span>/${split_answer.length})`;

if (randomised_terms.length === 0) randomised_terms = random_shuffle(full_terms_list);
if (randomised_terms.length === 0 && reload) randomised_terms = random_shuffle([...full_terms_list]);

textbox.focus();
return true;
}

function update_bar_text() {
Expand Down Expand Up @@ -158,6 +167,71 @@ function check_input_classic() {
update_bar_text();
}

function check_input_legacy() {
let result = check_input(userans = textbox.value);
let cont = true;

if (result === undefined) return;

textbox.classList.remove("correct");
textbox.classList.remove("wrong");
textbox.offsetWidth;

if (OPTIONS["all"]) {
if (result) {
textbox.classList.add("correct");
split_answer = split_answer.filter(l =>
!l.map(remove_punctuation)
.includes(remove_punctuation(userans))
);
if (split_answer.length === 0) {
correct++;
document.getElementById("typo-text").innerHTML = `
<span class="green">Correct!</span>
`;
cont = new_question(false);
} else {
let n = document.getElementById("classic-all-num");
n.innerHTML = +n.innerHTML + 1;
document.getElementById("typo-text").innerHTML = `
<span class="green">Keep going!</span>
`;
}
} else {
wrong++;
textbox.classList.add("wrong");
document.getElementById("typo-text").innerHTML = `
<span class="red">Wrong:</span>
${answer}
`;
wrongtbl.push([question, answer, userans]);
cont = new_question(false);
}
} else {
if (result) {
correct++;
textbox.classList.add("correct");
document.getElementById("typo-text").innerHTML = `
<span class="green">Correct!</span>
`;
} else {
wrong++;
textbox.classList.add("wrong");
document.getElementById("typo-text").innerHTML = `
<span class="red">Wrong:</span>
${answer}
`;
wrongtbl.push([question, answer, userans]);
}
cont = new_question(false);
}
update_bar_text();

if (!cont) {
finish_legacy_game();
}
}

function check_input_quickfire() {
let result = check_input(userans = textbox.value);

Expand Down Expand Up @@ -289,6 +363,99 @@ function finish_classic_game() {
}
}

function finish_legacy_game() {
if (randomised_terms.length === 0 || window.confirm("Are you sure you want to finish the game?")) {
document.getElementById("classic-div").remove();
let finish_div = document.createElement("div");
finish_div.innerHTML = `
<div id="score-div">
<h3>${correct}/${correct + wrong} (${(correct / ((correct + wrong) || 1) * 100).toPrecision(3)}%)</h3>
</div>
<div id="restart-button-div">
<button class="start-button" id="classic-retry-button"
${wrongtbl.length === 0 ? 'disabled' : ''}>Mistakes</button>
<button class="start-button" id="classic-restart-button">Restart!</button>
</div>
<table id="wrong-table">
<tr>
<th>Term</th>
<th>Definition</th>
<th>Your&nbsp;Answer</th>
</tr>
</table>
`;
finish_div.id = "finish-div";
document.getElementById("content")
.insertBefore(finish_div, document.getElementById("margin"));

[...wrongtbl].forEach(row => {
let [a, b, c] = row;
let tr = document.createElement("tr");
tr.innerHTML = `
<td>${a}</td> <td>${b}</td>
<td><em>${c}</em></td>
`;
document.getElementById("wrong-table").appendChild(tr);
});

document.getElementById("classic-restart-button")
.addEventListener("click", () => {
document.getElementById("finish-div").remove();
document.getElementById("settings-bar").hidden = false;
document.getElementById("units-flex").style.display = "flex";

full_terms_list = [];
randomised_terms = [];

[question, answer] = ["", ""];

split_answer = [];

textbox = undefined;

correct = 0;
wrong = 0;

wrongtbl = [];

quickfire_timer = 150;
quickfire_timer_id = 0;
quickfire_increment = 30;
});

document.getElementById("classic-retry-button")
.addEventListener("click", () => {
let mistakes = [...wrongtbl].map(([x, y, _]) => [x, y]);

document.getElementById("finish-div").remove();
document.getElementById("settings-bar").hidden = false;
document.getElementById("units-flex").style.display = "flex";

full_terms_list = [];
randomised_terms = [];

[question, answer] = ["", ""];

split_answer = [];

textbox = undefined;

correct = 0;
wrong = 0;

wrongtbl = [];

quickfire_timer = 150;
quickfire_timer_id = 0;
quickfire_increment = 30;

folders_start_legacy([...mistakes]);
document.getElementById("settings-bar").hidden = true;
document.getElementById("units-flex").style.display = "none";
})
}
}

function set_quickfire_high_score(score) {
let currenths = get_cookies()["vtp6HighScore_quick_fire"];
if (currenths === undefined || score > +currenths) {
Expand Down Expand Up @@ -411,6 +578,53 @@ function folders_start_classic(terms) {
new_question();
}

function folders_start_legacy(terms) {
full_terms_list = [...terms];
randomised_terms = random_shuffle(terms);

let classic_div = document.createElement("div");
classic_div.innerHTML = `
<div id="progress-bar-div">
<div id="progress-bar-container"><div id="progress-bar"></div></div>
<span id="progress-bar-text">0/0 (0.00%)</span>
</div>
<h1 id="classic-question">
<button class="start-button" id="skip-button">Skip &rarr;</button>
<span id="classic-question-text"></span>
<button class="start-button" id="finish-button">Finish!</button>
</h1>
<div id="input-div">
<input type="text" id="classic-input"
placeholder="Type the definition here..."
autocomplete="off" autocorrect="off"
spellcheck="false" />
<button class="start-button" id="square-finish-button"><img id="finish-image" /></button>
</div>
<p id="typo-text">&nbsp;</p>
`;
classic_div.id = "classic-div";
document.getElementById("content")
.insertBefore(classic_div, document.getElementById("margin"));

textbox = document.getElementById("classic-input");

document.getElementById("skip-button").addEventListener("click", () =>
(textbox.value = "") || check_input_legacy()
);

document.getElementById("finish-button").addEventListener("click", finish_legacy_game);
document.getElementById("square-finish-button").addEventListener("click", finish_legacy_game);

textbox.addEventListener("keyup", ({ key }) => {
if (key === "Enter") {
check_input_legacy();
}
});

window.scrollTo(0, 0);
new_question(false);
}

function folders_start_quickfire(terms) {
full_terms_list = [...terms];
randomised_terms = random_shuffle(terms);
Expand Down
1 change: 1 addition & 0 deletions scripts/folders-misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ document.addEventListener("keydown", (event) => {

const GAME_MODE_DESCRIPTIONS = {
classic: "Simply give the definition of each term that comes up. No clock, no high scores, no stress.",
classic_infinite: "Same as Classic mode, except you can keep answering questions for as long as you want.",
match: "Match the terms on the left to the definitions on the right as quickly as possible.",
quick_fire: "Race against the clock to answer as many questions as possible in a set amount of time."
}
Expand Down
2 changes: 2 additions & 0 deletions scripts/folders-start.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ function folders_start_game() {
).map(arr => arr[1]).flat();

if (game_mode === "classic") {
folders_start_legacy(selected_terms)
} else if (game_mode === "classic_infinite") {
folders_start_classic(selected_terms);
} else if (game_mode === "match") {
folders_start_match(selected_terms);
Expand Down
Loading

0 comments on commit 681d903

Please sign in to comment.