From b0e1789914564017e95afdd3f7873b439aa1fb3c Mon Sep 17 00:00:00 2001 From: lingdocs <71590811+lingdocs@users.noreply.github.com> Date: Sat, 10 Sep 2022 15:42:09 +0400 Subject: [PATCH] verb formulas game --- src/content/verbs/master-chart.mdx | 1 + src/games/sub-cores/VerbFormulas.tsx | 117 ++++++++++++++++++++++----- 2 files changed, 97 insertions(+), 21 deletions(-) diff --git a/src/content/verbs/master-chart.mdx b/src/content/verbs/master-chart.mdx index ab5892f..0971f6e 100644 --- a/src/content/verbs/master-chart.mdx +++ b/src/content/verbs/master-chart.mdx @@ -4,6 +4,7 @@ title: Verb Forms Master Chart import { Camera, Video } from "../../components/terms-links"; import Link from "../../components/Link"; +import GameDisplay from "../../games/GameDisplay"; ## Basic Verb Tenses diff --git a/src/games/sub-cores/VerbFormulas.tsx b/src/games/sub-cores/VerbFormulas.tsx index fdcaa56..0d3ea24 100644 --- a/src/games/sub-cores/VerbFormulas.tsx +++ b/src/games/sub-cores/VerbFormulas.tsx @@ -9,20 +9,22 @@ import { import { makePool } from "../../lib/pool"; import { CSSProperties, useEffect, useState } from "react"; import classNames from "classnames"; +import { isImperativeTense } from "@lingdocs/pashto-inflector/dist/lib/type-predicates"; -const amount = 10; -const timeLimit = 60; +const amount = 12; +const timeLimit = 125; type StemRoot = "imperfective stem" | "perfective stem" | "imperfective root" | "perfective root"; type Ending = "present" | "past" | "imperative"; type Formula = { ba: boolean, + mu: boolean, stemRoot: StemRoot, ending: Ending, }; type Question = { - tense: T.VerbTense, + tense: T.VerbTense | T.ImperativeTense | "negative imperative", formula: Formula, } @@ -31,6 +33,7 @@ const questions: Question[] = [ tense: "presentVerb", formula: { ba: false, + mu: false, stemRoot: "imperfective stem", ending: "present", }, @@ -39,6 +42,7 @@ const questions: Question[] = [ tense: "subjunctiveVerb", formula: { ba: false, + mu: false, stemRoot: "perfective stem", ending: "present", }, @@ -47,6 +51,7 @@ const questions: Question[] = [ tense: "imperfectiveFuture", formula: { ba: true, + mu: false, stemRoot: "imperfective stem", ending: "present", }, @@ -55,6 +60,7 @@ const questions: Question[] = [ tense: "perfectiveFuture", formula: { ba: true, + mu: false, stemRoot: "perfective stem", ending: "present", }, @@ -63,6 +69,7 @@ const questions: Question[] = [ tense: "imperfectivePast", formula: { ba: false, + mu: false, stemRoot: "imperfective root", ending: "past", }, @@ -71,6 +78,7 @@ const questions: Question[] = [ tense: "perfectivePast", formula: { ba: false, + mu: false, stemRoot: "perfective root", ending: "past", }, @@ -79,6 +87,7 @@ const questions: Question[] = [ tense: "habitualImperfectivePast", formula: { ba: true, + mu: false, stemRoot: "imperfective root", ending: "past", }, @@ -87,10 +96,38 @@ const questions: Question[] = [ tense: "habitualPerfectivePast", formula: { ba: true, + mu: false, stemRoot: "perfective root", ending: "past", }, }, + { + tense: "perfectiveImperative", + formula: { + ba: false, + mu: false, + stemRoot: "perfective stem", + ending: "imperative", + }, + }, + { + tense: "imperfectiveImperative", + formula: { + ba: false, + mu: false, + stemRoot: "imperfective stem", + ending: "imperative", + }, + }, + { + tense: "negative imperative", + formula: { + ba: false, + mu: true, + stemRoot: "imperfective stem", + ending: "imperative", + }, + } ]; export default function VerbFormulas({ inChapter, id, link, level }: { inChapter: boolean, id: string, link: string, level: "all" }) { @@ -101,7 +138,6 @@ export default function VerbFormulas({ inChapter, id, link, level }: { inChapter function Instructions() { return

Pick the formula for each verb tense

; } - return ) { const [ba, setBa] = useState(false); + const [mu, setMu] = useState(false); const [stemRoot, setStemRoot] = useState(""); const [ending, setEnding] = useState(""); useEffect(() => { setBa(false); setStemRoot(""); setEnding(""); + setMu(false); }, [question]); const canSubmit = !!(stemRoot && ending); + const showMu = question.tense === "negative imperative" || isImperativeTense(question.tense); function handleSubmit() { const { formula } = question; callback( (ba === formula.ba) && + (mu === formula.mu) + && (stemRoot === formula.stemRoot) && (ending === formula.ending) @@ -138,13 +179,14 @@ function Display({ question, callback }: QuestionDisplayProps) { return

- {humanReadableVerbForm(question.tense)} + {humanReadableT(question.tense)}

- - - + + {showMu && } + +
- {canSubmit ? printFormula({ ba, stemRoot, ending }) : " "} + {printFormula({ ba, stemRoot, ending, mu })}
} -function printFormula(f: Formula): string { - return `${f.ba ? "ba + " : ""}${f.stemRoot} + ${f.ending} ending`; +function humanReadableT(tense: T.VerbTense | T.ImperativeTense | "negative imperative"): string { + if (tense === "negative imperative") { + return tense; + } + return humanReadableVerbForm(tense); +} + +function printFormula({ mu, ba, stemRoot, ending }: { + mu: boolean, + ba: boolean, + stemRoot: StemRoot | "", + ending: Ending | "", +}): string { + const elements = [ + mu ? "mu" : undefined, + ba ? "ba" : undefined, + stemRoot, + ending ? `${ending} ending` : undefined, + ].filter(x => x) as string[]; + return elements.join(" + "); } function DisplayCorrectAnswer({ question }: { question: Question }): JSX.Element { @@ -167,7 +227,7 @@ function DisplayCorrectAnswer({ question }: { question: Question }): JSX.Element ; } -function EndingPicker({ onChange, ending }: { ending: Ending | "", onChange: (e: Ending | "") => void }) { +function EndingPicker({ onChange, value }: { value: Ending | "", onChange: (e: Ending | "") => void }) { const options: { label: string, value: Ending }[] = [ { label: "Present", value: "present" }, { label: "Past", value: "past" }, @@ -187,7 +247,7 @@ function EndingPicker({ onChange, ending }: { ending: Ending | "", onChange: (e: className={classNames( "btn", "btn-outline-secondary", - { active: ending === option.value }, + { active: value === option.value }, )} onClick={() => handleClick(option.value)} > @@ -198,13 +258,13 @@ function EndingPicker({ onChange, ending }: { ending: Ending | "", onChange: (e: ; } -function BaPicker({ onChange, hasBa }: { hasBa: boolean, onChange: (b: boolean) => void }) { +function BaPicker({ onChange, value }: { value: boolean, onChange: (b: boolean) => void }) { return
onChange(e.target.checked)} />
} -function RootsAndStemsPicker({ onChange, stemRoot }: { stemRoot: StemRoot | "", onChange: (s: StemRoot | "" ) => void }) { +function MuPicker({ onChange, value }: { value: boolean, onChange: (b: boolean) => void }) { + return
+ onChange(e.target.checked)} + /> + +
+} + +function RootsAndStemsPicker({ onChange, value }: { value: StemRoot | "", onChange: (s: StemRoot | "" ) => void }) { const colClass = "col col-md-5 px-0 mb-1"; const rowClass = "row justify-content-between"; const title: CSSProperties = { @@ -225,7 +300,7 @@ function RootsAndStemsPicker({ onChange, stemRoot }: { stemRoot: StemRoot | "", background: "rgba(255, 227, 10, 0.6)", }; function handleStemRootClick(s: StemRoot) { - onChange(stemRoot === s ? "" : s); + onChange(value === s ? "" : s); } return
-
+
handleStemRootClick("imperfective stem")}>
Imperfective Stem
-
+
handleStemRootClick("perfective stem")}>
Perfective Stem
-
+
handleStemRootClick("imperfective root")}>
Imperfective Root
-
+
handleStemRootClick("perfective root")}>
Perfective Root