game better
This commit is contained in:
parent
bccecdfc80
commit
1535a8b174
|
@ -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",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -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>
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -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,18 +178,6 @@ export default function EquativeGame({ id, link, tense, onStartStop }: { id: str
|
||||||
onChange={handleInput}
|
onChange={handleInput}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<div className="form-check mt-1">
|
|
||||||
<input
|
|
||||||
className="form-check-input"
|
|
||||||
type="checkbox"
|
|
||||||
checked={withBa}
|
|
||||||
onChange={e => setWithBa(e.target.checked)}
|
|
||||||
/>
|
|
||||||
<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 className="text-center my-2">
|
||||||
{/* <div> */}
|
{/* <div> */}
|
||||||
<button className="btn btn-primary" type="submit">check</button>
|
<button className="btn btn-primary" type="submit">check</button>
|
||||||
|
@ -190,7 +186,6 @@ export default function EquativeGame({ id, link, tense, onStartStop }: { id: str
|
||||||
Type <kbd>Enter</kbd> to check
|
Type <kbd>Enter</kbd> to check
|
||||||
</div> */}
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -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"`
|
||||||
|
|
Loading…
Reference in New Issue