add unisex gender game
This commit is contained in:
parent
0410642492
commit
2fa773ab60
|
@ -4,7 +4,7 @@
|
|||
"private": true,
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.15.2",
|
||||
"@lingdocs/pashto-inflector": "^0.8.3",
|
||||
"@lingdocs/pashto-inflector": "^0.9.3",
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.3.2",
|
||||
"@testing-library/user-event": "^7.1.2",
|
||||
|
|
|
@ -16,7 +16,7 @@ const pConsonants = ["ب", "پ", "ت", "ټ", "ث", "ج", "چ", "ح", "خ", "څ",
|
|||
fetch(process.env.LINGDOCS_DICTIONARY_URL).then(res => res.arrayBuffer()).then(data => {
|
||||
const { entries } = readDictionary(data);
|
||||
const filtered = entries.filter(e => (
|
||||
e.c === "n. m." && ["ا", "ه", "ي"].includes(e.p.slice(-1)) && (!["u", "h"].includes(e.g.slice(-1)))
|
||||
e.c?.includes("n. m. unisex")
|
||||
));
|
||||
const content = `module.exports = [
|
||||
${filtered.reduce((text, entry) => (
|
||||
|
|
|
@ -56,7 +56,10 @@ export default function({level}: { level: 1 | 2 }) {
|
|||
? wordPool
|
||||
: getRandomFromList([wordPool, exceptions]);
|
||||
const gender = getRandomFromList(Object.keys(base));
|
||||
const typeToUse = getRandomFromList(Object.keys(base[gender]));
|
||||
let typeToUse: string;
|
||||
do {
|
||||
typeToUse = getRandomFromList(Object.keys(base[gender]));
|
||||
} while (!base[gender].length);
|
||||
const question = getRandomFromList(base[gender][typeToUse]).entry;
|
||||
base[gender][typeToUse] = base[gender][typeToUse].filter(({ entry }) => entry.ts !== question.ts);
|
||||
yield {
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
import React, { useState } from "react";
|
||||
import {
|
||||
getRandomFromList,
|
||||
makeProgress,
|
||||
} from "../lib/game-utils";
|
||||
import genderColors from "../lib/gender-colors";
|
||||
import Game from "./Game";
|
||||
import {
|
||||
Types as T,
|
||||
Examples,
|
||||
defaultTextOptions as opts,
|
||||
inflectWord,
|
||||
standardizePashto,
|
||||
removeAccents,
|
||||
// pashtoConsonants,
|
||||
} from "@lingdocs/pashto-inflector";
|
||||
import words from "../words/nouns-adjs";
|
||||
import {
|
||||
firstVariation,
|
||||
} from "../lib/text-tools";
|
||||
|
||||
const nouns = words.filter((w) => w.category === "nouns-unisex").map(x => x.entry);
|
||||
// type NType = "consonant" | "eyUnstressed" | "eyStressed" | "pashtun" | "withu"
|
||||
// const types: Record<NType, T.DictionaryEntry[]> = {
|
||||
// consonant: nouns.filter((w) => pashtoConsonants.includes(w.p.slice(-1))),
|
||||
// eyUnstressed: nouns.filter((w) => w.f.slice(-2) === "ey"),
|
||||
// eyStressed: nouns.filter((w) => w.f.slice(-2) === "éy"),
|
||||
// pashtun: nouns.filter((w) => w.infaf?.includes("aa")),
|
||||
// withu: nouns.filter((w) => w.infaf?.slice(-1) === "u" && !!w.infaf?.includes("aa")),
|
||||
// }
|
||||
const genders: T.Gender[] = ["masc", "fem"];
|
||||
|
||||
const amount = 20;
|
||||
|
||||
type Question = { entry: T.DictionaryEntry, gender: T.Gender };
|
||||
|
||||
export default function() {
|
||||
function* questions (): Generator<Current<Question>> {
|
||||
let pool = [...nouns];
|
||||
for (let i = 0; i < amount; i++) {
|
||||
// const keys = Object.keys(types) as NType[];
|
||||
// let type: NType
|
||||
// do {
|
||||
// type = getRandomFromList(keys);
|
||||
// } while (!pool[type].length);
|
||||
const entry = getRandomFromList(pool);
|
||||
const gender = getRandomFromList(genders) as T.Gender;
|
||||
pool = pool.filter((x) => x.ts !== entry.ts);
|
||||
yield {
|
||||
progress: makeProgress(i, amount),
|
||||
question: {
|
||||
entry,
|
||||
gender,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function Display({ question, callback }: QuestionDisplayProps<Question>) {
|
||||
function flipGender(g: T.Gender): T.Gender {
|
||||
return g === "masc" ? "fem" : "masc";
|
||||
}
|
||||
const [answer, setAnswer] = useState<string>("");
|
||||
const inflected = inflectWord(question.entry) as T.UnisexInflections;
|
||||
const givenGender = question.gender === "masc" ? "masculine" : "feminine";
|
||||
const requiredGender = question.gender === "fem" ? "masculine" : "feminine";
|
||||
if (!inflected || !inflected.masc || !inflected.fem) {
|
||||
return <div>WORD ERROR</div>;
|
||||
}
|
||||
function handleInput({ target: { value }}: React.ChangeEvent<HTMLInputElement>) {
|
||||
setAnswer(value);
|
||||
}
|
||||
function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
|
||||
e.preventDefault();
|
||||
const given = standardizePashto(answer.trim());
|
||||
const correct = inflected[flipGender(question.gender)][0].some((ps) => (
|
||||
(given === ps.p) || (removeAccents(given) === removeAccents(ps.f))
|
||||
));
|
||||
if (correct) {
|
||||
setAnswer("");
|
||||
}
|
||||
callback(correct);
|
||||
}
|
||||
|
||||
return <div>
|
||||
<div className="pt-2 pb-1 mb-2" style={{ maxWidth: "300px", margin: "0 auto", backgroundColor: genderColors[question.gender === "masc" ? "m" : "f"]}}>
|
||||
<Examples opts={opts}>{[
|
||||
{
|
||||
...inflected[question.gender][0][0],
|
||||
e: firstVariation(question.entry.e),
|
||||
}
|
||||
]}</Examples>
|
||||
</div>
|
||||
<div>Is {givenGender}. Make it <span style={{ background: genderColors[requiredGender === "masculine" ? "m" : "f"]}}>{requiredGender}</span>.</div>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className="my-3" style={{ maxWidth: "200px", margin: "0 auto" }}>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
autoComplete="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
dir="auto"
|
||||
value={answer}
|
||||
onChange={handleInput}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<button type="submit" className="btn btn-primary">Check</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
}
|
||||
|
||||
function Instructions() {
|
||||
return <div>
|
||||
Change the gender of a given word
|
||||
</div>
|
||||
}
|
||||
|
||||
return <Game
|
||||
questions={questions}
|
||||
Display={Display}
|
||||
timeLimit={125}
|
||||
Instructions={Instructions}
|
||||
/>
|
||||
};
|
|
@ -73,15 +73,24 @@ Notice how it does not use the first feminine inflection <InlinePs opts={opts} p
|
|||
|
||||
## 3. Words ending in a stressed <InlinePs opts={opts} ps={{ p: "ی", f: "éy" }} />
|
||||
|
||||
This is very similar to pattern #2, but with the stress on the last syllable the feminine inflection changes.
|
||||
|
||||
<InflectionCarousel items={startingWord(words, "ey-stressed-unisex", "لومړی")} />
|
||||
|
||||
## 4. Words with the "Pashtun" pattern
|
||||
|
||||
These words are a little irregular but you can see a common patten based around:
|
||||
|
||||
- lengthening the 1st masculine inflection with <InlinePs opts={opts} ps={{ p: "ا ـ ـه", f: "aa _ u" }} />
|
||||
- shortening the other forms and adding the <InlinePs opts={opts} ps={{ p: "ـه", f: "-a" }} />, <InlinePs opts={opts} ps={{ p: "ـې", f: "-e" }} />, <InlinePs opts={opts} ps={{ p: "ـو", f: "-o" }} /> endings
|
||||
|
||||
<InflectionCarousel items={startingWord(words, "aanu-unisex", "پښتون")} />
|
||||
|
||||
**Note**: Nouns in this pattern will often only use the first inflection for the plural. Adjectives will use the 1st inflection for all 3 reasons.
|
||||
|
||||
## 5. Shorter irregular words
|
||||
## 5. Shorter words that take <InlinePs opts={opts} ps={{ p: "ـه", f: "-u" }} />
|
||||
|
||||
These are also a little irregular but instead of lengthening the 1st masculine inflection they compress it as well and take just an <InlinePs opts={opts} ps={{ p: "ـه", f: "-u" }} /> on the end.
|
||||
|
||||
<InflectionCarousel items={startingWord(words, "short-irreg-unisex", "غل")} />
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
import Table from "../../components/Table";
|
||||
import Link from "../../components/Link";
|
||||
import GenderTable from "../../components/GenderTable";
|
||||
import UnisexNounGame from "../../components/UnisexNounGame";
|
||||
|
||||
There are many words for people and animals in Pashto that can be used in both masculine and feminine forms.
|
||||
|
||||
|
@ -104,8 +105,6 @@ If the accent comes on the end of the word, the femine form is a little differen
|
|||
|
||||
### 4. Words with the "Pashtun" pattern
|
||||
|
||||
Well...
|
||||
|
||||
<GenderTable rows={[
|
||||
{
|
||||
masc: {
|
||||
|
@ -173,9 +172,7 @@ Well...
|
|||
}
|
||||
]} />
|
||||
|
||||
### 5. Shorter irregular words
|
||||
|
||||
You get the idea...
|
||||
### 5. Shorter words that take <InlinePs opts={opts} ps={{ p: "ـه", f: "-u" }} />
|
||||
|
||||
<GenderTable rows={[
|
||||
{
|
||||
|
@ -212,6 +209,10 @@ You get the idea...
|
|||
}
|
||||
]} />
|
||||
|
||||
**🕹 Here's a game to practice changing the genders of nouns**
|
||||
|
||||
<UnisexNounGame />
|
||||
|
||||
<!--
|
||||
{
|
||||
masc: {
|
||||
|
|
|
@ -26,7 +26,6 @@ module.exports = [
|
|||
// { ts: 1527815845, e: "life" }, // ژوندون
|
||||
{ ts: 1527815300, e: "rider, mounted" }, // سپور
|
||||
{ ts: 1527819505, e: "being (in a place after returning, coming back etc.)" }, // ستون
|
||||
{ ts: 1527813293, e: "red; hot" }, // سور
|
||||
{ ts: 1600080053835, e: "riding, mounted" }, // سور
|
||||
{ ts: 1527813068, e: "cold" }, // سوړ
|
||||
{ ts: 1575924767041, e: "shepherd" }, // شپون
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
module.exports = [
|
||||
{ ts: 1527821744, e: `cook, chef` }, // آشپز - aashpáz
|
||||
{ ts: 1527812156, e: `officer` }, // افسر - afsar
|
||||
{ ts: 1591872915426, e: `Afghan (person)` }, // افغانی - afghaanéy
|
||||
{ ts: 1527815137, e: `instigator, insurgent, terrorist` }, // اورپکی - orpakey
|
||||
{ ts: 1582853867682, e: `resident` }, // اوسېدونکی - osedóonkey
|
||||
{ ts: 1527812476, e: `child, offspring` }, // بچی - bachéy
|
||||
{ ts: 1623044005072, e: `insurrectionist, rebel` }, // بلواګر - balwaagar
|
||||
{ ts: 1612616237182, e: `Pakistani (person)` }, // پاکستانی - paakistaanéy
|
||||
{ ts: 1527817965, e: `keeper, one who brings up, raises (cattle etc.)` }, // پالونکی - paaloonkey
|
||||
{ ts: 1527815197, e: `Pashtun` }, // پښتون - puxtoon
|
||||
{ ts: 1527819228, e: `inspector, detective, person checking people at the doors etc.` }, // پلټونکی - pulaToonkey
|
||||
{ ts: 1527820130, e: `adherent, supporter; the outside or further ox in a team of oxes grinding or threshing` }, // پلوی - palawéy
|
||||
{ ts: 1527815924, e: `customer` }, // پېرودونکی - perodoonkey
|
||||
{ ts: 1527816431, e: `cousin (of paternal aunt)` }, // ترورزی - trorzéy
|
||||
{ ts: 1527820820, e: `follower` }, // تعقیبوونکی - ta'qeebawóonkey
|
||||
{ ts: 1586270915475, e: `mammal` }, // تي لرونکی - tee laroonkey
|
||||
{ ts: 1613563994424, e: `joker, jester, mocker` }, // ټوقمار - Toqmaar
|
||||
{ ts: 1610793723568, e: `ram, goat` }, // چېلی - cheléy
|
||||
{ ts: 1527811466, e: `researcher` }, // څېړونکی - tseRoonkey
|
||||
{ ts: 1527812795, e: `relative` }, // خپلوان - khpulwaan
|
||||
{ ts: 1527812802, e: `donkey` }, // خر - khur
|
||||
{ ts: 1527813282, e: `seller` }, // خرڅوونکی - khartsawóonkey
|
||||
{ ts: 1527819362, e: `calf (animal)` }, // خوسی - khooséy
|
||||
{ ts: 1527822535, e: `tailor` }, // خیاط - khayáat
|
||||
{ ts: 1590052667427, e: `witness` }, // درستی - drustéy, drastéy
|
||||
{ ts: 1622873938137, e: `crook, swindler, criminal` }, // درغلګر - darghalgar
|
||||
{ ts: 1527820656, e: `mediator, arbitrator` }, // دریمګړی - driyamgúRey
|
||||
{ ts: 1614081825855, e: `priest, monk/nun` }, // راهب - raahib
|
||||
{ ts: 1527813758, e: `student, learner, pupil` }, // زدکوونکی - zdakawóonkey
|
||||
{ ts: 1527819587, e: `translator` }, // ژباړونکی - jzbaaRoonkey
|
||||
{ ts: 1527815299, e: `dog` }, // سپی - spéy
|
||||
{ ts: 1610447830096, e: `calf; bull-calf` }, // سخی - skhey
|
||||
{ ts: 1527816932, e: `soldier` }, // سرتېری - sărtérey
|
||||
{ ts: 1527811519, e: `embassador, ambassador` }, // سفیر - safeer
|
||||
{ ts: 1622366208373, e: `secretary` }, // سکرتر - sakratár
|
||||
{ ts: 1527820170, e: `singer` }, // سندرغاړی - sandurgháaRey
|
||||
{ ts: 1566468540788, e: `rabbit` }, // سوی - sooy
|
||||
{ ts: 1527819801, e: `tourist, sightseer, visitor` }, // سیلانی - seylaanéy
|
||||
{ ts: 1575924767041, e: `shepherd` }, // شپون - shpoon
|
||||
{ ts: 1527815279, e: `shepherd` }, // شپونکی - shpoonkey
|
||||
{ ts: 1527819173, e: `analyst, examiner` }, // شنونکی - shanóonkey
|
||||
{ ts: 1612614411126, e: `teacher` }, // ښووونکی - xowóonkey
|
||||
{ ts: 1527815436, e: `tyrant, oppressor, cruel person` }, // ظالم - zaalim
|
||||
{ ts: 1527818632, e: `twin` }, // غبرګونی - ghbargoney
|
||||
{ ts: 1527812624, e: `thief` }, // غل - ghul
|
||||
{ ts: 1613561408232, e: `guilty, at fault` }, // قصوروار - qUsoorwáar
|
||||
{ ts: 1527812724, e: `of Kabul (a person)` }, // کابلی - kaabuley
|
||||
{ ts: 1527814715, e: `user` }, // کاروونکی - kaarawoonkey
|
||||
{ ts: 1527816256, e: `great-grandson` }, // کړوسی - kaRwaséy
|
||||
{ ts: 1594906790729, e: `child` }, // ککی - kakéy
|
||||
{ ts: 1527819244, e: `host, hostess; master of house` }, // کوربه - korba
|
||||
{ ts: 1527812174, e: `neighbour` }, // ګاونډی - gaawanDéy
|
||||
{ ts: 1579030083953, e: `sinner, sinful` }, // ګناه ګار - gUnaahgáar
|
||||
{ ts: 1527816249, e: `grandchild` }, // لمسی - lmaséy
|
||||
{ ts: 1527822661, e: `athlete, player; actor; mischevious, playful (of a child)` }, // لوبغاړی - lobgháaRey
|
||||
{ ts: 1589885143650, e: `fox` }, // لومبړ - loombáR
|
||||
{ ts: 1527812043, e: `writer, author` }, // لیکوال - leekwaal
|
||||
{ ts: 1527820680, e: `crazy, insane, mad person` }, // لېونی - lewanéy
|
||||
{ ts: 1527812881, e: `child, kid` }, // ماشوم - maashoom
|
||||
{ ts: 1527814445, e: `assigned, appointed, given orders or istructions (Arabic), authorized, sent on business; officer (as in government worker)` }, // مامور - maamóor
|
||||
{ ts: 1527818760, e: `civil activist` }, // مدني فاعل - madanee faa'al
|
||||
{ ts: 1527821523, e: `slave, servant` }, // مریی - mrayéy
|
||||
{ ts: 1527814159, e: `friend, companion` }, // ملګری - malgúrey
|
||||
{ ts: 1527820661, e: `mediator, go-between, arbitrator` }, // مېنځګړی - mendzgúRey
|
||||
{ ts: 1527823403, e: `fan, someone who loves or appreciates someone or something` }, // مینه وال - meenawáal
|
||||
{ ts: 1527815127, e: `nurse` }, // نرس - nurs
|
||||
{ ts: 1527816254, e: `grandson` }, // نوسی - nwaséy
|
||||
{ ts: 1527814806, e: `peer, someone of the same age` }, // همځولی - hamdzoléy ??
|
||||
{ ts: 1527812684, e: `co-worker, fellow worker, collaborator, aid` }, // همکار - hamkaar
|
||||
{ ts: 1527811732, e: `artist, performer` }, // هنر مند - hUnarmand
|
||||
{ ts: 1527821373, e: `deer` }, // هوسی - hoséy
|
||||
{ ts: 1591027046896, e: `goat` }, // وز - wuz
|
||||
{ ts: 1611395180139, e: `fellow countryman, person from the same country` }, // وطندار - watandáar
|
||||
{ ts: 1527811296, e: `lawyer, proxy holder` }, // وکیل - wakeel
|
||||
{ ts: 1527813585, e: `person, human being, creature` }, // وګړی - wagúRey
|
||||
{ ts: 1527814672, e: `spokesperson, spokesman, newcaster` }, // ویاند - wayaand
|
||||
{ ts: 1586454081484, e: `orphan` }, // یتیم - yateem
|
||||
];
|
File diff suppressed because one or more lines are too long
20
yarn.lock
20
yarn.lock
|
@ -1566,10 +1566,10 @@
|
|||
"@types/yargs" "^15.0.0"
|
||||
chalk "^4.0.0"
|
||||
|
||||
"@lingdocs/pashto-inflector@^0.8.3":
|
||||
version "0.8.3"
|
||||
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-0.8.3.tgz#427cf38a2c8ae81a65dc8bd0d65445d317e8ad36"
|
||||
integrity sha512-+8S5fEiJo3fC2/gp+IP09j3NZNBc5NuCV5FOWAGINEmg8NBKDVMa1gXnmuca6nVQsV2G4ZTk3UJyLwizq1RzDg==
|
||||
"@lingdocs/pashto-inflector@^0.9.3":
|
||||
version "0.9.4"
|
||||
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-0.9.4.tgz#a05aa5151ec57550e1364377dff1b593039be76c"
|
||||
integrity sha512-sn1TMGf8myoBr0NfRF5JtP//Y3A6cxwhVC8PtrZYgocYWA6lyB3H/R+ZblcUx7TCPwoH/aHIA365oKOpRDNMgw==
|
||||
dependencies:
|
||||
classnames "^2.2.6"
|
||||
pbf "^3.2.1"
|
||||
|
@ -9559,9 +9559,9 @@ property-information@^5.0.0, property-information@^5.3.0:
|
|||
xtend "^4.0.0"
|
||||
|
||||
protocol-buffers-schema@^3.3.1:
|
||||
version "3.5.1"
|
||||
resolved "https://registry.yarnpkg.com/protocol-buffers-schema/-/protocol-buffers-schema-3.5.1.tgz#8388e768d383ac8cbea23e1280dfadb79f4122ad"
|
||||
integrity sha512-YVCvdhxWNDP8/nJDyXLuM+UFsuPk4+1PB7WGPVDzm3HTHbzFLxQYeW2iZpS4mmnXrQJGBzt230t/BbEb7PrQaw==
|
||||
version "3.5.2"
|
||||
resolved "https://registry.yarnpkg.com/protocol-buffers-schema/-/protocol-buffers-schema-3.5.2.tgz#38ad35ba768607a5ed2375f8db4c2ecc5ea293c8"
|
||||
integrity sha512-LPzSaBYp/TcbuSlpGwqT5jR9kvJ3Zp5ic2N5c2ybx6XB/lSfEHq2D7ja8AgoxHoMD91wXFALJoXsvshKPuXyew==
|
||||
|
||||
proxy-addr@~2.0.5:
|
||||
version "2.0.6"
|
||||
|
@ -9679,9 +9679,9 @@ raf@^3.4.1:
|
|||
performance-now "^2.1.0"
|
||||
|
||||
rambda@^6.7.0:
|
||||
version "6.7.0"
|
||||
resolved "https://registry.yarnpkg.com/rambda/-/rambda-6.7.0.tgz#50322efdd23a108b61eb6ac4e0868d10dd95b4aa"
|
||||
integrity sha512-qg2atEwhAS4ipYoNfggkIP7qBUbY2OqdW17n25VqZIz5YC1MIwSpIToQ7XacvqSCZz16efM8Y8QKLx+Js1Sybg==
|
||||
version "6.9.0"
|
||||
resolved "https://registry.yarnpkg.com/rambda/-/rambda-6.9.0.tgz#17cd0b0c427295e00e8fe12de5bd63884502a9a4"
|
||||
integrity sha512-yosVdGg1hNGkXPzqGiOYNEpXKjEOxzUCg2rB0l+NKdyCaSf4z+i5ojbN0IqDSezMMf71YEglI+ZUTgTffn5afw==
|
||||
|
||||
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0:
|
||||
version "2.1.0"
|
||||
|
|
Loading…
Reference in New Issue