game better

This commit is contained in:
lingdocs 2022-05-09 16:00:21 -05:00
parent bccecdfc80
commit 1535a8b174
4 changed files with 84 additions and 64 deletions

View File

@ -345,8 +345,8 @@ Like the <Link to="#past-equative">past equative</Link> that it's based on, it's
<Examples opts={opts}>{psmd([ <Examples opts={opts}>{psmd([
{ {
p: "زه به هر سهار هلته وم", p: "زه **به** هر سهار هلته **وم**",
f: "zu ba hăr saháar halta wum", f: "zu **ba** hăr saháar halta **wum**",
e: "I would be there every morning", e: "I would be there every morning",
}, },
{ {

View File

@ -14,18 +14,18 @@ function GamesBrowser() {
} }
return <div> return <div>
{games.map((chapter) => ( {games.map((chapter) => (
<> <div key={chapter.chapter}>
<h3 key={chapter.chapter}>{chapter.chapter}</h3> <h3>{chapter.chapter}</h3>
{chapter.items.map(({ id, title, Game, studyLink }) => { {chapter.items.map(({ id, title, Game, studyLink }) => {
const done = user && user.tests.some(t => t.id === id); const done = user && user.tests.some(t => t.id === id);
const open = opened === id; const open = opened === id;
return <div key={id}> return <div key={id}>
<div className="d-flex flex-row justify-content-between align-items-center"> <div className="d-flex flex-row justify-content-between align-items-center">
<div> <div>
<h4 className="my-4 clickable" onClick={() => handleTitleClick(id)}> <h5 className="my-4 clickable" onClick={() => handleTitleClick(id)}>
<i className={`fas fa-caret-${open ? "down" : "right"}`}></i> {title} <i className={`fas fa-caret-${open ? "down" : "right"}`}></i> {title}
{` `} {` `}
</h4> </h5>
</div> </div>
<div> <div>
<h4> <h4>
@ -41,7 +41,7 @@ function GamesBrowser() {
</SmoothCollapse> </SmoothCollapse>
</div> </div>
})} })}
</> </div>
))} ))}
</div> </div>
} }

View File

@ -39,49 +39,56 @@ export const equativeGamePresent = makeGameRecord(
"Write the present equative", "Write the present equative",
"equative-present", "equative-present",
"/equatives/present-equative/", "/equatives/present-equative/",
(id, link) => (s: (a: "start" | "stop") => void) => <EquativeGame id={id} link={link} tense="present" onStartStop={s} />, (id, link) => (s: (a: "start" | "stop") => void) => <EquativeGame id={id} link={link} level="present" onStartStop={s} />,
); );
export const equativeGameHabitual = makeGameRecord( export const equativeGameHabitual = makeGameRecord(
"Write the habitual equative", "Write the habitual equative",
"equative-habitual", "equative-habitual",
"/equatives/habitual-equative/", "/equatives/habitual-equative/",
(id, link) => (s: (a: "start" | "stop") => void) => <EquativeGame id={id} link={link} tense="habitual" onStartStop={s} />, (id, link) => (s: (a: "start" | "stop") => void) => <EquativeGame id={id} link={link} level="habitual" onStartStop={s} />,
); );
export const equativeGameSubjunctive = makeGameRecord( export const equativeGameSubjunctive = makeGameRecord(
"Write the subjunctive equative", "Write the subjunctive equative",
"equative-subjunctive", "equative-subjunctive",
"/equatives/other-equatives/#subjunctive-equative", "/equatives/other-equatives/#subjunctive-equative",
(id, link) => (s: (a: "start" | "stop") => void) => <EquativeGame id={id} link={link} tense="subjunctive" onStartStop={s} />, (id, link) => (s: (a: "start" | "stop") => void) => <EquativeGame id={id} link={link} level="subjunctive" onStartStop={s} />,
); );
export const equativeGameFuture = makeGameRecord( export const equativeGameFuture = makeGameRecord(
"Write the future equative", "Write the future equative",
"equative-future", "equative-future",
"/equatives/other-equatives/#future-equative", "/equatives/other-equatives/#future-equative",
(id, link) => (s: (a: "start" | "stop") => void) => <EquativeGame id={id} link={link} tense="future" onStartStop={s} />, (id, link) => (s: (a: "start" | "stop") => void) => <EquativeGame id={id} link={link} level="future" onStartStop={s} />,
); );
export const equativeGamePast = makeGameRecord( export const equativeGamePast = makeGameRecord(
"Write the past equative", "Write the past equative",
"equative-past", "equative-past",
"/equatives/other-equatives/#past-equative", "/equatives/other-equatives/#past-equative",
(id, link) => (s: (a: "start" | "stop") => void) => <EquativeGame id={id} link={link} tense="past" onStartStop={s} />, (id, link) => (s: (a: "start" | "stop") => void) => <EquativeGame id={id} link={link} level="past" onStartStop={s} />,
); );
export const equativeGameWouldBe = makeGameRecord( export const equativeGameWouldBe = makeGameRecord(
'Write the "would be" equative', 'Write the "would be" equative',
"equative-would-be", "equative-would-be",
"equatives/other-equatives/#would-be-equative", "/equatives/other-equatives/#would-be-equative",
(id, link) => (s: (a: "start" | "stop") => void) => <EquativeGame id={id} link={link} tense="wouldBe" onStartStop={s} />, (id, link) => (s: (a: "start" | "stop") => void) => <EquativeGame id={id} link={link} level="wouldBe" onStartStop={s} />,
); );
export const equativeGamePastSubjunctive = makeGameRecord( export const equativeGamePastSubjunctive = makeGameRecord(
'Write the past subjunctive equative', 'Write the past subjunctive equative',
"equative-past-subjunctive", "equative-past-subjunctive",
"/equatives/other-equatives/#past-subjunctive", "/equatives/other-equatives/#past-subjunctive",
(id, link) => (s: (a: "start" | "stop") => void) => <EquativeGame id={id} link={link} tense="pastSubjunctive" onStartStop={s} />, (id, link) => (s: (a: "start" | "stop") => void) => <EquativeGame id={id} link={link} level="pastSubjunctive" onStartStop={s} />,
);
export const equativeGameAll = makeGameRecord(
'Write the equative (summary)',
"equative-past-summary",
"/equatives/other-equatives",
(id, link) => (s: (a: "start" | "stop") => void) => <EquativeGame id={id} link={link} level="all" onStartStop={s} />,
); );
const games: { chapter: string, items: GameRecord[] }[] = [ const games: { chapter: string, items: GameRecord[] }[] = [
@ -103,6 +110,7 @@ const games: { chapter: string, items: GameRecord[] }[] = [
equativeGamePast, equativeGamePast,
equativeGameWouldBe, equativeGameWouldBe,
equativeGamePastSubjunctive, equativeGamePastSubjunctive,
equativeGameAll,
], ],
}, },
]; ];

View File

@ -1,4 +1,4 @@
import { useState } from "react"; import { useEffect, useState } from "react";
import { import {
makeProgress, makeProgress,
} from "../../lib/game-utils"; } from "../../lib/game-utils";
@ -44,13 +44,17 @@ const locAdverbs: T.LocativeAdverbEntry[] = [
{"ts":1527812558,"i":6241,"p":"دلته","f":"dălta","g":"dalta","e":"here","c":"loc. adv."}, {"ts":1527812558,"i":6241,"p":"دلته","f":"dălta","g":"dalta","e":"here","c":"loc. adv."},
{"ts":1527812449,"i":13937,"p":"هلته","f":"hálta, álta","g":"halta,alta","e":"there","c":"loc. adv."}, {"ts":1527812449,"i":13937,"p":"هلته","f":"hálta, álta","g":"halta,alta","e":"there","c":"loc. adv."},
].filter(tp.isLocativeAdverbEntry); ].filter(tp.isLocativeAdverbEntry);
const tenses: T.EquativeTense[] = [
"present", "habitual", "subjunctive", "future", "past", "wouldBe", "pastSubjunctive",
];
const amount = 20; const amount = 20;
const timeLimit = 55; const timeLimit = 75;
type Question = { type Question = {
phrase: { ps: T.PsString, e?: string[] }, phrase: { ps: T.PsString, e?: string[] },
equative: T.EquativeRendered, equative: T.EquativeRendered,
tense: T.EquativeTense,
}; };
const pronounTypes = [ const pronounTypes = [
@ -63,7 +67,7 @@ const pronounTypes = [
[T.Person.ThirdPlurMale, T.Person.ThirdPlurFemale], [T.Person.ThirdPlurMale, T.Person.ThirdPlurFemale],
]; ];
export default function EquativeGame({ id, link, tense, onStartStop }: { id: string, link: string, tense: T.EquativeTense, onStartStop: (a: "start" | "stop") => void }) { export default function EquativeGame({ id, link, level, onStartStop }: { id: string, link: string, level: T.EquativeTense | "all", onStartStop: (a: "start" | "stop") => void }) {
function* questions (): Generator<Current<Question>> { function* questions (): Generator<Current<Question>> {
let pool = [...pronounTypes]; let pool = [...pronounTypes];
function makeRandPronoun(): T.PronounSelection { function makeRandPronoun(): T.PronounSelection {
@ -100,6 +104,7 @@ export default function EquativeGame({ id, link, tense, onStartStop }: { id: str
makeRandPronoun, makeRandPronoun,
])(); ])();
const pred = randFromArray([...adjectives, ...locAdverbs]); const pred = randFromArray([...adjectives, ...locAdverbs]);
const tense = level === "all" ? randFromArray(tenses) : level;
const EPS = makeEPS(subj, pred, tense); const EPS = makeEPS(subj, pred, tense);
const rendered = renderEP(EPS); const rendered = renderEP(EPS);
const compiled = compileEP(rendered, true, { equative: true, ba: false, kidsSection: true }); const compiled = compileEP(rendered, true, { equative: true, ba: false, kidsSection: true });
@ -112,6 +117,7 @@ export default function EquativeGame({ id, link, tense, onStartStop }: { id: str
question: { question: {
phrase, phrase,
equative: rendered.equative, equative: rendered.equative,
tense,
}, },
}; };
}; };
@ -132,32 +138,34 @@ export default function EquativeGame({ id, link, tense, onStartStop }: { id: str
if (correct) { if (correct) {
setAnswer(""); setAnswer("");
} }
callback(!correct callback(!correct ? makeCorrectAnswer(question) : true);
? <div>
<div className="my-2">
{flattenLengths(question.equative.ps).reduce(((accum, curr, i): JSX.Element[] => (
[
...accum,
...i > 0 ? [<span className="text-muted"> or </span>] : [],
<span>{curr.p}</span>,
]
)), [] as JSX.Element[])}
</div>
<div><strong>{question.equative.hasBa ? "with" : "without"}</strong> a <InlinePs opts={opts}>{grammarUnits.baParticle}</InlinePs> in the kids' section.</div>
</div>
: true);
} }
useEffect(() => {
if (level === "all") setWithBa(false);
}, [question]);
return <div> return <div>
<div className="pt-2 pb-1 mb-2" style={{ maxWidth: "300px", margin: "0 auto" }}> <div className="pt-2 pb-1 mb-2" style={{ maxWidth: "300px", margin: "0 auto" }}>
{/* {/* @ts-ignore */}
@ts-ignore */} <Examples opts={opts} ex={modExs([question.phrase.ps], withBa)}></Examples>
<Examples opts={opts} ex={modExs([question.phrase.ps])}></Examples> {question.phrase.e && question.phrase.e.map((e, i) => (
{question.phrase.e && question.phrase.e.map(e => ( <div key={e+i} className="text-muted mb-1">{e}</div>
<div className="text-muted mb-1">{e}</div>
))} ))}
<div className="lead text-muted">{humanReadableTense(question.tense)} equative</div>
</div> </div>
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<div className="form-check mt-1">
<input
id="baCheckbox"
className="form-check-input"
type="checkbox"
checked={withBa}
onChange={e => setWithBa(e.target.checked)}
/>
<label className="form-check-label text-muted" htmlFor="baCheckbox">
with <InlinePs opts={opts}>{grammarUnits.baParticle}</InlinePs> in the <span style={{ color: kidsColor }}>kids' section</span>
</label>
</div>
<div className="my-3" style={{ maxWidth: "200px", margin: "0 auto" }}> <div className="my-3" style={{ maxWidth: "200px", margin: "0 auto" }}>
<input <input
type="text" type="text"
@ -170,26 +178,13 @@ export default function EquativeGame({ id, link, tense, onStartStop }: { id: str
onChange={handleInput} onChange={handleInput}
/> />
</div> </div>
<div> <div className="text-center my-2">
<div className="form-check mt-1"> {/* <div> */}
<input <button className="btn btn-primary" type="submit">check</button>
className="form-check-input" {/* </div> */}
type="checkbox" {/* <div className="text-muted small text-center mt-2">
checked={withBa} Type <kbd>Enter</kbd> to check
onChange={e => setWithBa(e.target.checked)} </div> */}
/>
<label className="form-check-label text-muted" htmlFor="OSVCheckbox">
with <InlinePs opts={opts}>{grammarUnits.baParticle}</InlinePs> in the <span style={{ color: kidsColor }}>kids' section</span>
</label>
</div>
<div className="text-center my-2">
{/* <div> */}
<button className="btn btn-primary" type="submit">check</button>
{/* </div> */}
{/* <div className="text-muted small text-center mt-2">
Type <kbd>Enter</kbd> to check
</div> */}
</div>
</div> </div>
</form> </form>
@ -198,7 +193,8 @@ export default function EquativeGame({ id, link, tense, onStartStop }: { id: str
function Instructions() { function Instructions() {
return <div> return <div>
<p className="lead">Fill in the blank with the correct <strong>{humanReadableTense(tense)} equative</strong> <strong>in Pashto script</strong></p> <p className="lead">Fill in the blank with the correct <strong>{humanReadableTense(level)} equative</strong> <strong>in Pashto script</strong></p>
{level === "all" && <div> All tenses included...</div>}
</div> </div>
} }
@ -208,12 +204,26 @@ export default function EquativeGame({ id, link, tense, onStartStop }: { id: str
questions={questions} questions={questions}
id={id} id={id}
Display={Display} Display={Display}
timeLimit={timeLimit} timeLimit={level === "all" ? timeLimit * 1.4 : timeLimit}
Instructions={Instructions} Instructions={Instructions}
/> />
}; };
function modExs(exs: T.PsString[]): { p: JSX.Element, f: JSX.Element }[] { function makeCorrectAnswer(question: Question): JSX.Element {
return <div>
<div className="my-2">
{flattenLengths(question.equative.ps).reduce(((accum, curr, i): JSX.Element[] => (
[
...accum,
...i > 0 ? [<span className="text-muted"> or </span>] : [],
<span>{curr.p}</span>,
]
)), [] as JSX.Element[])}
</div>
<div><strong>{question.equative.hasBa ? "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 => { return exs.map(ps => {
if (!ps.p.includes(" ___ ")) { if (!ps.p.includes(" ___ ")) {
return { return {
@ -224,14 +234,16 @@ function modExs(exs: T.PsString[]): { p: JSX.Element, f: JSX.Element }[] {
const splitP = ps.p.split(" ___ "); const splitP = ps.p.split(" ___ ");
const splitF = ps.f.split(" ___ "); const splitF = ps.f.split(" ___ ");
return { return {
p: <>{splitP[0]} <span style={{ color: kidsColor }}>___</span> {splitP[1]}</>, p: <>{splitP[0]} <span style={{ color: kidsColor }}>{withBa ? "به" : "__"}</span> {splitP[1]}</>,
f: <>{splitF[0]} <span style={{ color: kidsColor }}>___</span> {splitF[1]}</>, f: <>{splitF[0]} <span style={{ color: kidsColor }}>{withBa ? "ba" : "__"}</span> {splitF[1]}</>,
}; };
}); });
} }
function humanReadableTense(tense: T.EquativeTense): string { function humanReadableTense(tense: T.EquativeTense | "all"): string {
return tense === "pastSubjunctive" return tense === "all"
? ""
: tense === "pastSubjunctive"
? "past subjunctive" ? "past subjunctive"
: tense === "wouldBe" : tense === "wouldBe"
? `"would be"` ? `"would be"`