future game and verb game cleanup

This commit is contained in:
lingdocs 2022-08-29 19:00:12 +04:00
parent 7c8d190582
commit 4583e733fa
8 changed files with 54 additions and 32 deletions

View File

@ -7,7 +7,7 @@
"@formkit/auto-animate": "^1.0.0-beta.1", "@formkit/auto-animate": "^1.0.0-beta.1",
"@fortawesome/fontawesome-free": "^5.15.4", "@fortawesome/fontawesome-free": "^5.15.4",
"@lingdocs/lingdocs-main": "^0.3.1", "@lingdocs/lingdocs-main": "^0.3.1",
"@lingdocs/pashto-inflector": "^3.7.9", "@lingdocs/pashto-inflector": "^3.8.3",
"@testing-library/jest-dom": "^5.11.4", "@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0", "@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10", "@testing-library/user-event": "^12.1.10",

View File

@ -14,7 +14,7 @@ function BlockDiagram({ opts, children }: {
try { try {
const rendered = children.type === "AP" const rendered = children.type === "AP"
? renderAPSelection(children) ? renderAPSelection(children)
: renderNPSelection(children, false, false, "subject", "none"); : renderNPSelection(children, false, false, "subject", "none", false);
const english = getEnglishFromRendered(rendered); const english = getEnglishFromRendered(rendered);
return <div className="mb-3"> return <div className="mb-3">
<div className="d-flex flex-row justify-content-center text-center" style={{ maxWidth: "100%" }}> <div className="d-flex flex-row justify-content-center text-center" style={{ maxWidth: "100%" }}>

View File

@ -14,6 +14,10 @@ import Formula from "../../components/formula/Formula";
import imperfectiveFuture from "./imperfective-future-graph.svg"; import imperfectiveFuture from "./imperfective-future-graph.svg";
import perfectiveFuture from "./perfective-future-graph.svg"; import perfectiveFuture from "./perfective-future-graph.svg";
import BasicVerbShowCase from "../../components/BasicVerbShowCase"; import BasicVerbShowCase from "../../components/BasicVerbShowCase";
import {
futureVerbGame,
} from "../../games/games";
import GameDisplay from "../../games/GameDisplay";
There are two kinds of future forms in Pashto: There are two kinds of future forms in Pashto:
@ -51,3 +55,5 @@ This is used to talk about something happening in the future, while thinking of
</Formula> </Formula>
<BasicVerbShowCase opts={opts} tense="perfectiveFuture" /> <BasicVerbShowCase opts={opts} tense="perfectiveFuture" />
<GameDisplay record={futureVerbGame} />

View File

@ -69,6 +69,7 @@ function GameCore<T>({ questions, Display, timeLimit, Instructions, studyLink, i
setJustStruck(true); setJustStruck(true);
} else { } else {
logGameEvent("fail on game"); logGameEvent("fail on game");
setJustStruck(false);
setFinish({ msg: "fail", answer: correct }); setFinish({ msg: "fail", answer: correct });
} }
} }
@ -126,7 +127,8 @@ function GameCore<T>({ questions, Display, timeLimit, Instructions, studyLink, i
setTimerKey(prev => prev + 1); setTimerKey(prev => prev + 1);
} }
function handleTimeOut() { function handleTimeOut() {
logGameEvent("timeout on game") logGameEvent("timeout on game");
setJustStruck(false);
setFinish("time out"); setFinish("time out");
navigator.vibrate(errorVibration); navigator.vibrate(errorVibration);
} }

View File

@ -29,6 +29,12 @@ export const subjunctiveVerbGame = makeGameRecord(
"/verbs/subjunctive-verbs/", "/verbs/subjunctive-verbs/",
(id, link) => () => <VerbGame id={id} level="subjunctiveVerb" link={link} /> (id, link) => () => <VerbGame id={id} level="subjunctiveVerb" link={link} />
); );
export const futureVerbGame = makeGameRecord(
"Write the future verb",
"future-verbs-write",
"/verbs/future-verbs/",
(id, link) => () => <VerbGame id={id} level="futureVerb" link={link} />
);
export const nounGenderGame1 = makeGameRecord( export const nounGenderGame1 = makeGameRecord(
"Identify Noun Genders - Level 1", "Identify Noun Genders - Level 1",
@ -156,6 +162,7 @@ const games: { chapter: string, items: GameRecord[] }[] = [
items: [ items: [
presentVerbGame, presentVerbGame,
subjunctiveVerbGame, subjunctiveVerbGame,
futureVerbGame,
], ],
} }
]; ];

View File

@ -168,7 +168,7 @@ const situations: Situation[] = [
}, },
]; ];
const amount = 15; const amount = 12;
const timeLimit = 100; const timeLimit = 100;
type Question = { type Question = {

View File

@ -25,6 +25,7 @@ import {
RootsAndStems, RootsAndStems,
getVerbInfo, getVerbInfo,
defaultTextOptions, defaultTextOptions,
humanReadableVerbForm,
} from "@lingdocs/pashto-inflector"; } from "@lingdocs/pashto-inflector";
import { isThirdPerson } from "@lingdocs/pashto-inflector/dist/lib/phrase-building/vp-tools"; import { isThirdPerson } from "@lingdocs/pashto-inflector/dist/lib/phrase-building/vp-tools";
import { maybeShuffleArray } from "../../lib/shuffle-array"; import { maybeShuffleArray } from "../../lib/shuffle-array";
@ -33,7 +34,7 @@ import { getVerbFromBlocks } from "@lingdocs/pashto-inflector/dist/lib/phrase-bu
const kidsColor = "#017BFE"; const kidsColor = "#017BFE";
const amount = 10; const amount = 10;
const timeLimit = 80; const timeLimit = 150;
type Question = { type Question = {
rendered: T.VPRendered, rendered: T.VPRendered,
@ -46,6 +47,7 @@ const verbs: T.VerbEntry[] = [
{"ts":1527812275,"i":11608,"p":"لیدل","f":"leedul","g":"leedul","e":"to see","c":"v. trans./gramm. trans.","psp":"وین","psf":"ween","tppp":"لید","tppf":"leed","ec":"see,sees,seeing,saw,seen"}, {"ts":1527812275,"i":11608,"p":"لیدل","f":"leedul","g":"leedul","e":"to see","c":"v. trans./gramm. trans.","psp":"وین","psf":"ween","tppp":"لید","tppf":"leed","ec":"see,sees,seeing,saw,seen"},
{"ts":1577049208257,"i":1068,"p":"اورېدل","f":"awredul","g":"awredul","e":"to hear, listen","c":"v. trans./gramm. trans.","psp":"اور","psf":"awr","tppp":"اورېد","tppf":"awred","ec":"hear,hears,hearing,heard"}, {"ts":1577049208257,"i":1068,"p":"اورېدل","f":"awredul","g":"awredul","e":"to hear, listen","c":"v. trans./gramm. trans.","psp":"اور","psf":"awr","tppp":"اورېد","tppf":"awred","ec":"hear,hears,hearing,heard"},
{"ts":1527812790,"i":5813,"p":"خوړل","f":"khoRul","g":"khoRul","e":"to eat, to bite","c":"v. trans.","psp":"خور","psf":"khor","tppp":"خوړ","tppf":"khoR","ec":"eat,eats,eating,ate,eaten"}, {"ts":1527812790,"i":5813,"p":"خوړل","f":"khoRul","g":"khoRul","e":"to eat, to bite","c":"v. trans.","psp":"خور","psf":"khor","tppp":"خوړ","tppf":"khoR","ec":"eat,eats,eating,ate,eaten"},
{"ts":1527812447,"i":292,"p":"اخستل","f":"akhistúl, akhustúl","g":"akhistul,akhustul","e":"to take, buy, purchase, receive; to shave, cut with scissors","c":"v. trans.","psp":"اخل","psf":"akhl","tppp":"اخست","tppf":"akhist","ec":"take,takes,taking,took,taken"},
].map(entry => ({ entry })) as T.VerbEntry[]; ].map(entry => ({ entry })) as T.VerbEntry[];
// @ts-ignore // @ts-ignore
const nouns: T.NounEntry[] = [ const nouns: T.NounEntry[] = [
@ -68,7 +70,13 @@ const pronounTypes = [
[T.Person.ThirdPlurMale, T.Person.ThirdPlurFemale], [T.Person.ThirdPlurMale, T.Person.ThirdPlurFemale],
]; ];
export default function VerbGame({ id, link, level }: { id: string, link: string, level: T.VerbTense }) { type VerbGameLevel = "presentVerb" | "subjunctiveVerb" | "futureVerb";
export default function VerbGame({ id, link, level }: {
id: string,
link: string,
level: VerbGameLevel,
}) {
function* questions (): Generator<Current<Question>> { function* questions (): Generator<Current<Question>> {
let pool = [...pronounTypes]; let pool = [...pronounTypes];
function getRandPersFromPool(): T.Person { function getRandPersFromPool(): T.Person {
@ -133,13 +141,13 @@ export default function VerbGame({ id, link, level }: { id: string, link: string
}); });
} }
for (let i = 0; i < amount; i++) { for (let i = 0; i < amount; i++) {
const VPS = makeRandomVPS(level); const VPS = makeRandomVPS(levelToTense(level));
const VP = renderVP(VPS); const VP = renderVP(VPS);
const compiled = compileVP( const compiled = compileVP(
VP, VP,
{ removeKing: false, shrinkServant: false }, { removeKing: false, shrinkServant: false },
true, true,
"verb", { ba: true, verb: true },
); );
const phrase = { const phrase = {
ps: compiled.ps, ps: compiled.ps,
@ -217,7 +225,7 @@ export default function VerbGame({ id, link, level }: { id: string, link: string
function Instructions() { function Instructions() {
return <div> return <div>
<p className="lead">Write the {humanReadableVerbTense(level)} verb to complete the phrase</p> <p className="lead">Write the {levelToDescription(level)} verb to complete the phrase</p>
</div> </div>
} }
@ -242,18 +250,19 @@ function QuestionDisplay({ question }: { question: Question }) {
? infoV.stative ? infoV.stative
: infoV; : infoV;
return <div className="mb-3"> return <div className="mb-3">
<div className="lead mb-2">{vEntry.p} - {removeFVarients(vEntry.f)} "{getEnglishVerb(vEntry)}"</div> <div className="mb-2">{vEntry.p} - {removeFVarients(vEntry.f)} "{getEnglishVerb(vEntry)}"</div>
<details> <details style={{ marginBottom: 0 }}>
<summary>🌳 Show roots and stems</summary> <summary>🌳 Show roots and stems</summary>
<RootsAndStems info={info} textOptions={defaultTextOptions} /> <RootsAndStems info={info} textOptions={defaultTextOptions} />
</details> </details>
<div>{ps.p}</div> <div dir="rtl">{ps.p}</div>
<div>{ps.f}</div> <div dir="ltr">{ps.f}</div>
{question.phrase.e && <div className="text-muted mt-2"> {question.phrase.e && <div className="text-muted mt-2">
{question.phrase.e.map(x => <div key={Math.random()}> {question.phrase.e.map(x => <div key={Math.random()}>
{x} {x}
</div>)} </div>)}
</div>} </div>}
<div>{humanReadableVerbForm(v.block.tense)}</div>
</div>; </div>;
} }
@ -264,7 +273,7 @@ function makeCorrectAnswer(question: Question): JSX.Element {
[ [
...accum, ...accum,
...i > 0 ? [<span className="text-muted"> or </span>] : [], ...i > 0 ? [<span className="text-muted"> or </span>] : [],
<span>{curr.p}</span>, <span>{curr.p} - {curr.f}</span>,
] ]
)), [] as JSX.Element[])} )), [] as JSX.Element[])}
</div> </div>
@ -289,22 +298,20 @@ function makeCorrectAnswer(question: Question): JSX.Element {
// } // }
function humanReadableVerbTense(tense: T.VerbTense): string { function levelToDescription(level: VerbGameLevel): string {
return tense === "presentVerb" return level === "presentVerb"
? "present" ? "present"
: tense === "subjunctiveVerb" : level === "subjunctiveVerb"
? "subjunctive" ? "subjunctive"
: tense === "imperfectiveFuture" : "imperfective future or perfective future"
? "imperfective future" }
: tense === "perfectiveFuture"
? "perfective future" function levelToTense(level: VerbGameLevel): T.VerbTense {
: tense === "perfectivePast" return level === "presentVerb"
? "simple past" ? level
: tense === "imperfectivePast" : level === "subjunctiveVerb"
? "continuous past" ? level
: tense === "habitualImperfectivePast" : randFromArray(["perfectiveFuture", "imperfectiveFuture"]);
? "habitual simple past"
: "habitual continuous past";
} }
function makeVPS({ verb, subject, object, tense }: { function makeVPS({ verb, subject, object, tense }: {

View File

@ -1803,10 +1803,10 @@
rambda "^6.7.0" rambda "^6.7.0"
react-select "^5.2.2" react-select "^5.2.2"
"@lingdocs/pashto-inflector@^3.7.9": "@lingdocs/pashto-inflector@^3.8.3":
version "3.7.9" version "3.8.3"
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-3.7.9.tgz#a1dc7b6635d9415d8dddfee9a09bb5b95190d7f0" resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-3.8.3.tgz#c549a3f3d33efc3ab18fab79160b9db8558e4a10"
integrity sha512-2LKY5TRUs9h7nE9gQaUUiNV0eLOh5Tr4eJtYp2RGaxeMZhOZhVbbiXc+FV2BPe9bOEpYK3hy678RLBIx0C18nQ== integrity sha512-gvvKiiIeBXVaua84Fj+F3F+ZgHWIMV393NgTX1Kt48bQWU+704igiClZmOu6p1lxWOsOwdVslER1rCoYhvnSbQ==
dependencies: dependencies:
"@formkit/auto-animate" "^1.0.0-beta.1" "@formkit/auto-animate" "^1.0.0-beta.1"
classnames "^2.2.6" classnames "^2.2.6"