mirror of
https://github.com/ZetaKebab/japanese-conjugation-drill.git
synced 2025-01-14 22:08:44 +00:00
Added polv mode.
This commit is contained in:
parent
5b6ec67759
commit
1dee0d87f8
228
conjugation/polv.html
Normal file
228
conjugation/polv.html
Normal file
@ -0,0 +1,228 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="stylesheet" href="drill.css" type="text/css" media="screen"/>
|
||||
<link href="https://fonts.googleapis.com/css?family=Amaranth" rel="stylesheet">
|
||||
<script type="text/ecmascript" src="//code.jquery.com/jquery-3.1.1.min.js"></script>
|
||||
<script type="text/ecmascript" src="polv_words.js"></script>
|
||||
<script type="text/ecmascript" src="polv.js"></script>
|
||||
<title>Don's Japanese Conjugation Drill</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="splash">
|
||||
|
||||
<h1>Don's Japanese Conjugation Drill</h1>
|
||||
|
||||
<div>
|
||||
<span>Number of Questions</span>
|
||||
<input id="numQuestions" value="10">
|
||||
<button id="go">Go</button>
|
||||
</div>
|
||||
|
||||
<div>Question pool size: <span id="questionCount">...</span></div>
|
||||
|
||||
<div class="options">
|
||||
<div>
|
||||
<h2>Conjugation types</h2>
|
||||
<ul>
|
||||
<li><label><input type="checkbox" id="plain" checked> Plain</label></li>
|
||||
<li><label><input type="checkbox" id="polite" checked> Polite</label></li>
|
||||
<li><label><input type="checkbox" id="negative" checked> Negative</label></li>
|
||||
<li><label><input type="checkbox" id="past" checked> Past</label></li>
|
||||
<li><label><input type="checkbox" id="te-form"> て form</label></li>
|
||||
<li><label><input type="checkbox" id="progressive"> Progressive</label></li>
|
||||
<li><label><input type="checkbox" id="potential"> Potential</label></li>
|
||||
<li><label><input type="checkbox" id="imperative"> Imperative</label></li>
|
||||
<li><label><input type="checkbox" id="passive"> Passive</label></li>
|
||||
<li><label><input type="checkbox" id="causative"> Causative</label></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>Verb classes</h2>
|
||||
<ul>
|
||||
<li><label><input type="checkbox" id="godan" checked> Group 1 verbs</label></li>
|
||||
<li><label><input type="checkbox" id="ichidan" checked> Group 2 verbs</label></li>
|
||||
<li><label><input type="checkbox" id="iku" checked> 行く verb</label></li>
|
||||
<li><label><input type="checkbox" id="kuru" checked> 来る verb</label></li>
|
||||
<li><label><input type="checkbox" id="suru" checked> する verbs</label></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>Adjective classes</h2>
|
||||
<ul>
|
||||
<li><label><input type="checkbox" id="i-adjective"> い adjectives</label></li>
|
||||
<li><label><input type="checkbox" id="na-adjective"> な adjectives</label></li>
|
||||
<li><label><input type="checkbox" id="ii"> いい adjective</label></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div>
|
||||
<label><input type="checkbox" id="trick" checked> Trick questions (answers may be the same as the given form)</label>
|
||||
</div>
|
||||
-->
|
||||
|
||||
</div>
|
||||
|
||||
<div id="scoreSection">
|
||||
|
||||
<div id="history">
|
||||
</div>
|
||||
|
||||
<button id="backToStart">Back to Start</button>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="quizSection">
|
||||
|
||||
<div class="questionOuter">
|
||||
<div id="question"></div>
|
||||
</div>
|
||||
|
||||
<div id="input">
|
||||
<form action="javascript:processAnswer()">
|
||||
<input placeholder="答え" autocomplete="off" id="answer">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="proceed">
|
||||
|
||||
<form style="float: right" action="javascript:proceed()">
|
||||
<button>
|
||||
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 48 48">
|
||||
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
|
||||
<g transform="scale(0.03)"><path d="M762.1,441.8L354.4,34.1C322.2,2,270.1,2,237.9,34.1c-32.2,32.2-32.2,84.3,0,116.5L587.4,500L237.9,849.4c-32.2,32.2-32.2,84.3,0,116.5s84.3,32.2,116.5,0l407.6-407.6c16.1-16.1,24.1-37.2,24.1-58.2S778.1,457.8,762.1,441.8z"></path></g>
|
||||
</svg>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div id="response">
|
||||
</div>
|
||||
|
||||
<div id="message">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div id="explanation">
|
||||
<h2>Conjugations for group 1 verbs (godan)</h2>
|
||||
<p>Group 1 (godan) verbs are those that, with a few exceptions, do not
|
||||
end with an いる or える sound.</p>
|
||||
|
||||
<table class="syllabary">
|
||||
|
||||
<tr class="あ">
|
||||
<td><div>ぱ</div><div>pa</div></td>
|
||||
<td><div>ば</div><div>ba</div></td>
|
||||
<td><div>だ</div><div>da</div></td>
|
||||
<td><div>ざ</div><div>za</div></td>
|
||||
<td><div>が</div><div>ga</div></td>
|
||||
<td class="empty"></td>
|
||||
<td><div>ん</div><div>n</div></td>
|
||||
<td><div>わ</div><div>wa</div></td>
|
||||
<td><div>ら</div><div>ra</div></td>
|
||||
<td><div>や</div><div>ya</div></td>
|
||||
<td><div>ま</div><div>ma</div></td>
|
||||
<td><div>は</div><div>ha</div></td>
|
||||
<td><div>な</div><div>na</div></td>
|
||||
<td><div>た</div><div>ta</div></td>
|
||||
<td><div>さ</div><div>sa</div></td>
|
||||
<td><div>か</div><div>ka</div></td>
|
||||
<td><div>あ</div><div>a</div></td>
|
||||
</tr>
|
||||
|
||||
<tr class="い">
|
||||
<td><div>ぴ</div><div>pi</div></td>
|
||||
<td><div>び</div><div>bi</div></td>
|
||||
<td><div>ぢ</div><div>ji</div></td>
|
||||
<td><div>じ</div><div>ji</div></td>
|
||||
<td><div>ぎ</div><div>gi</div></td>
|
||||
<td class="empty"></td>
|
||||
<td class="empty"></td>
|
||||
<td class="empty"></td>
|
||||
<td><div>り</div><div>ri</div></td>
|
||||
<td class="empty"></td>
|
||||
<td><div>み</div><div>mi</div></td>
|
||||
<td><div>ひ</div><div>hi</div></td>
|
||||
<td><div>に</div><div>ni</div></td>
|
||||
<td><div>ち</div><div>chi</div></td>
|
||||
<td><div>し</div><div>shi</div></td>
|
||||
<td><div>き</div><div>ki</div></td>
|
||||
<td><div>い</div><div>i</div></td>
|
||||
</tr>
|
||||
|
||||
<tr class="う">
|
||||
<td><div>ぷ</div><div>pu</div></td>
|
||||
<td><div>ぶ</div><div>bu</div></td>
|
||||
<td><div>づ</div><div>zu</div></td>
|
||||
<td><div>ず</div><div>zu</div></td>
|
||||
<td><div>ぐ</div><div>gu</div></td>
|
||||
<td class="empty"></td>
|
||||
<td class="empty"></td>
|
||||
<td class="empty"></td>
|
||||
<td><div>る</div><div>ru</div></td>
|
||||
<td><div>ゆ</div><div>yu</div></td>
|
||||
<td><div>む</div><div>mu</div></td>
|
||||
<td><div>ふ</div><div>fu</div></td>
|
||||
<td><div>ぬ</div><div>nu</div></td>
|
||||
<td><div>つ</div><div>tsu</div></td>
|
||||
<td><div>す</div><div>su</div></td>
|
||||
<td><div>く</div><div>ku</div></td>
|
||||
<td><div>う</div><div>u</div></td>
|
||||
</tr>
|
||||
|
||||
<tr class="え">
|
||||
<td><div>ぺ</div><div>pe</div></td>
|
||||
<td><div>べ</div><div>be</div></td>
|
||||
<td><div>で</div><div>de</div></td>
|
||||
<td><div>ぜ</div><div>ze</div></td>
|
||||
<td><div>げ</div><div>ge</div></td>
|
||||
<td class="empty"></td>
|
||||
<td class="empty"></td>
|
||||
<td class="empty"></td>
|
||||
<td><div>れ</div><div>re</div></td>
|
||||
<td class="empty"></td>
|
||||
<td><div>め</div><div>me</div></td>
|
||||
<td><div>へ</div><div>he</div></td>
|
||||
<td><div>ね</div><div>ne</div></td>
|
||||
<td><div>て</div><div>te</div></td>
|
||||
<td><div>せ</div><div>se</div></td>
|
||||
<td><div>け</div><div>ke</div></td>
|
||||
<td><div>え</div><div>e</div></td>
|
||||
</tr>
|
||||
|
||||
<tr class="お">
|
||||
<td><div>ぽ</div><div>po</div></td>
|
||||
<td><div>ぼ</div><div>bo</div></td>
|
||||
<td><div>ど</div><div>do</div></td>
|
||||
<td><div>ぞ</div><div>zo</div></td>
|
||||
<td><div>ご</div><div>go</div></td>
|
||||
<td class="empty"></td>
|
||||
<td class="empty"></td>
|
||||
<td><div>を</div><div>o</div></td>
|
||||
<td><div>ろ</div><div>ro</div></td>
|
||||
<td><div>よ</div><div>yo</div></td>
|
||||
<td><div>も</div><div>mo</div></td>
|
||||
<td><div>ほ</div><div>ho</div></td>
|
||||
<td><div>の</div><div>no</div></td>
|
||||
<td><div>と</div><div>to</div></td>
|
||||
<td><div>そ</div><div>so</div></td>
|
||||
<td><div>こ</div><div>ko</div></td>
|
||||
<td><div>お</div><div>o</div></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
-->
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
576
conjugation/polv.js
Executable file
576
conjugation/polv.js
Executable file
@ -0,0 +1,576 @@
|
||||
// drill.js
|
||||
|
||||
var transformations = [
|
||||
{ from: "causative", to: "dictionary" },
|
||||
{ from: "causative negative", to: "dictionary" },
|
||||
{ from: "causative passive", to: "dictionary" },
|
||||
{ from: "causative passive negative", to: "dictionary" },
|
||||
{ from: "imperative", to: "dictionary" },
|
||||
{ from: "imperative negative", to: "dictionary" },
|
||||
{ from: "negative", to: "dictionary" },
|
||||
{ from: "passive", to: "dictionary" },
|
||||
{ from: "passive negative", to: "dictionary" },
|
||||
{ from: "past", to: "dictionary" },
|
||||
{ from: "past negative", to: "dictionary" },
|
||||
{ from: "polite", to: "dictionary" },
|
||||
{ from: "polite negative", to: "dictionary" },
|
||||
{ from: "polite past", to: "dictionary" },
|
||||
{ from: "polite past negative", to: "dictionary" },
|
||||
{ from: "polite progressive", to: "dictionary" },
|
||||
{ from: "polite progressive negative", to: "dictionary" },
|
||||
{ from: "polite progressive past", to: "dictionary" },
|
||||
{ from: "polite progressive past negative", to: "dictionary" },
|
||||
{ from: "potential", to: "dictionary" },
|
||||
{ from: "potential negative", to: "dictionary" },
|
||||
{ from: "progressive", to: "dictionary" },
|
||||
{ from: "progressive negative", to: "dictionary" },
|
||||
{ from: "progressive past", to: "dictionary" },
|
||||
{ from: "progressive past negative", to: "dictionary" },
|
||||
{ from: "te-form", to: "dictionary" },
|
||||
{ from: "te-form negative", to: "dictionary" },
|
||||
];
|
||||
|
||||
var log;
|
||||
|
||||
Array.prototype.randomElement = function () {
|
||||
return this[Math.floor(Math.random() * this.length)]
|
||||
}
|
||||
|
||||
// From: http://stackoverflow.com/a/2897510
|
||||
|
||||
new function ($) {
|
||||
$.fn.getCursorPosition = function () {
|
||||
var input = this.get(0);
|
||||
if (!input) return; // No (input) element found
|
||||
if ('selectionStart' in input) {
|
||||
// Standard-compliant browsers
|
||||
return input.selectionStart;
|
||||
} else if (document.selection) {
|
||||
// IE
|
||||
input.fmcus();
|
||||
var sel = document.selection.createRange();
|
||||
var selLen = document.selection.createRange().text.length;
|
||||
sel.moveStart('character', -input.value.length);
|
||||
return sel.text.length - selLen;
|
||||
}
|
||||
}
|
||||
}(jQuery);
|
||||
|
||||
// From: http://stackoverflow.com/questions/499126/jquery-set-cursor-position-in-text-area
|
||||
|
||||
new function ($) {
|
||||
$.fn.setCursorPosition = function (pos) {
|
||||
if (this.setSelectionRange) {
|
||||
this.setSelectionRange(pos, pos);
|
||||
} else if (this.createTextRange) {
|
||||
var range = this.createTextRange();
|
||||
range.collapse(true);
|
||||
if (pos < 0) {
|
||||
pos = $(this).val().length + pos;
|
||||
}
|
||||
range.moveEnd('character', pos);
|
||||
range.moveStart('character', pos);
|
||||
range.select();
|
||||
}
|
||||
}
|
||||
}(jQuery);
|
||||
|
||||
function commaList(items, conjunction) {
|
||||
|
||||
if (conjunction == undefined) {
|
||||
conjunction = "and";
|
||||
}
|
||||
|
||||
var result = "";
|
||||
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
result = result + items[i];
|
||||
|
||||
if (i < (items.length - 2)) {
|
||||
result += ", ";
|
||||
}
|
||||
|
||||
if (i == (items.length - 2)) {
|
||||
result += " " + conjunction + " ";
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function resetLog() {
|
||||
log = { "history": [] };
|
||||
}
|
||||
|
||||
function getVerbForms(entry) {
|
||||
|
||||
function kanaForm(words) {
|
||||
|
||||
if (words.constructor !== Array) {
|
||||
words = [words];
|
||||
}
|
||||
|
||||
return words.map(function (word) { return word.split(/.\[([^\]]*)\]/).join(""); } );
|
||||
}
|
||||
|
||||
function kanjiForm(words) {
|
||||
|
||||
if (words.constructor !== Array) {
|
||||
words = [words];
|
||||
}
|
||||
|
||||
return words.map(function (word) { return word.split(/(.)\[[^\]]*\]/).join(""); } );
|
||||
}
|
||||
|
||||
var result = {
|
||||
"kanji": {},
|
||||
"hiragana": {},
|
||||
"furigana": {}
|
||||
};
|
||||
|
||||
Object.keys(words[entry].conjugations).forEach(function (key) {
|
||||
result["kanji"][key] = kanjiForm(words[entry].conjugations[key]);
|
||||
result["hiragana"][key] = kanaForm(words[entry].conjugations[key]);
|
||||
result["furigana"][key] = words[entry].conjugations[key];
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function wordWithFurigana(words) {
|
||||
|
||||
if (words.constructor !== Array) {
|
||||
words = [words];
|
||||
}
|
||||
|
||||
return words.map(function (word) {
|
||||
|
||||
var bits = word.split(/(.)\[([^\]]*)\]/);
|
||||
|
||||
while (bits.length > 1) {
|
||||
bits[0] = bits[0] + "<span tooltip='" + bits[2] + "'>" + bits[1] + "</span>" + bits[3];
|
||||
bits.splice(1, 3);
|
||||
}
|
||||
|
||||
return bits[0];
|
||||
});
|
||||
}
|
||||
|
||||
function processAnswerKey() {
|
||||
|
||||
var el = $('#answer');
|
||||
|
||||
var pos = el.getCursorPosition();
|
||||
var val = el.val();
|
||||
|
||||
var last1 = val.slice(pos - 1, pos);
|
||||
var last2 = val.slice(pos - 2, pos);
|
||||
var last3 = val.slice(pos - 3, pos);
|
||||
|
||||
var replace1 = {
|
||||
"a": "あ", "i": "い", "u": "う", "e": "え", "o": "お"
|
||||
};
|
||||
|
||||
var replace2 = {
|
||||
|
||||
"ka": "か", "ki": "き", "ku": "く", "ke": "け", "ko": "こ",
|
||||
"sa": "さ", "si": "し", "su": "す", "se": "せ", "so": "そ",
|
||||
"ta": "た", "ti": "ち", "tu": "つ", "te": "て", "to": "と",
|
||||
"na": "な", "ni": "に", "nu": "ぬ", "ne": "ね", "no": "の",
|
||||
"ha": "は", "hi": "ひ", "hu": "ふ", "he": "へ", "ho": "ほ",
|
||||
"ma": "ま", "mi": "み", "mu": "む", "me": "め", "mo": "も",
|
||||
"ra": "ら", "ri": "り", "ru": "る", "re": "れ", "ro": "ろ",
|
||||
"ga": "が", "gi": "ぎ", "gu": "ぐ", "ge": "げ", "go": "ご",
|
||||
"za": "ざ", "zi": "じ", "zu": "ず", "ze": "ぜ", "zo": "ぞ",
|
||||
"da": "だ", "di": "ぢ", "du": "づ", "de": "で", "do": "ど",
|
||||
"ba": "ば", "bi": "び", "bu": "ぶ", "be": "べ", "bo": "ぼ",
|
||||
"pa": "ぱ", "pi": "ぴ", "pu": "ぷ", "pe": "ぺ", "po": "ぽ",
|
||||
|
||||
"qa": "くぁ", "qi": "くぃ", "qu": "く", "qe": "くぇ", "qo": "くぉ",
|
||||
"wa": "わ", "wi": "うぃ", "wu": "う", "we": "うぇ", "wo": "を",
|
||||
"ya": "や", "yi": "い", "yu": "ゆ", "ye": "いぇ", "yo": "よ",
|
||||
"fa": "ふぁ", "fi": "ふぃ", "fu": "ふ", "fe": "ふぇ", "fo": "ふぉ",
|
||||
"ja": "じゃ", "ji": "じ", "ju": "じゅ", "je": "じぇ", "jo": "じょ",
|
||||
"la": "ぁ", "li": "ぃ", "lu": "ぅ", "le": "ぇ", "lo": "ぉ",
|
||||
"za": "ざ", "zi": "じ", "zu": "ず", "ze": "ぜ", "zo": "ぞ",
|
||||
"xa": "ぁ", "xi": "ぃ", "xu": "ぅ", "xe": "ぇ", "xo": "ぉ",
|
||||
"ca": "か", "ci": "し", "cu": "く", "ce": "せ", "co": "こ",
|
||||
"va": "ヴぁ", "vi": "ヴぃ", "vu": "ヴ", "ve": "ヴぇ", "vo": "ヴぉ",
|
||||
|
||||
"lu": "っ",
|
||||
|
||||
"nn": "ん", "n'": "ん",
|
||||
|
||||
"nb": "んb", "nc": "んc", "nd": "んd", "nf": "んf", "ng": "んg",
|
||||
"nh": "んh", "nj": "んj", "nk": "んk", "nl": "んl", "nm": "んm",
|
||||
"np": "んp", "nq": "んq", "nr": "んr", "ns": "んs", "nt": "んt",
|
||||
"nv": "んv", "nw": "んw", "nx": "んx", "nz": "んz",
|
||||
|
||||
"aa": "っa", "bb": "っb", "cc": "っc", "dd": "っd", "ee": "っe",
|
||||
"ff": "っf", "gg": "っg", "hh": "っh", "ii": "っi", "jj": "っj",
|
||||
"kk": "っk", "ll": "っl", "mm": "っm", "oo": "っo", "pp": "っp",
|
||||
"qq": "っq", "rr": "っr", "ss": "っs", "tt": "っt", "uu": "っu",
|
||||
"vv": "っv", "ww": "っw", "xx": "っx", "yy": "っy", "zz": "っz",
|
||||
};
|
||||
|
||||
var replace3 = {
|
||||
|
||||
"kya": "きゃ", "kyi": "きぃ", "kyu": "きゅ", "kye": "きぇ", "kyo": "きょ",
|
||||
"sha": "しゃ", "shi": "し", "shu": "しゅ", "she": "しぇ", "sho": "しょ",
|
||||
"cha": "ちゃ", "chi": "ち", "chu": "ちゅ", "che": "ちぇ", "cho": "ちょ",
|
||||
"nya": "にゃ", "nyi": "にぃ", "nyu": "にゅ", "nye": "にぇ", "nyo": "にょ",
|
||||
"hya": "ひゃ", "hyi": "ひぃ", "hyu": "ひゅ", "hye": "ひぇ", "hyo": "ひょ",
|
||||
"mya": "みゃ", "myi": "みぃ", "myu": "みゅ", "mye": "みぇ", "myo": "みょ",
|
||||
"rya": "りゃ", "ryi": "りぃ", "ryu": "りゅ", "rye": "りぇ", "ryo": "りょ",
|
||||
"gya": "ぎゃ", "gyi": "ぎぃ", "gyu": "ぎゅ", "gye": "ぎぇ", "gyo": "ぎょ",
|
||||
"zya": "じゃ", "zyi": "じぃ", "zyu": "じゅ", "zye": "じぇ", "zyo": "じょ",
|
||||
"dya": "ぢゃ", "dyi": "ぢぃ", "dyu": "ぢゅ", "dye": "ぢぇ", "dyo": "ぢょ",
|
||||
"bya": "びゃ", "byi": "びぃ", "byu": "びゅ", "bye": "びぇ", "byo": "びょ",
|
||||
"pya": "ぴゃ", "pyi": "ぴぃ", "pyu": "ぴゅ", "pye": "ぴぇ", "pyo": "ぴょ",
|
||||
|
||||
"shi": "し",
|
||||
"tsu": "つ",
|
||||
};
|
||||
|
||||
if (replace3[last3]) {
|
||||
val = val.slice(0, pos - 3) + replace3[last3] + val.slice(pos, -1);
|
||||
el.val(val);
|
||||
el.setCursorPosition(pos - 3 + replace3[last3].length);
|
||||
} else if (replace2[last2]) {
|
||||
val = val.slice(0, pos - 2) + replace2[last2] + val.slice(pos, -1);
|
||||
el.val(val);
|
||||
el.setCursorPosition(pos - 2 + replace2[last2].length);
|
||||
} else if (replace1[last1]) {
|
||||
val = val.slice(0, pos - 1) + replace1[last1] + val.slice(pos, -1);
|
||||
el.val(val);
|
||||
el.setCursorPosition(pos - 1 + replace1[last1].length);
|
||||
}
|
||||
}
|
||||
|
||||
function validQuestion(entry, forms, transformation, options) {
|
||||
|
||||
var valid = true;
|
||||
|
||||
transformation.tags.forEach(function (type) {
|
||||
if (options[type] == false) {
|
||||
valid = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (options[words[entry].group] == false) {
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (!forms["furigana"][transformation.from])
|
||||
valid = false;
|
||||
|
||||
if (!forms["furigana"][transformation.to])
|
||||
valid = false;
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
function generateQuestion() {
|
||||
|
||||
var entry;
|
||||
var to_form;
|
||||
var from_form;
|
||||
var forms;
|
||||
|
||||
var count = 0;
|
||||
|
||||
while (true) {
|
||||
|
||||
if (count++ == 10000) {
|
||||
showSplash();
|
||||
return;
|
||||
}
|
||||
|
||||
entry = Object.keys(words).randomElement();
|
||||
transformation = transformations.randomElement();
|
||||
|
||||
from_form = transformation.from;
|
||||
to_form = transformation.to;
|
||||
|
||||
forms = getVerbForms(entry);
|
||||
|
||||
var valid = validQuestion(entry, forms, transformation, getOptions());
|
||||
|
||||
if (valid) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var kanjiForms = forms["kanji"];
|
||||
var kanaForms = forms["hiragana"];
|
||||
var furiganaForms = forms["furigana"];
|
||||
|
||||
var question = "What is the " + transformation.phrase + " form of " +
|
||||
wordWithFurigana(furiganaForms[from_form]).randomElement() + "?";
|
||||
|
||||
var answer = kanjiForms[to_form];
|
||||
var answer2 = kanaForms[to_form];
|
||||
|
||||
$('#question').html(question);
|
||||
|
||||
window.question = question;
|
||||
window.answer = kanjiForms[to_form];
|
||||
window.answerWithFurigana = wordWithFurigana(furiganaForms[to_form]);
|
||||
window.answer2 = answer2;
|
||||
|
||||
$('#next').prop('disabled', true);
|
||||
$('#response').html("");
|
||||
$('#message').html("");
|
||||
|
||||
$('#proceed').hide();
|
||||
$('#input').show();
|
||||
$('#answer').focus();
|
||||
|
||||
$('#answer').on('input', processAnswerKey);
|
||||
}
|
||||
|
||||
function processAnswer() {
|
||||
|
||||
var response = $('#answer').val().trim();
|
||||
|
||||
if (response == "")
|
||||
return;
|
||||
|
||||
var correct = ((window.answer.indexOf(response) != -1) || (window.answer2.indexOf(response) != -1));
|
||||
|
||||
var klass = correct ? "correct" : "incorrect";
|
||||
|
||||
log.history.push({
|
||||
"question": window.question,
|
||||
"response": response,
|
||||
"answer": window.answerWithFurigana,
|
||||
"kana": window.answer2,
|
||||
"correct": correct
|
||||
});
|
||||
|
||||
$('#answer').val("");
|
||||
$('#response').prop('class', klass).text(response);
|
||||
$('#next').prop('disabled', false);
|
||||
|
||||
if (correct) {
|
||||
$('#message').html("");
|
||||
} else {
|
||||
$('#message').html("<div>The correct answer was " + commaList(window.answerWithFurigana, "or") + "</div>");
|
||||
}
|
||||
|
||||
$('#input').hide();
|
||||
$('#proceed').show();
|
||||
$('#proceed button').focus();
|
||||
|
||||
updateHistoryView(log);
|
||||
}
|
||||
|
||||
function updateHistoryView(log) {
|
||||
|
||||
var review = $('<table>');
|
||||
|
||||
var total = 0;
|
||||
var correct = 0;
|
||||
|
||||
var header_tr = $('<tr>');
|
||||
|
||||
header_tr.append($('<th>Question</th>'));
|
||||
header_tr.append($('<th>Answer</th>'));
|
||||
header_tr.append($('<th>Response</th>'));
|
||||
|
||||
review.append(header_tr);
|
||||
|
||||
log.history.forEach(function (entry) {
|
||||
|
||||
total++;
|
||||
|
||||
if (entry.correct) {
|
||||
correct++;
|
||||
}
|
||||
|
||||
var tr = $('<tr>');
|
||||
|
||||
var td1 = $('<td>');
|
||||
var td2 = $('<td>');
|
||||
var td3 = $('<td>');
|
||||
|
||||
td1.html(entry.question);
|
||||
td2.html(commaList(entry.answer, "or"));
|
||||
td3.text(entry.response);
|
||||
|
||||
tr.append(td1);
|
||||
tr.append(td2);
|
||||
tr.append(td3);
|
||||
|
||||
if (entry.correct) {
|
||||
td3.append("<span class='answer-correct'> ○</span>");
|
||||
} else {
|
||||
td3.append("<span class='answer-wrong'> ×</span>");
|
||||
}
|
||||
review.append(tr);
|
||||
});
|
||||
|
||||
$('#history').empty().append(review);
|
||||
|
||||
$('#history').append("<p>" + correct + " of " + total + " correct.</p>");
|
||||
}
|
||||
|
||||
function proceed() {
|
||||
if (log.history.length == $('#numQuestions').val()) {
|
||||
endQuiz();
|
||||
} else {
|
||||
generateQuestion();
|
||||
}
|
||||
}
|
||||
|
||||
function showSplash() {
|
||||
$('#splash').show();
|
||||
$('#quizSection').hide();
|
||||
$('#scoreSection').hide();
|
||||
|
||||
$('#go').focus();
|
||||
}
|
||||
|
||||
function startQuiz() {
|
||||
$('#splash').hide();
|
||||
$('#quizSection').show();
|
||||
$('#scoreSection').hide();
|
||||
|
||||
resetLog();
|
||||
generateQuestion();
|
||||
}
|
||||
|
||||
function endQuiz() {
|
||||
$('#splash').hide();
|
||||
$('#quizSection').hide();
|
||||
$('#scoreSection').show();
|
||||
|
||||
$('#backToStart').focus();
|
||||
}
|
||||
|
||||
function arrayDifference(a, b) {
|
||||
// From http://stackoverflow.com/a/1723220
|
||||
return a.filter(function (x) { return b.indexOf(x) < 0 });
|
||||
}
|
||||
|
||||
function arrayUnique(arr) {
|
||||
return arr.filter(function (value, index, self) {
|
||||
return self.indexOf(value) === index;
|
||||
});
|
||||
}
|
||||
|
||||
function calculateTransitions() {
|
||||
|
||||
function getTags(str) {
|
||||
|
||||
var tags = str.split(" ");
|
||||
|
||||
if ((tags.length == 1) && (tags[0] == "plain")) {
|
||||
tags = [];
|
||||
}
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
function calculateTags(tags) {
|
||||
|
||||
tags = tags.split(" ");
|
||||
|
||||
if (tags.indexOf("polite") == -1) {
|
||||
tags.push("plain");
|
||||
}
|
||||
|
||||
if (tags.indexOf("dictionary") != -1) {
|
||||
tags.splice(tags.indexOf("dictionary"), 1);
|
||||
}
|
||||
|
||||
return tags;
|
||||
}
|
||||
|
||||
transformations.forEach(function (transformation) {
|
||||
|
||||
var from = getTags(transformation.from);
|
||||
var to = getTags(transformation.to);
|
||||
|
||||
var from_extra = {
|
||||
"negative": "affirmative",
|
||||
"past": "present",
|
||||
"polite": "plain",
|
||||
"te-form": "non-て",
|
||||
"potential": "non-potential",
|
||||
"imperative": "non-imperative",
|
||||
"causative": "non-causative",
|
||||
"passive": "active",
|
||||
"progressive": "non-progressive",
|
||||
};
|
||||
|
||||
var to_extra = {
|
||||
"negative": "negative",
|
||||
"past": "past",
|
||||
"polite": "polite",
|
||||
"te-form": "て",
|
||||
"potential": "potential",
|
||||
"imperative": "imperative",
|
||||
"causative": "causative",
|
||||
"passive": "passive",
|
||||
"progressive": "progressive",
|
||||
};
|
||||
|
||||
transformation.phrase = "dictionary";
|
||||
|
||||
transformation.tags = arrayUnique(calculateTags(transformation.from).concat(calculateTags(transformation.to)));
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function updateOptionSummary() {
|
||||
|
||||
// Calculate how many questions will apply
|
||||
|
||||
var options = getOptions();
|
||||
var applicable = 0;
|
||||
|
||||
Object.keys(words).forEach(function (word) {
|
||||
|
||||
var forms = getVerbForms(word);
|
||||
|
||||
transformations.forEach(function (transformation) {
|
||||
|
||||
if (validQuestion(word, forms, transformation, options)) {
|
||||
applicable++;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$("#questionCount").text(applicable);
|
||||
}
|
||||
|
||||
function getOptions() {
|
||||
|
||||
var options = ["plain", "polite", "negative", "past", "te-form",
|
||||
"progressive", "potential", "imperative", "passive", "causative",
|
||||
"godan", "ichidan", "iku", "kuru", "suru", "i-adjective", "na-adjective",
|
||||
"ii"];
|
||||
|
||||
var result = {};
|
||||
|
||||
options.forEach(function (option) {
|
||||
result[option] = $('#' + option).is(':checked') != false;
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
$('window').ready(function () {
|
||||
|
||||
calculateTransitions();
|
||||
|
||||
$('#go').click(startQuiz);
|
||||
$('#backToStart').click(showSplash);
|
||||
|
||||
$('div.options input').click(updateOptionSummary);
|
||||
|
||||
updateOptionSummary();
|
||||
|
||||
showSplash();
|
||||
});
|
1754
conjugation/polv_words.js
Normal file
1754
conjugation/polv_words.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,12 @@
|
||||
<html>
|
||||
<body>
|
||||
<a href="conjugation/drill.html">Japanese Conjugation Drill</a>
|
||||
<p>
|
||||
<a href="conjugation/drill.html">Japanese Conjugation Drill</a>.
|
||||
</p>
|
||||
<p>A couple of people wanted a <a href="conjugation/polv.html">special
|
||||
version</a> to go from any form to dictionary form to train themselves for
|
||||
speed-reading where dictionary look-up time is to be minimised. This isn't an
|
||||
advanced version as such, it's just a bit specialist! You're better off
|
||||
ignoring this one altogether.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user