If you were able to write the character in another syllabary kanaguessr will not show it again until you've got all characters basically
401 lines
8 KiB
JavaScript
401 lines
8 KiB
JavaScript
const items = [
|
||
{
|
||
"h": "あ",
|
||
"k": "ア",
|
||
"r": "a"
|
||
},
|
||
{
|
||
"h": "い",
|
||
"k": "イ",
|
||
"r": "i"
|
||
},
|
||
{
|
||
"h": "う",
|
||
"k": "ウ",
|
||
"r": "u"
|
||
},
|
||
{
|
||
"h": "え",
|
||
"k": "エ",
|
||
"r": "e"
|
||
},
|
||
{
|
||
"h": "お",
|
||
"k": "オ",
|
||
"r": "o"
|
||
},
|
||
{
|
||
"h": "か",
|
||
"k": "カ",
|
||
"r": "ka"
|
||
},
|
||
{
|
||
"h": "き",
|
||
"k": "キ",
|
||
"r": "ki"
|
||
},
|
||
{
|
||
"h": "く",
|
||
"k": "ク",
|
||
"r": "ku"
|
||
},
|
||
{
|
||
"h": "け",
|
||
"k": "ケ",
|
||
"r": "ke"
|
||
},
|
||
{
|
||
"h": "こ",
|
||
"k": "コ",
|
||
"r": "ko"
|
||
},
|
||
{
|
||
"h": "さ",
|
||
"k": "サ",
|
||
"r": "sa"
|
||
},
|
||
{
|
||
"h": "し",
|
||
"k": "シ",
|
||
"r": "shi"
|
||
},
|
||
{
|
||
"h": "す",
|
||
"k": "ス",
|
||
"r": "su"
|
||
},
|
||
{
|
||
"h": "せ",
|
||
"k": "セ",
|
||
"r": "se"
|
||
},
|
||
{
|
||
"h": "そ",
|
||
"k": "ソ",
|
||
"r": "so"
|
||
},
|
||
{
|
||
"h": "た",
|
||
"k": "タ",
|
||
"r": "ta"
|
||
},
|
||
{
|
||
"h": "ち",
|
||
"k": "チ",
|
||
"r": "chi"
|
||
},
|
||
{
|
||
"h": "つ",
|
||
"k": "ツ",
|
||
"r": "tsu"
|
||
},
|
||
{
|
||
"h": "て",
|
||
"k": "テ",
|
||
"r": "te"
|
||
},
|
||
{
|
||
"h": "と",
|
||
"k": "ト",
|
||
"r": "to"
|
||
},
|
||
{
|
||
"h": "な",
|
||
"k": "ナ",
|
||
"r": "na"
|
||
},
|
||
{
|
||
"h": "に",
|
||
"k": "ニ",
|
||
"r": "ni"
|
||
},
|
||
{
|
||
"h": "ぬ",
|
||
"k": "ヌ",
|
||
"r": "nu"
|
||
},
|
||
{
|
||
"h": "ね",
|
||
"k": "ネ",
|
||
"r": "ne"
|
||
},
|
||
{
|
||
"h": "の",
|
||
"k": "ノ",
|
||
"r": "no"
|
||
},
|
||
{
|
||
"h": "は",
|
||
"k": "ハ",
|
||
"r": "ha"
|
||
},
|
||
{
|
||
"h": "ひ",
|
||
"k": "ヒ",
|
||
"r": "hi"
|
||
},
|
||
{
|
||
"h": "ふ",
|
||
"k": "フ",
|
||
"r": "fu"
|
||
},
|
||
{
|
||
"h": "へ",
|
||
"k": "ヘ",
|
||
"r": "he"
|
||
},
|
||
{
|
||
"h": "ほ",
|
||
"k": "ホ",
|
||
"r": "ho"
|
||
},
|
||
{
|
||
"h": "ま",
|
||
"k": "マ",
|
||
"r": "ma"
|
||
},
|
||
{
|
||
"h": "み",
|
||
"k": "ミ",
|
||
"r": "mi"
|
||
},
|
||
{
|
||
"h": "む",
|
||
"k": "ム",
|
||
"r": "mu"
|
||
},
|
||
{
|
||
"h": "め",
|
||
"k": "メ",
|
||
"r": "me"
|
||
},
|
||
{
|
||
"h": "も",
|
||
"k": "モ",
|
||
"r": "mo"
|
||
},
|
||
{
|
||
"h": "や",
|
||
"k": "ヤ",
|
||
"r": "ya"
|
||
},
|
||
{
|
||
"h": "ゆ",
|
||
"k": "ユ",
|
||
"r": "yu"
|
||
},
|
||
{
|
||
"h": "よ",
|
||
"k": "ヨ",
|
||
"r": "yo"
|
||
},
|
||
{
|
||
"h": "ら",
|
||
"k": "ラ",
|
||
"r": "ra"
|
||
},
|
||
{
|
||
"h": "り",
|
||
"k": "リ",
|
||
"r": "ri"
|
||
},
|
||
{
|
||
"h": "る",
|
||
"k": "ル",
|
||
"r": "ru"
|
||
},
|
||
{
|
||
"h": "れ",
|
||
"k": "レ",
|
||
"r": "re"
|
||
},
|
||
{
|
||
"h": "ろ",
|
||
"k": "ロ",
|
||
"r": "ro"
|
||
},
|
||
{
|
||
"h": "わ",
|
||
"k": "ワ",
|
||
"r": "wa"
|
||
},
|
||
{
|
||
"h": "を",
|
||
"k": "ヲ",
|
||
"r": "wo"
|
||
},
|
||
{
|
||
"h": "ん",
|
||
"k": "ン",
|
||
"r": "n"
|
||
}
|
||
]
|
||
|
||
const all = []
|
||
items.forEach((i) => {all.push(["h", i.h]); all.push(["k", i.k]); all.push(["r", i.r])})
|
||
let got_right = []
|
||
|
||
const settings = {
|
||
character: {
|
||
hiragana: true,
|
||
katakana: true,
|
||
romaji: false,
|
||
},
|
||
typeas: {
|
||
hiragana: false,
|
||
katakana: false,
|
||
romaji: true,
|
||
}
|
||
}
|
||
|
||
$(function() {
|
||
$("#answer_field").on("keyup", event => {
|
||
if (event.key === "Enter") {
|
||
$("#correct_answer").css("visibility") === "visible" ? $("#next_btn").trigger("click") : $("#answer_btn").trigger("click")
|
||
}
|
||
})
|
||
|
||
settings.character.hiragana = $("#hq").is(":checked")
|
||
$("#hq").change(() => {settings.character.hiragana = $("#hq").is(":checked");changeQuestion()})
|
||
settings.character.katakana = $("#kq").is(":checked")
|
||
$("#kq").change(() => {settings.character.katakana = $("#kq").is(":checked"); changeQuestion()})
|
||
settings.character.romaji = $("#rq").is(":checked")
|
||
$("#rq").change(() => {settings.character.romaji = $("#rq").is(":checked"); changeQuestion()})
|
||
|
||
settings.typeas.hiragana = $("#he").is(":checked")
|
||
$("#he").change(() => {settings.typeas.hiragana = $("#he").is(":checked"); changeQuestion()})
|
||
settings.typeas.katakana = $("#ke").is(":checked")
|
||
$("#ke").change(() => {settings.typeas.katakana = $("#ke").is(":checked"); changeQuestion()})
|
||
settings.typeas.romaji = $("#re").is(":checked")
|
||
$("#re").change(() => {settings.typeas.romaji = $("#re").is(":checked"); changeQuestion()})
|
||
|
||
$("#answer_field").on("input propertychange", () => {checkCharacters()})
|
||
$("#answer_field").on("focus", () => {$("#answer_field").select()})
|
||
$("#answer_btn").click(checkAnswer)
|
||
$("#next_btn").click(() => changeQuestion())
|
||
|
||
changeQuestion()
|
||
})
|
||
|
||
function crash(are_we_looping) {
|
||
if (!are_we_looping) {
|
||
got_right = []
|
||
return changeQuestion(true)
|
||
} else {
|
||
$("#settings").css("opacity", "0")
|
||
$("#settings").animate({"opacity": "1"}, 200)
|
||
console.error("Impossible to ask anything with such settings!")
|
||
return
|
||
}
|
||
}
|
||
|
||
function changeQuestion(are_we_looping) {
|
||
const all_possibilities = all.filter((p) => !got_right.map((t) => t[1]).includes(p[1]))
|
||
|
||
const only_type_as_hiragana = settings.typeas.hiragana && !settings.typeas.katakana && !settings.typeas.romaji
|
||
const only_type_as_katakana = !settings.typeas.hiragana && settings.typeas.katakana && !settings.typeas.romaji
|
||
const only_type_as_romaji = !settings.typeas.hiragana && !settings.typeas.katakana && settings.typeas.romaji
|
||
|
||
const possibilities = all_possibilities.filter((p) => {
|
||
if (p[0] === "h" && settings.character.hiragana && !only_type_as_hiragana) {return p}
|
||
if (p[0] === "k" && settings.character.katakana && !only_type_as_katakana) {return p}
|
||
if (p[0] === "r" && settings.character.romaji && !only_type_as_romaji) {return p}
|
||
})
|
||
|
||
if (!possibilities.length) {
|
||
return crash(are_we_looping)
|
||
}
|
||
|
||
const i1 = Math.floor(Math.random() * possibilities.length)
|
||
const character = possibilities[i1][1]
|
||
const character_type = possibilities[i1][0]
|
||
const item = items.find((i) => i[character_type] === character)
|
||
|
||
const equivalent_types = []
|
||
if (settings.typeas.hiragana) {equivalent_types.push("h")}
|
||
if (settings.typeas.katakana) {equivalent_types.push("k")}
|
||
if (settings.typeas.romaji) {equivalent_types.push("r")}
|
||
|
||
const equivalents = equivalent_types
|
||
.filter((t) => t !== character_type)
|
||
.map((t) => [t, item[t]])
|
||
|
||
if (!equivalents.length) {
|
||
return crash(are_we_looping)
|
||
}
|
||
|
||
const i2 = Math.floor(Math.random() * equivalents.length)
|
||
const equivalent = equivalents[i2][1]
|
||
const equivalent_type = equivalents[i2][0]
|
||
|
||
$("#answer_field").val("") // Empty field so user doesn't have to do it
|
||
$("#answer_field").focus() // Focus on field so user doesn't have to do it
|
||
$("#answer_btn").attr("disabled", false)
|
||
$("#answer_btn").css("display", "block")
|
||
$("#next_btn").css("display", "none")
|
||
$("#next_btn").html("skip")
|
||
|
||
changeBackground(character_type, $("#character"))
|
||
changeBackground(equivalent_type, $("#equivalent"))
|
||
|
||
$("#correct_answer").css("visibility", "hidden")
|
||
$("#correct_answer").slideUp(100)
|
||
|
||
$("#character").html(character)
|
||
$("#equivalent").html(equivalent_type === "h" ? "ひらがな" : equivalent_type === "k" ? "カタカナ" : "rōmaji")
|
||
$("#answer_paragraph").html(`the answer was ${equivalent}`)
|
||
}
|
||
|
||
function changeBackground(char, para) {
|
||
let colour = "black"
|
||
if (char === "h") {colour = "#b57642"}
|
||
else if (char === "k") {colour = "steelblue"}
|
||
else if (char === "r") {colour = "blueviolet"}
|
||
|
||
para.css("backgroundColor", colour)
|
||
para.attr("char", char)
|
||
}
|
||
|
||
function checkCharacters() {
|
||
const REGEX_JAPANESE = /[\u3040-\u30ff]/
|
||
const REGEX_OTHER = /[^\u3040-\u30ff]/
|
||
const regex = $("#equivalent").html() === "rōmaji" ? REGEX_JAPANESE : REGEX_OTHER
|
||
|
||
if (!$("#answer_field").val() || !$("#answer_field").val().match(regex)) {
|
||
$("#answer_field").css("backgroundColor", "black")
|
||
} else {
|
||
$("#answer_field").css("backgroundColor", "red")
|
||
}
|
||
}
|
||
|
||
function checkAnswer() {
|
||
$("#answer_field").focus() // Keey keyboard on for mobile users
|
||
if (!$("#answer_field").val()) {return}
|
||
if ($("#answer_field").css("backgroundColor") === "rgb(255, 0, 0)") {
|
||
$("#equivalent").css("fontSize", "25px")
|
||
$("#equivalent").animate({"fontSize": "20px"}, 1000)
|
||
return
|
||
}
|
||
|
||
const html = $("#answer_paragraph").html()
|
||
const correct = $("#answer_field").val().toLowerCase() === html.slice(html.lastIndexOf(" ") + 1)
|
||
const element = correct ? $("#positive") : $("#negative")
|
||
if (correct) {got_right.push([$("#character").attr("char"), $("#character").html()])}
|
||
|
||
element.css("opacity", "0")
|
||
element.css("backgroundColor", element.css("color"))
|
||
setTimeout(() => {element.css("backgroundColor", "black")}, 125)
|
||
element.animate({"opacity": "1"}, 250)
|
||
element.html(Number(element.html()) + 1)
|
||
|
||
if ($("#auto:checked").length) {
|
||
changeQuestion()
|
||
} else {
|
||
$("#correct_answer").css("visibility", "visible")
|
||
$("#correct_answer").slideDown(100)
|
||
$("#answer_btn").attr("disabled", true)
|
||
$("#answer_btn").css("display", "none")
|
||
$("#next_btn").html("next")
|
||
$("#next_btn").css("display", "block")
|
||
}
|
||
}
|