really basic present and subjunctive verb games
This commit is contained in:
parent
55512ce788
commit
1c3f9c2f62
|
@ -7,7 +7,7 @@
|
|||
"@formkit/auto-animate": "^1.0.0-beta.1",
|
||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||
"@lingdocs/lingdocs-main": "^0.3.1",
|
||||
"@lingdocs/pashto-inflector": "^3.7.6",
|
||||
"@lingdocs/pashto-inflector": "^3.7.9",
|
||||
"@testing-library/jest-dom": "^5.11.4",
|
||||
"@testing-library/react": "^11.1.0",
|
||||
"@testing-library/user-event": "^12.1.10",
|
||||
|
|
|
@ -13,6 +13,10 @@ import Formula from "../../components/formula/Formula";
|
|||
import realityGraph from "./reality-graph.svg";
|
||||
import presentTime from "./present-time.svg";
|
||||
import BasicVerbShowCase from "./../../components/BasicVerbShowCase";
|
||||
import {
|
||||
presentVerbGame,
|
||||
} from "../../games/games";
|
||||
import GameDisplay from "../../games/GameDisplay";
|
||||
|
||||
The first verb form we'll learn is the **present**. This will be the first tool in our toolbox of verb forms. 🧰 With each verb form we'll learn two things:
|
||||
|
||||
|
@ -118,4 +122,6 @@ Here are some examples of how the present form is used in different situations:
|
|||
},
|
||||
])}</Examples>
|
||||
|
||||
<GameDisplay record={presentVerbGame} />
|
||||
|
||||
|
||||
|
|
|
@ -15,6 +15,10 @@ import Formula from "../../components/formula/Formula";
|
|||
import presentInReality from "./present-in-reality.svg";
|
||||
import subjunctiveAboveReality from "./subjunctive-above-reality.svg";
|
||||
import BasicVerbShowCase from "../../components/BasicVerbShowCase";
|
||||
import {
|
||||
subjunctiveVerbGame,
|
||||
} from "../../games/games";
|
||||
import GameDisplay from "../../games/GameDisplay";
|
||||
|
||||
The **subjunctive** is a very important verb form in Pashto, but it's often ignored by English-speaking learners because we don't really have anything like it in English. So, we need to understand what it is, and then train our brains to reach for it and use it in the right situations!
|
||||
|
||||
|
@ -103,3 +107,5 @@ As you can see, the subjunctive is often used in [subordinate clauses](https://e
|
|||
- <InlinePs opts={opts} ps={{ p: "په کار دی چې ...", f: "pu kaar dey che ...", e: "It's necessary that ..." }} />
|
||||
|
||||
...etc.
|
||||
|
||||
<GameDisplay record={subjunctiveVerbGame} />
|
||||
|
|
|
@ -22,7 +22,13 @@ export const presentVerbGame = makeGameRecord(
|
|||
"present-verbs-write",
|
||||
"/verbs/present-verbs/",
|
||||
(id, link) => () => <VerbGame id={id} level="presentVerb" link={link} />
|
||||
)
|
||||
);
|
||||
export const subjunctiveVerbGame = makeGameRecord(
|
||||
"Write the subjunctive verb",
|
||||
"subjunctive-verbs-write",
|
||||
"/verbs/subjunctive-verbs/",
|
||||
(id, link) => () => <VerbGame id={id} level="subjunctiveVerb" link={link} />
|
||||
);
|
||||
|
||||
export const nounGenderGame1 = makeGameRecord(
|
||||
"Identify Noun Genders - Level 1",
|
||||
|
@ -149,6 +155,7 @@ const games: { chapter: string, items: GameRecord[] }[] = [
|
|||
chapter: "Verbs",
|
||||
items: [
|
||||
presentVerbGame,
|
||||
subjunctiveVerbGame,
|
||||
],
|
||||
}
|
||||
];
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
comparePs,
|
||||
makeProgress,
|
||||
|
@ -6,26 +6,23 @@ import {
|
|||
import GameCore from "../GameCore";
|
||||
import {
|
||||
Types as T,
|
||||
Examples,
|
||||
defaultTextOptions as opts,
|
||||
typePredicates as tp,
|
||||
makeNounSelection,
|
||||
randFromArray,
|
||||
renderEP,
|
||||
compileEP,
|
||||
flattenLengths,
|
||||
randomPerson,
|
||||
InlinePs,
|
||||
grammarUnits,
|
||||
randomSubjObj,
|
||||
renderVP,
|
||||
makeVPSelectionState,
|
||||
compileVP,
|
||||
blockUtils,
|
||||
concatPsString,
|
||||
isInvalidSubjObjCombo,
|
||||
} from "@lingdocs/pashto-inflector";
|
||||
import { basicVerbs, intransitivePast } from "../../content/verbs/basic-present-verbs";
|
||||
import { psStringEquals } from "@lingdocs/pashto-inflector/dist/lib/p-text-helpers";
|
||||
import { isThirdPerson } from "@lingdocs/pashto-inflector/dist/lib/phrase-building/vp-tools";
|
||||
import { maybeShuffleArray } from "../../lib/shuffle-array";
|
||||
|
||||
const kidsColor = "#017BFE";
|
||||
|
||||
|
@ -37,6 +34,12 @@ type Question = {
|
|||
phrase: { ps: T.SingleOrLengthOpts<T.PsString[]>, e?: string[] },
|
||||
};
|
||||
|
||||
const verbs: T.VerbEntry[] = [
|
||||
{"ts":1527812856,"i":11630,"p":"لیکل","f":"leekul","g":"leekul","e":"to write, draw","c":"v. trans./gramm. trans.","ec":"write,writes,writing,wrote,written"},
|
||||
{"ts":1527815399,"i":14480,"p":"وهل","f":"wahul","g":"wahul","e":"to hit","c":"v. trans.","tppp":"واهه","tppf":"waahu","ec":"hit,hits,hitting,hit,hit"},
|
||||
{"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"},
|
||||
].map(entry => ({ entry })) as T.VerbEntry[];
|
||||
// @ts-ignore
|
||||
const nouns: T.NounEntry[] = [
|
||||
{"ts":1527815251,"i":7790,"p":"سړی","f":"saRéy","g":"saRey","e":"man","c":"n. m.","ec":"man","ep":"men"},
|
||||
|
@ -61,7 +64,7 @@ const pronounTypes = [
|
|||
export default function VerbGame({ id, link, level }: { id: string, link: string, level: T.VerbTense }) {
|
||||
function* questions (): Generator<Current<Question>> {
|
||||
let pool = [...pronounTypes];
|
||||
function makeRandPronoun(): T.PronounSelection {
|
||||
function getRandPersFromPool(): T.Person {
|
||||
let person: T.Person;
|
||||
do {
|
||||
person = randomPerson();
|
||||
|
@ -71,11 +74,7 @@ export default function VerbGame({ id, link, level }: { id: string, link: string
|
|||
if (pool.length === 0) {
|
||||
pool = pronounTypes;
|
||||
}
|
||||
return {
|
||||
type: "pronoun",
|
||||
distance: "far",
|
||||
person,
|
||||
};
|
||||
return person;
|
||||
}
|
||||
function makeRandomNoun(): T.NounSelection {
|
||||
const n = makeNounSelection(randFromArray(nouns), undefined);
|
||||
|
@ -86,43 +85,48 @@ export default function VerbGame({ id, link, level }: { id: string, link: string
|
|||
};
|
||||
}
|
||||
function makeRandomVPS(l: T.VerbTense): T.VPSelectionComplete {
|
||||
function makePronoun(p: T.Person): T.PronounSelection {
|
||||
function personToNPSelection(p: T.Person): T.NPSelection {
|
||||
if (!isThirdPerson(p)) {
|
||||
return {
|
||||
type: "NP",
|
||||
selection: randFromArray([
|
||||
() => makePronounS(p),
|
||||
makeRandomNoun,
|
||||
() => makePronounS(p),
|
||||
])(),
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: "NP",
|
||||
selection: makePronounS(p),
|
||||
};
|
||||
}
|
||||
function makePronounS(p: T.Person): T.PronounSelection {
|
||||
return {
|
||||
type: "pronoun",
|
||||
person: p,
|
||||
distance: "far",
|
||||
distance: randFromArray(["far", "near", "far"]),
|
||||
};
|
||||
}
|
||||
function makeNPSelection(pr: T.PronounSelection): T.NPSelection {
|
||||
return {
|
||||
type: "NP",
|
||||
selection: pr,
|
||||
};
|
||||
}
|
||||
const verb = randFromArray(basicVerbs);
|
||||
const { subj, obj } = randomSubjObj();
|
||||
// const subj: T.NPSelection = {
|
||||
// type: "NP",
|
||||
// selection: randFromArray([
|
||||
// makeRandPronoun,
|
||||
// makeRandPronoun,
|
||||
// makeRandomNoun,
|
||||
// makeRandPronoun,
|
||||
// ])(),
|
||||
// };
|
||||
const verb = randFromArray(verbs);
|
||||
const subj = getRandPersFromPool();
|
||||
let obj: T.Person;
|
||||
do {
|
||||
obj = randomPerson();
|
||||
} while (isInvalidSubjObjCombo(subj, obj));
|
||||
// const tense = (l === "allIdentify" || l === "allProduce")
|
||||
// ? randFromArray(tenses)
|
||||
// : l;
|
||||
const tense = l;
|
||||
return makeVPS({
|
||||
verb,
|
||||
subject: makeNPSelection(makePronoun(subj)),
|
||||
object: makeNPSelection(makePronoun(obj)),
|
||||
subject: personToNPSelection(subj),
|
||||
object: personToNPSelection(obj),
|
||||
tense,
|
||||
});
|
||||
}
|
||||
for (let i = 0; i < amount; i++) {
|
||||
const VPS = makeRandomVPS("presentVerb");
|
||||
const VPS = makeRandomVPS(level);
|
||||
const VP = renderVP(VPS);
|
||||
const compiled = compileVP(
|
||||
VP,
|
||||
|
@ -144,7 +148,6 @@ export default function VerbGame({ id, link, level }: { id: string, link: string
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
function Display({ question, callback }: QuestionDisplayProps<Question>) {
|
||||
const [answer, setAnswer] = useState<string>("");
|
||||
const [withBa, setWithBa] = useState<boolean>(false);
|
||||
|
@ -207,7 +210,7 @@ export default function VerbGame({ id, link, level }: { id: string, link: string
|
|||
|
||||
function Instructions() {
|
||||
return <div>
|
||||
<p className="lead">Write the present verb to complete the phrase</p>
|
||||
<p className="lead">Write the {humanReadableVerbTense(level)} verb to complete the phrase</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
@ -221,12 +224,12 @@ export default function VerbGame({ id, link, level }: { id: string, link: string
|
|||
/>
|
||||
};
|
||||
|
||||
function QuestionDisplay(question: Question) {
|
||||
function QuestionDisplay({ question }: { question: Question }) {
|
||||
const ps = flattenLengths(question.phrase.ps)[0];
|
||||
return <div>
|
||||
return <div className="mb-3">
|
||||
<div>{ps.p}</div>
|
||||
<div>{ps.f}</div>
|
||||
{question.phrase.e && <div>
|
||||
{question.phrase.e && <div className="text-muted mt-2">
|
||||
{question.phrase.e.map(x => <div key={Math.random()}>
|
||||
{x}
|
||||
</div>)}
|
||||
|
@ -248,33 +251,40 @@ function makeCorrectAnswer(question: Question): JSX.Element {
|
|||
<div><strong>{verbHasBa(question.rendered) ? "with" : "without"}</strong> a <InlinePs opts={opts}>{grammarUnits.baParticle}</InlinePs> in the kids' section.</div>
|
||||
</div>;
|
||||
}
|
||||
function modExs(exs: T.PsString[], withBa: boolean): { p: JSX.Element, f: JSX.Element }[] {
|
||||
return exs.map(ps => {
|
||||
if (!ps.p.includes(" ___ ")) {
|
||||
return {
|
||||
p: <>{ps.p}</>,
|
||||
f: <>{ps.f}</>,
|
||||
};
|
||||
}
|
||||
const splitP = ps.p.split(" ___ ");
|
||||
const splitF = ps.f.split(" ___ ");
|
||||
return {
|
||||
p: <>{splitP[0]} <span style={{ color: kidsColor }}>{withBa ? "به" : "__"}</span> {splitP[1]}</>,
|
||||
f: <>{splitF[0]} <span style={{ color: kidsColor }}>{withBa ? "ba" : "__"}</span> {splitF[1]}</>,
|
||||
};
|
||||
});
|
||||
}
|
||||
// function modExs(exs: T.PsString[], withBa: boolean): { p: JSX.Element, f: JSX.Element }[] {
|
||||
// return exs.map(ps => {
|
||||
// if (!ps.p.includes(" ___ ")) {
|
||||
// return {
|
||||
// p: <>{ps.p}</>,
|
||||
// f: <>{ps.f}</>,
|
||||
// };
|
||||
// }
|
||||
// const splitP = ps.p.split(" ___ ");
|
||||
// const splitF = ps.f.split(" ___ ");
|
||||
// return {
|
||||
// p: <>{splitP[0]} <span style={{ color: kidsColor }}>{withBa ? "به" : "__"}</span> {splitP[1]}</>,
|
||||
// f: <>{splitF[0]} <span style={{ color: kidsColor }}>{withBa ? "ba" : "__"}</span> {splitF[1]}</>,
|
||||
// };
|
||||
// });
|
||||
// }
|
||||
|
||||
function humanReadableTense(tense: T.EquativeTense | "allProduce"): string {
|
||||
return tense === "allProduce"
|
||||
? ""
|
||||
: tense === "pastSubjunctive"
|
||||
? "past subjunctive"
|
||||
: tense === "wouldBe"
|
||||
? `"would be"`
|
||||
: tense === "wouldHaveBeen"
|
||||
? `"would have been"`
|
||||
: tense;
|
||||
|
||||
function humanReadableVerbTense(tense: T.VerbTense): string {
|
||||
return tense === "presentVerb"
|
||||
? "present"
|
||||
: tense === "subjunctiveVerb"
|
||||
? "subjunctive"
|
||||
: tense === "imperfectiveFuture"
|
||||
? "imperfective future"
|
||||
: tense === "perfectiveFuture"
|
||||
? "perfective future"
|
||||
: tense === "perfectivePast"
|
||||
? "simple past"
|
||||
: tense === "imperfectivePast"
|
||||
? "continuous past"
|
||||
: tense === "habitualImperfectivePast"
|
||||
? "habitual simple past"
|
||||
: "habitual continuous past";
|
||||
}
|
||||
|
||||
function makeVPS({ verb, subject, object, tense }: {
|
||||
|
@ -284,13 +294,17 @@ function makeVPS({ verb, subject, object, tense }: {
|
|||
tense: T.VerbTense,
|
||||
}): T.VPSelectionComplete {
|
||||
const vps = makeVPSelectionState(verb);
|
||||
const transitivity = (vps.verb.transitivity === "transitive" && vps.verb.canChangeTransitivity)
|
||||
? "grammatically transitive"
|
||||
: vps.verb.transitivity;
|
||||
return {
|
||||
...vps,
|
||||
verb: {
|
||||
...vps.verb,
|
||||
transitivity,
|
||||
tense,
|
||||
},
|
||||
blocks: [
|
||||
blocks: maybeShuffleArray([
|
||||
{
|
||||
key: Math.random(),
|
||||
block: {
|
||||
|
@ -302,10 +316,14 @@ function makeVPS({ verb, subject, object, tense }: {
|
|||
key: Math.random(),
|
||||
block: {
|
||||
type: "objectSelection",
|
||||
selection: object,
|
||||
selection: transitivity === "intransitive"
|
||||
? "none"
|
||||
: transitivity === "grammatically transitive"
|
||||
? T.Person.ThirdPlurMale
|
||||
: object,
|
||||
},
|
||||
},
|
||||
],
|
||||
]),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// https://stackoverflow.com/a/2450976
|
||||
|
||||
import { randFromArray } from "@lingdocs/pashto-inflector";
|
||||
|
||||
function shuffleArray<T>(arr: Readonly<Array<T>>): Array<T> {
|
||||
let currentIndex = arr.length, temporaryValue, randomIndex;
|
||||
|
||||
|
@ -21,4 +23,12 @@ function shuffleArray<T>(arr: Readonly<Array<T>>): Array<T> {
|
|||
return array;
|
||||
}
|
||||
|
||||
export function maybeShuffleArray<T>(arr: Array<T>): Array<T> {
|
||||
const shuffle = randFromArray([true, false, true, false, false]);
|
||||
if (shuffle) {
|
||||
return shuffleArray(arr);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
export default shuffleArray;
|
|
@ -1803,10 +1803,10 @@
|
|||
rambda "^6.7.0"
|
||||
react-select "^5.2.2"
|
||||
|
||||
"@lingdocs/pashto-inflector@^3.7.5":
|
||||
version "3.7.5"
|
||||
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-3.7.5.tgz#6421b88ccf544cdbc7f4cefc66ff75b3b7f1bb44"
|
||||
integrity sha512-36ULd7ETZBz9/gs2K1s2XJFzEA3kDZfR9rPPN6B5oJvW9yAZXfgaJg9W2jzhodfu2WS3lpQvizis8zQjPioV8w==
|
||||
"@lingdocs/pashto-inflector@^3.7.9":
|
||||
version "3.7.9"
|
||||
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-3.7.9.tgz#a1dc7b6635d9415d8dddfee9a09bb5b95190d7f0"
|
||||
integrity sha512-2LKY5TRUs9h7nE9gQaUUiNV0eLOh5Tr4eJtYp2RGaxeMZhOZhVbbiXc+FV2BPe9bOEpYK3hy678RLBIx0C18nQ==
|
||||
dependencies:
|
||||
"@formkit/auto-animate" "^1.0.0-beta.1"
|
||||
classnames "^2.2.6"
|
||||
|
|
Loading…
Reference in New Issue