more games
This commit is contained in:
parent
b1c654b929
commit
10915e3728
|
@ -149,7 +149,7 @@ function GameCore<T>({ questions, Display, timeLimit, Instructions, studyLink, i
|
||||||
/>
|
/>
|
||||||
<button onClick={handleQuit} className="btn btn-outline-secondary btn-sm mr-2">Quit</button>
|
<button onClick={handleQuit} className="btn btn-outline-secondary btn-sm mr-2">Quit</button>
|
||||||
</div>}
|
</div>}
|
||||||
<Reward ref={rewardRef} config={{ lifetime: 130, spread: 90, elementCount: 150, zIndex: 500 }} type="confetti">
|
<Reward ref={rewardRef} config={{ lifetime: 130, spread: 90, elementCount: 150, zIndex: 999999999 }} type="confetti">
|
||||||
<div className="py-3">
|
<div className="py-3">
|
||||||
{finish === undefined &&
|
{finish === undefined &&
|
||||||
(current
|
(current
|
||||||
|
@ -176,7 +176,9 @@ function GameCore<T>({ questions, Display, timeLimit, Instructions, studyLink, i
|
||||||
<h4 className="mt-4">{failMessage(current?.progress, finish)}</h4>
|
<h4 className="mt-4">{failMessage(current?.progress, finish)}</h4>
|
||||||
{typeof finish === "object" && <div>
|
{typeof finish === "object" && <div>
|
||||||
<div>The correct answer was:</div>
|
<div>The correct answer was:</div>
|
||||||
|
<div className="my-2">
|
||||||
{finish?.answer}
|
{finish?.answer}
|
||||||
|
</div>
|
||||||
</div>}
|
</div>}
|
||||||
<div className="mt-3">
|
<div className="mt-3">
|
||||||
<button className="btn btn-success mr-2" onClick={handleRestart}>Try Again</button>
|
<button className="btn btn-success mr-2" onClick={handleRestart}>Try Again</button>
|
||||||
|
|
|
@ -91,6 +91,13 @@ export const equativeGameAllIdentify = makeGameRecord(
|
||||||
(id, link) => () => <EquativeGame id={id} link={link} level="allIdentify" />,
|
(id, link) => () => <EquativeGame id={id} link={link} level="allIdentify" />,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const equativeGameSituations = makeGameRecord(
|
||||||
|
"Choose the right equative for the situation",
|
||||||
|
"equative-past-situations",
|
||||||
|
"/equatives/other-equatives",
|
||||||
|
(id, link) => () => <EquativeGame id={id} link={link} level="situations" />,
|
||||||
|
);
|
||||||
|
|
||||||
export const equativeGameAllProduce = makeGameRecord(
|
export const equativeGameAllProduce = makeGameRecord(
|
||||||
"Write the equative (all tenses)",
|
"Write the equative (all tenses)",
|
||||||
"equative-past-summary-produce",
|
"equative-past-summary-produce",
|
||||||
|
@ -117,6 +124,7 @@ const games: { chapter: string, items: GameRecord[] }[] = [
|
||||||
equativeGamePast,
|
equativeGamePast,
|
||||||
equativeGameWouldBe,
|
equativeGameWouldBe,
|
||||||
equativeGamePastSubjunctive,
|
equativeGamePastSubjunctive,
|
||||||
|
equativeGameSituations,
|
||||||
equativeGameAllIdentify,
|
equativeGameAllIdentify,
|
||||||
equativeGameAllProduce,
|
equativeGameAllProduce,
|
||||||
],
|
],
|
||||||
|
|
|
@ -57,13 +57,126 @@ const tenses: T.EquativeTense[] = [
|
||||||
"present", "habitual", "subjunctive", "future", "past", "wouldBe", "pastSubjunctive",
|
"present", "habitual", "subjunctive", "future", "past", "wouldBe", "pastSubjunctive",
|
||||||
];
|
];
|
||||||
|
|
||||||
const amount = 16;
|
type Situation = {
|
||||||
const timeLimit = 75;
|
description: string | JSX.Element,
|
||||||
|
tense: T.EquativeTense[],
|
||||||
|
};
|
||||||
|
const situations: Situation[] = [
|
||||||
|
{
|
||||||
|
description: <>A is B, for sure, right now</>,
|
||||||
|
tense: ["present"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: <>A is <em>probably</em> B, right now</>,
|
||||||
|
tense: ["future"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: <>A will be B in the future</>,
|
||||||
|
tense: ["future"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: <>We can assume that A is most likely B</>,
|
||||||
|
tense: ["future"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: <>You <em>know</em> A is B, currently</>,
|
||||||
|
tense: ["present"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: <>A tends to be B</>,
|
||||||
|
tense: ["habitual"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: <>A is usually B</>,
|
||||||
|
tense: ["habitual"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: <>A is generally B</>,
|
||||||
|
tense: ["habitual"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: <>A is B, right now</>,
|
||||||
|
tense: ["present"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: <>A is always B, as a matter of habit</>,
|
||||||
|
tense: ["present"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "It's a good thing for A to be B",
|
||||||
|
tense: ["subjunctive"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "A needs to be B (out of obligation/necessity)",
|
||||||
|
tense: ["subjunctive"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "You hope that A is B",
|
||||||
|
tense: ["subjunctive"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "You desire A to be B",
|
||||||
|
tense: ["subjunctive"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "If A is B ...",
|
||||||
|
tense: ["subjunctive"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "...so that A will be B (a purpose)",
|
||||||
|
tense: ["subjunctive"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "A was definately B",
|
||||||
|
tense: ["past"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "A was B",
|
||||||
|
tense: ["past"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "A was probably B in the past",
|
||||||
|
tense: ["wouldBe"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "A used to be B (habitually, repeatedly)",
|
||||||
|
tense: ["wouldBe"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "assume that A would have probably been B",
|
||||||
|
tense: ["wouldBe"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "under different circumstances, A would have been B",
|
||||||
|
tense: ["wouldBe", "pastSubjunctive"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "You wish A were B (but it's not)",
|
||||||
|
tense: ["pastSubjunctive"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "If A were B (but it's not)",
|
||||||
|
tense: ["pastSubjunctive"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "Aaagh! If only A were B!",
|
||||||
|
tense: ["pastSubjunctive"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "A should have been B!",
|
||||||
|
tense: ["pastSubjunctive", "wouldBe"],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const amount = 20;
|
||||||
|
const timeLimit = 90;
|
||||||
|
|
||||||
type Question = {
|
type Question = {
|
||||||
EPS: T.EPSelectionComplete,
|
EPS: T.EPSelectionComplete,
|
||||||
phrase: { ps: T.PsString[], e?: string[] },
|
phrase: { ps: T.PsString[], e?: string[] },
|
||||||
equative: T.EquativeRendered,
|
equative: T.EquativeRendered,
|
||||||
|
} | {
|
||||||
|
situation: Situation,
|
||||||
};
|
};
|
||||||
|
|
||||||
const pronounTypes = [
|
const pronounTypes = [
|
||||||
|
@ -76,12 +189,12 @@ const pronounTypes = [
|
||||||
[T.Person.ThirdPlurMale, T.Person.ThirdPlurFemale],
|
[T.Person.ThirdPlurMale, T.Person.ThirdPlurFemale],
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function EquativeGame({ id, link, level }: { id: string, link: string, level: T.EquativeTense | "allProduce" | "allIdentify" }) {
|
export default function EquativeGame({ id, link, level }: { id: string, link: string, level: T.EquativeTense | "allProduce" | "allIdentify" | "situations" }) {
|
||||||
function* questions (): Generator<Current<Question>> {
|
function* questions (): Generator<Current<Question>> {
|
||||||
let pool = [...pronounTypes];
|
let pool = [...pronounTypes];
|
||||||
|
let situationPool = [...situations];
|
||||||
function makeRandPronoun(): T.PronounSelection {
|
function makeRandPronoun(): T.PronounSelection {
|
||||||
let person: T.Person;
|
let person: T.Person;
|
||||||
console.log(pool);
|
|
||||||
do {
|
do {
|
||||||
person = randomPerson();
|
person = randomPerson();
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
|
@ -104,7 +217,7 @@ export default function EquativeGame({ id, link, level }: { id: string, link: st
|
||||||
number: n.numberCanChange ? randFromArray(["singular", "plural"]) : n.number,
|
number: n.numberCanChange ? randFromArray(["singular", "plural"]) : n.number,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function makeRandomEPS(): T.EPSelectionComplete {
|
function makeRandomEPS(l: T.EquativeTense | "allIdentify" | "allProduce"): T.EPSelectionComplete {
|
||||||
const subj = randFromArray([
|
const subj = randFromArray([
|
||||||
makeRandPronoun,
|
makeRandPronoun,
|
||||||
makeRandPronoun,
|
makeRandPronoun,
|
||||||
|
@ -112,13 +225,24 @@ export default function EquativeGame({ id, link, level }: { id: string, link: st
|
||||||
makeRandPronoun,
|
makeRandPronoun,
|
||||||
])();
|
])();
|
||||||
const pred = randFromArray([...adjectives, ...locAdverbs]);
|
const pred = randFromArray([...adjectives, ...locAdverbs]);
|
||||||
const tense = (level === "allIdentify" || level === "allProduce")
|
const tense = (l === "allIdentify" || l === "allProduce")
|
||||||
? randFromArray(tenses)
|
? randFromArray(tenses)
|
||||||
: level;
|
: l;
|
||||||
return makeEPS(subj, pred, tense);
|
return makeEPS(subj, pred, tense);
|
||||||
}
|
}
|
||||||
for (let i = 0; i < amount; i++) {
|
for (let i = 0; i < amount; i++) {
|
||||||
const EPS = makeRandomEPS();
|
if (level === "situations") {
|
||||||
|
const picked = randFromArray(situationPool);
|
||||||
|
situationPool = situationPool.filter(x => picked.description !== x.description);
|
||||||
|
if (situationPool.length === 0) situationPool = [...situations];
|
||||||
|
yield {
|
||||||
|
progress: makeProgress(i, amount),
|
||||||
|
question: {
|
||||||
|
situation: picked,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const EPS = makeRandomEPS(level);
|
||||||
const EP = renderEP(EPS);
|
const EP = renderEP(EPS);
|
||||||
const compiled = compileEP(
|
const compiled = compileEP(
|
||||||
EP,
|
EP,
|
||||||
|
@ -137,6 +261,7 @@ export default function EquativeGame({ id, link, level }: { id: string, link: st
|
||||||
equative: EP.equative,
|
equative: EP.equative,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,6 +273,9 @@ export default function EquativeGame({ id, link, level }: { id: string, link: st
|
||||||
setAnswer(value);
|
setAnswer(value);
|
||||||
}
|
}
|
||||||
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
|
if ("situation" in question) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const given = standardizePashto(answer.trim());
|
const given = standardizePashto(answer.trim());
|
||||||
const correct = checkAnswer(given, question.equative.ps)
|
const correct = checkAnswer(given, question.equative.ps)
|
||||||
|
@ -158,6 +286,15 @@ export default function EquativeGame({ id, link, level }: { id: string, link: st
|
||||||
callback(!correct ? makeCorrectAnswer(question) : true);
|
callback(!correct ? makeCorrectAnswer(question) : true);
|
||||||
}
|
}
|
||||||
const handleTenseIdentify = (tense: T.EquativeTense) => {
|
const handleTenseIdentify = (tense: T.EquativeTense) => {
|
||||||
|
if ("situation" in question) {
|
||||||
|
const wasCorrect = question.situation.tense.includes(tense);
|
||||||
|
if (wasCorrect) {
|
||||||
|
callback(true);
|
||||||
|
} else {
|
||||||
|
callback(makeCorrectAnswer(question));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
const renderedWAnswer = renderEP({
|
const renderedWAnswer = renderEP({
|
||||||
...question.EPS,
|
...question.EPS,
|
||||||
equative: {
|
equative: {
|
||||||
|
@ -186,7 +323,7 @@ export default function EquativeGame({ id, link, level }: { id: string, link: st
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
callback(<div className="lead">
|
callback(<div className="lead">
|
||||||
{makeCorrectTenseAnswer(possibleCorrect)}
|
{possibleCorrect.map(humanReadableTense).join(" or ")}
|
||||||
</div>)
|
</div>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,13 +332,15 @@ export default function EquativeGame({ id, link, level }: { id: string, link: st
|
||||||
}, [question]);
|
}, [question]);
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
{level === "allIdentify" ?
|
{(level === "allIdentify" || level === "situations") ?
|
||||||
<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" }}>
|
||||||
<Examples opts={opts}>
|
{"situation" in question ? <p className="lead">
|
||||||
|
{question.situation.description}
|
||||||
|
</p> : <Examples opts={opts}>
|
||||||
{randFromArray(question.phrase.ps)}
|
{randFromArray(question.phrase.ps)}
|
||||||
</Examples>
|
</Examples>}
|
||||||
</div>
|
</div>
|
||||||
: <div className="pt-2 pb-1 mb-2" style={{ maxWidth: "300px", margin: "0 auto" }}>
|
: !("situation" in question) && <div className="pt-2 pb-1 mb-2" style={{ maxWidth: "300px", margin: "0 auto" }}>
|
||||||
<Examples opts={opts}>
|
<Examples opts={opts}>
|
||||||
{/* @ts-ignore TODO: REMOVE AS P_INFLE */}
|
{/* @ts-ignore TODO: REMOVE AS P_INFLE */}
|
||||||
{modExs(question.phrase.ps, withBa)[0]}
|
{modExs(question.phrase.ps, withBa)[0]}
|
||||||
|
@ -212,9 +351,9 @@ export default function EquativeGame({ id, link, level }: { id: string, link: st
|
||||||
<div className="lead text-muted">{humanReadableTense(question.EPS.equative.tense)} equative</div>
|
<div className="lead text-muted">{humanReadableTense(question.EPS.equative.tense)} equative</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
{level === "allIdentify" ? <div className="text-center">
|
{level === "allIdentify" || "situation" in question ? <div className="text-center">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
{tenses.map(t => <div className="col" key={t+question.phrase.ps}>
|
{tenses.map(t => <div className="col" key={Math.random()}>
|
||||||
<button
|
<button
|
||||||
style={{ width: "8rem" }}
|
style={{ width: "8rem" }}
|
||||||
className="btn btn-outline-secondary mb-3"
|
className="btn btn-outline-secondary mb-3"
|
||||||
|
@ -265,6 +404,8 @@ export default function EquativeGame({ id, link, level }: { id: string, link: st
|
||||||
return <div>
|
return <div>
|
||||||
{level === "allProduce"
|
{level === "allProduce"
|
||||||
? <p className="lead">Fill in the blank with the correct <strong>{humanReadableTense(level)} 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 === "situations"
|
||||||
|
? <p className="lead">Choose the right type of equative for each given situation</p>
|
||||||
: <p className="lead">Identify a correct tense for each equative phrase you see</p>}
|
: <p className="lead">Identify a correct tense for each equative phrase you see</p>}
|
||||||
{level === "allProduce" && <div>⚠ All tenses included...</div>}
|
{level === "allProduce" && <div>⚠ All tenses included...</div>}
|
||||||
</div>
|
</div>
|
||||||
|
@ -280,15 +421,14 @@ export default function EquativeGame({ id, link, level }: { id: string, link: st
|
||||||
/>
|
/>
|
||||||
};
|
};
|
||||||
|
|
||||||
function makeCorrectTenseAnswer(tenses: T.EquativeTense[]): string {
|
|
||||||
return tenses.reduce((accum, curr, i) => (
|
|
||||||
`${accum}${(i > 0 ? " or " : " ")}'${humanReadableTense(curr)}'`
|
|
||||||
), "");
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeCorrectAnswer(question: Question): JSX.Element {
|
function makeCorrectAnswer(question: Question): JSX.Element {
|
||||||
|
if ("situation" in question) {
|
||||||
return <div>
|
return <div>
|
||||||
<div className="my-2">
|
{question.situation.tense.map(humanReadableTense).join(" or ")}
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
return <div>
|
||||||
|
<div>
|
||||||
{flattenLengths(question.equative.ps).reduce(((accum, curr, i): JSX.Element[] => (
|
{flattenLengths(question.equative.ps).reduce(((accum, curr, i): JSX.Element[] => (
|
||||||
[
|
[
|
||||||
...accum,
|
...accum,
|
||||||
|
|
|
@ -114,7 +114,7 @@ export default function GenderGame({level, id, link }: { level: 1 | 2, id: strin
|
||||||
const nounGender: T.Gender = nounNotIn(mascNouns)(question) ? "fem" : "masc";
|
const nounGender: T.Gender = nounNotIn(mascNouns)(question) ? "fem" : "masc";
|
||||||
const correct = gender === nounGender;
|
const correct = gender === nounGender;
|
||||||
callback(!correct
|
callback(!correct
|
||||||
? <div className="my-4 text-center">
|
? <div className="my-2 text-center">
|
||||||
<button style={{ background: genderColors[nounGender === "masc" ? "m" : "f"], color: "black" }} className="btn btn-lg" disabled>
|
<button style={{ background: genderColors[nounGender === "masc" ? "m" : "f"], color: "black" }} className="btn btn-lg" disabled>
|
||||||
{nounGender === "masc" ? "Masculine" : "Feminine"}
|
{nounGender === "masc" ? "Masculine" : "Feminine"}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -36,7 +36,7 @@ function UserProvider({ children }: any) {
|
||||||
}).catch(console.error);
|
}).catch(console.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
const checkUserCronJob = new CronJob("1/30 * * * * *", () => {
|
const checkUserCronJob = new CronJob("10 * * * *", () => {
|
||||||
pullUser();
|
pullUser();
|
||||||
if (value) {
|
if (value) {
|
||||||
postSavedResults(value.userId);
|
postSavedResults(value.userId);
|
||||||
|
|
Loading…
Reference in New Issue