Skip to content

Commit 4923335

Browse files
committed
The grid game now allows for statement checks
1 parent 318d3f0 commit 4923335

File tree

4 files changed

+127
-10
lines changed

4 files changed

+127
-10
lines changed

media/js/src/firstOrderLogic/firstOrderLogic.tsx

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { shuffleArray, getRandomElement, GridItem, GridStatement,
44
import { getTemplatesByDifficulty } from './statementGenerator';
55
import { Grid } from './grid';
66
import { Options } from './options';
7+
import { StatementInput } from './statementInput';
78

89
export const STATIC_URL = LogicLearner.staticUrl;
910

@@ -16,9 +17,10 @@ export const FirstOrderLogic: React.FC = () => {
1617
const [options, setOptions] = useState<GridStatement[]>([]);
1718
const [size, setSize] = useState<number>(5);
1819
const [templateBank, setTemplateBank] = useState<Object[]>(getTemplatesByDifficulty(difficulty));
19-
const [value, setValue] = useState();
20+
const [text, setText] = useState<string>('');
2021
const [isCorrect, setIsCorrect] = useState<boolean>(false);
2122
const [selected, setSelected] = useState<number|null>()
23+
const [mode, setMode] = useState<number>(0);
2224

2325
const [correctTemplate, setCorrectTemplate] =
2426
useState<GridTemplate>(getRandomElement(templateBank));
@@ -30,8 +32,8 @@ export const FirstOrderLogic: React.FC = () => {
3032
];
3133

3234
const inputOptions = [ // [value, innerText]
33-
['mc', 'Multiple Choice'],
34-
['text', 'Text Input']
35+
[0, 'Multiple Choice'],
36+
[1, 'Text Input']
3537
];
3638

3739
function generateIncorrectStatements(templateBank, correctTemplate) {
@@ -68,6 +70,10 @@ export const FirstOrderLogic: React.FC = () => {
6870
setDifficulty(e.target.value);
6971
};
7072

73+
const handleMode = (e) => {
74+
setMode(Number(e.target.value));
75+
}
76+
7177
const handleNewGrid = () => {
7278
let newArr = getRandomElement(templateBank)
7379
while (newArr === correctTemplate) {
@@ -85,7 +91,7 @@ export const FirstOrderLogic: React.FC = () => {
8591

8692
const settings = [
8793
mkSelect(diffOptions, handleDifficulty),
88-
mkSelect(inputOptions, () => alert('Needs implementation.')),
94+
mkSelect(inputOptions, handleMode),
8995
<button className='btn btn-primary mt-2' onClick={handleNewGrid}>
9096
Next Grid
9197
</button>
@@ -105,7 +111,7 @@ export const FirstOrderLogic: React.FC = () => {
105111
const generated = correctTemplate.generateGrid(true, statementData.details)
106112

107113
setGrid(generated.grid);
108-
setValue(generated.satisfies);
114+
setText('');
109115

110116
setCorrectStatement({
111117
naturalLanguageStatement: statementData.naturalLanguageStatement,
@@ -135,6 +141,10 @@ export const FirstOrderLogic: React.FC = () => {
135141
setSelected(null);
136142
}, []);
137143

144+
useEffect(() => {
145+
setIsCorrect(false);
146+
}, [mode])
147+
138148
return <section id='grid-game'
139149
className='container d-flex justify-content-center'
140150
>
@@ -148,9 +158,14 @@ export const FirstOrderLogic: React.FC = () => {
148158
</li>)}
149159
</ul>
150160
</div>
151-
<Options options={options} correctIndex={correctIndex}
161+
{mode === 0 && <Options options={options} correctIndex={correctIndex}
152162
isCorrect={isCorrect} setIsCorrect={setIsCorrect}
153-
selected={selected} setSelected={setSelected} />
163+
selected={selected} setSelected={setSelected} />}
164+
{mode === 1 && <StatementInput isCorrect={isCorrect}
165+
correctStatement={correctStatement}
166+
setIsCorrect={setIsCorrect}
167+
text={text}
168+
setText={setText} />}
154169
</div>
155170
</section>
156171
}

media/js/src/firstOrderLogic/gridTemplates/hardTemplates/hardTemplate_05.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export const hardTemplate_05 = {
5656
const formalFOLStatement = `
5757
∀x (
5858
(Shape(x, ${shape1}) ∧ Color(x, ${colorName}))
59-
→ ∃y (Shape(y, ${shape2}) ∧ Value(y) ≥ ${threshold}TopLeftDiagonalOf(y, x))
59+
→ ∃y (Shape(y, ${shape2}) ∧ Value(y) ≥ ${threshold}TopLeftOf(y, x))
6060
)
6161
`.trim();
6262

media/js/src/firstOrderLogic/gridTemplates/hardTemplates/hardTemplate_06.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ export const hardTemplate_06 = {
4949
);
5050

5151
// FOL example:
52-
// "∀x( (Shape(x)=s1 ∧ Color(x)=c1) → ∃y( Shape(y)=s2 ∧ Value(y)<threshold ∧ TopRightDiagonalOf(y,x) ) )"
52+
// "∀x( (Shape(x)=s1 ∧ Color(x)=c1) → ∃y( Shape(y)=s2 ∧ Value(y)<threshold ∧ TopRightOf(y,x) ) )"
5353
const formalFOLStatement = `
5454
∀x (
5555
(Shape(x, ${shape1}) ∧ Color(x, ${colorName}))
56-
→ ∃y (Shape(y, ${shape2}) ∧ Value(y) < ${threshold}TopRightDiagonalOf(y, x))
56+
→ ∃y (Shape(y, ${shape2}) ∧ Value(y) < ${threshold}TopRightOf(y, x))
5757
)
5858
`.trim();
5959

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import React, { useEffect, useState } from 'react';
2+
import { GridStatement } from './utils';
3+
4+
interface StatementProps {
5+
correctStatement: GridStatement
6+
isCorrect: boolean
7+
setIsCorrect: Function
8+
text: string
9+
setText: Function
10+
}
11+
12+
export const StatementInput: React.FC<StatementProps> = ({
13+
correctStatement, isCorrect, setIsCorrect, text, setText
14+
}:StatementProps) => {
15+
const [feedback, setFeedback] = useState<string>(
16+
'ERROR: This feedback should not be visible.')
17+
const [submitted, setSubmitted] = useState<boolean>(false);
18+
19+
const buttonList = ['∀', '→', '∃', '∧', '≥'];
20+
21+
const directionalRelationships = ['Top(y,x)', 'TopLeftOf(y,x)',
22+
'TopRightOf(y,x)', 'LeftOf(y,x)', 'RightOf(y,x)', 'Below(y,x)',
23+
'BottomLeftOf(y,x)', 'BottomRightOf(y,x)'];
24+
25+
const objectRelationships = ['Shape(x/y, Circle/Square/Triangle)',
26+
'Color(x/y, Blue/Green/Red))', 'Value(x/y, 0 to 9))',]
27+
28+
const mkList = (items:string[], uniqueClass='') =>
29+
<ul className={`list-group-flush ps-2 ${uniqueClass}`}>
30+
{items.map((item, i) =>
31+
<li key={i} className='list-group-item'>{item}</li>
32+
)}
33+
</ul>
34+
35+
const mkBtnList = (items:string[]) =>
36+
<ul className="list-inline row my-2">
37+
{items.map((item:string, i:number) =>
38+
<li key={i} className='col-auto'>
39+
<button className='btn btn-outline-secondary'
40+
aria-label={`Add a ${item} symbol to the statement.`}
41+
onClick={mkAddChar(item)}
42+
>
43+
{item}</button>
44+
</li>
45+
)}
46+
</ul>
47+
48+
const mkAddChar = (char:string) => () => {
49+
const el =
50+
document.getElementById('statement-text') as HTMLInputElement;
51+
el.value = el.value + char
52+
el.focus();
53+
};
54+
55+
const generalize = (text:string) => {
56+
return text.replace(/\s/g, '').toLowerCase();
57+
};
58+
59+
const handleCheck = (e) => {
60+
setSubmitted(true);
61+
const el =
62+
document.getElementById('statement-text') as HTMLInputElement;
63+
setIsCorrect(generalize(el.value) ===
64+
generalize(correctStatement.formalFOLStatement));
65+
};
66+
67+
const handleText = (e) => {
68+
setText(e.value);
69+
};
70+
71+
useEffect(() => {
72+
if (isCorrect) setFeedback('Good! XD');
73+
else setFeedback('Ooops <:O');
74+
}, [isCorrect])
75+
76+
useEffect(() => {
77+
setSubmitted(false);
78+
}, [])
79+
80+
return <section className='col-4'>
81+
<p>Enter the statment that defines the relationship of</p>
82+
<p>{correctStatement.naturalLanguageStatement}</p>
83+
{mkBtnList(buttonList)}
84+
<textarea id='statement-text' className='form-control mb-2' onChange={handleText}
85+
placeholder='Enter the value here' value={text}></textarea>
86+
<button type='submit' className='btn btn-primary my-2'
87+
onClick={handleCheck}>Check Statement</button>
88+
{submitted && (isCorrect ? <p className='text-success'>{feedback}</p> :
89+
<p className='text-danger'>{feedback}</p>)}
90+
<p className='col-12 fs-4 my-2'>Relationships</p>
91+
<div className="row">
92+
<div className="col-6">
93+
<strong>Object</strong>
94+
{mkList(objectRelationships)}
95+
</div>
96+
<div className="col-6">
97+
<strong>Directional</strong>
98+
{mkList(directionalRelationships)}
99+
</div>
100+
</div>
101+
</section>
102+
}

0 commit comments

Comments
 (0)