-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcustomary-units-three-numbers.js
More file actions
315 lines (277 loc) · 18.9 KB
/
customary-units-three-numbers.js
File metadata and controls
315 lines (277 loc) · 18.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
import { animationSystem } from './animations.js';
import { setupScratchpad, shuffleArray } from './shared.js';
// Problem generator functions
function generateProblem() {
// Names array to cycle through
const names = ['Elizabeth', 'Matilda', 'Dylan', 'Joe', 'Andrew', 'James', 'Sarah', 'Austin',
'Angela', 'Sydney', 'Ashley', 'Sadie', 'Adalyn', 'Michael', 'Emma', 'Noah',
'Olivia', 'William', 'Ava', 'Benjamin', 'Isabella', 'Lucas', 'Mia', 'Micah',
'Charlotte', 'Theodore', 'Amelia', 'Jack', 'Harper', 'Oliver'];
// Helper function for unit pluralization
function getUnit(value, unit) {
if (unit === 'foot') {
return value === 1 ? 'foot' : 'feet';
}
return value === 1 ? unit : unit + 's';
}
// Get two different random names
let name1Index = Math.floor(Math.random() * names.length);
let name2Index;
do {
name2Index = Math.floor(Math.random() * names.length);
} while (name2Index === name1Index);
const name1 = names[name1Index];
const name2 = names[name2Index];
// Generate appropriate numbers based on the measurement context
const smallNumber = Math.floor(Math.random() * 5) + 1; // 1-5
const mediumNumber = Math.floor(Math.random() * 15) + 5; // 5-20
const largeNumber = Math.floor(Math.random() * 25) + 15; // 15-40
// Helper function to ensure sums don't exceed 100
function getValidSecondNumber(firstNum, maxSum = 100) {
const maxAllowed = maxSum - firstNum;
return Math.min(smallNumber, maxAllowed);
}
const problemTypes = [
// Original problems with adjusted measurements
{
text: `There are three trees in the garden. The smallest tree is ${mediumNumber} ${getUnit(mediumNumber, 'foot')} tall. The middle tree is ${smallNumber} ${getUnit(smallNumber, 'foot')} taller. If the tallest tree is ${smallNumber} ${getUnit(smallNumber, 'foot')} taller than the middle tree, how tall is the tallest tree?`,
answer: mediumNumber + smallNumber + smallNumber
},
{
text: `A garden path has three sections. The first section is ${mediumNumber} ${getUnit(mediumNumber, 'yard')} long. The second section is ${smallNumber} ${getUnit(smallNumber, 'yard')} longer than the first. The third section is ${smallNumber} ${getUnit(smallNumber, 'yard')} longer than the second. How long is the third section?`,
answer: mediumNumber + smallNumber + smallNumber
},
{
text: `Three friends measured their heights. ${name1} is ${mediumNumber} ${getUnit(mediumNumber, 'inch')} tall. ${name2} is ${smallNumber} ${getUnit(smallNumber, 'inch')} taller. Charlie is ${smallNumber} ${getUnit(smallNumber, 'inch')} taller than ${name2}. How tall is Charlie?`,
answer: mediumNumber + smallNumber + smallNumber
},
{
text: `A race track has three laps. The first lap is ${mediumNumber} ${getUnit(mediumNumber, 'yard')} long. The second lap is ${smallNumber} ${getUnit(smallNumber, 'yard')} longer than the first. The final lap is ${smallNumber} ${getUnit(smallNumber, 'yard')} longer than the second. How long is the final lap?`,
answer: mediumNumber + smallNumber + smallNumber
},
{
text: `A red ribbon is ${smallNumber} ${getUnit(smallNumber, 'inch')} long. A blue ribbon is ${smallNumber} ${getUnit(smallNumber, 'inch')} longer than the red ribbon. If a yellow ribbon is ${smallNumber} ${getUnit(smallNumber, 'inch')} longer than the blue ribbon, how long is the yellow ribbon?`,
answer: smallNumber + smallNumber + smallNumber
},
// New problems with realistic measurements
// Classroom items (inches)
{
text: `${name1} is measuring three pencils. The first pencil is ${smallNumber} ${getUnit(smallNumber, 'inch')} long. The second pencil is ${smallNumber} ${getUnit(smallNumber, 'inch')} longer than the first. The third pencil is ${smallNumber} ${getUnit(smallNumber, 'inch')} longer than the second. How long is the third pencil?`,
answer: smallNumber + smallNumber + smallNumber
},
{
text: `Three rulers are lined up. The first ruler is ${mediumNumber} ${getUnit(mediumNumber, 'inch')} long. The second ruler is ${smallNumber} ${getUnit(smallNumber, 'inch')} longer. The third ruler is ${smallNumber} ${getUnit(smallNumber, 'inch')} longer than the second. How long is the third ruler?`,
answer: mediumNumber + smallNumber + smallNumber
},
// Sports equipment (inches)
{
text: `${name1} has three different baseball bats. The shortest bat is ${mediumNumber} ${getUnit(mediumNumber, 'inch')} long. The medium bat is ${smallNumber} ${getUnit(smallNumber, 'inch')} longer. The longest bat is ${smallNumber} ${getUnit(smallNumber, 'inch')} longer than the medium bat. How long is the longest bat?`,
answer: mediumNumber + smallNumber + smallNumber
},
{
text: `Three tennis rackets are displayed at the store. The junior racket is ${mediumNumber} ${getUnit(mediumNumber, 'inch')} long. The intermediate racket is ${smallNumber} ${getUnit(smallNumber, 'inch')} longer. The adult racket is ${smallNumber} ${getUnit(smallNumber, 'inch')} longer than the intermediate. How long is the adult racket?`,
answer: mediumNumber + smallNumber + smallNumber
},
// Garden measurements (feet)
{
text: `${name1} is planting three rows of flowers. The first row is ${mediumNumber} ${getUnit(mediumNumber, 'foot')} long. The second row is ${smallNumber} ${getUnit(smallNumber, 'foot')} longer. The third row is ${smallNumber} ${getUnit(smallNumber, 'foot')} longer than the second. How long is the third row?`,
answer: mediumNumber + smallNumber + smallNumber
},
{
text: `Three garden hoses are connected. The first hose is ${mediumNumber} ${getUnit(mediumNumber, 'foot')} long. The second hose is ${smallNumber} ${getUnit(smallNumber, 'foot')} longer. The third hose is ${smallNumber} ${getUnit(smallNumber, 'foot')} longer than the second. What is the length of the third hose?`,
answer: mediumNumber + smallNumber + smallNumber
},
// Playground equipment (feet)
{
text: `The playground has three slides. The small slide is ${mediumNumber} ${getUnit(mediumNumber, 'foot')} long. The medium slide is ${smallNumber} ${getUnit(smallNumber, 'foot')} longer. The big slide is ${smallNumber} ${getUnit(smallNumber, 'foot')} longer than the medium slide. How long is the big slide?`,
answer: mediumNumber + smallNumber + smallNumber
},
{
text: `Three balance beams are set up. The low beam is ${smallNumber} ${getUnit(smallNumber, 'foot')} high. The middle beam is ${smallNumber} ${getUnit(smallNumber, 'foot')} higher. The high beam is ${smallNumber} ${getUnit(smallNumber, 'foot')} higher than the middle beam. How high is the high beam?`,
answer: smallNumber + smallNumber + smallNumber
},
// Building features (feet)
{
text: `A house has three different walls. The shortest wall is ${mediumNumber} ${getUnit(mediumNumber, 'foot')} long. The middle wall is ${smallNumber} ${getUnit(smallNumber, 'foot')} longer. The longest wall is ${smallNumber} ${getUnit(smallNumber, 'foot')} longer than the middle wall. How long is the longest wall?`,
answer: mediumNumber + smallNumber + smallNumber
},
{
text: `Three fences are being built. The first fence is ${mediumNumber} ${getUnit(mediumNumber, 'foot')} long. The second fence is ${smallNumber} ${getUnit(smallNumber, 'foot')} longer. The third fence is ${smallNumber} ${getUnit(smallNumber, 'foot')} longer than the second. How long is the third fence?`,
answer: mediumNumber + smallNumber + smallNumber
},
// Sports fields (yards)
{
text: `Three football fields are marked. The practice field is ${mediumNumber} ${getUnit(mediumNumber, 'yard')} long. The junior field is ${smallNumber} ${getUnit(smallNumber, 'yard')} longer. The main field is ${smallNumber} ${getUnit(smallNumber, 'yard')} longer than the junior field. How long is the main field?`,
answer: mediumNumber + smallNumber + smallNumber
},
{
text: `${name1} runs three different tracks. The indoor track is ${mediumNumber} ${getUnit(mediumNumber, 'yard')} long. The outdoor track is ${smallNumber} ${getUnit(smallNumber, 'yard')} longer. The competition track is ${smallNumber} ${getUnit(smallNumber, 'yard')} longer than the outdoor track. How long is the competition track?`,
answer: mediumNumber + smallNumber + smallNumber
},
// Craft materials (inches)
{
text: `${name1} needs three pieces of string. The first piece is ${smallNumber} ${getUnit(smallNumber, 'inch')} long. The second piece needs to be ${smallNumber} ${getUnit(smallNumber, 'inch')} longer. The third piece needs to be ${smallNumber} ${getUnit(smallNumber, 'inch')} longer than the second. How long should the third piece be?`,
answer: smallNumber + smallNumber + smallNumber
},
{
text: `Three pieces of paper are cut. The first is ${mediumNumber} ${getUnit(mediumNumber, 'inch')} wide. The second is ${smallNumber} ${getUnit(smallNumber, 'inch')} wider. The third is ${smallNumber} ${getUnit(smallNumber, 'inch')} wider than the second. How wide is the third piece?`,
answer: mediumNumber + smallNumber + smallNumber
},
// Vehicle measurements (feet)
{
text: `Three parking spaces are marked. The compact space is ${mediumNumber} ${getUnit(mediumNumber, 'foot')} long. The standard space is ${smallNumber} ${getUnit(smallNumber, 'foot')} longer. The large vehicle space is ${smallNumber} ${getUnit(smallNumber, 'foot')} longer than the standard space. How long is the large vehicle space?`,
answer: mediumNumber + smallNumber + smallNumber
},
{
text: `Three boats are docked. The small boat needs ${mediumNumber} ${getUnit(mediumNumber, 'foot')} of space. The medium boat needs ${smallNumber} ${getUnit(smallNumber, 'foot')} more space. The large boat needs ${smallNumber} ${getUnit(smallNumber, 'foot')} more space than the medium boat. How much space does the large boat need?`,
answer: mediumNumber + smallNumber + smallNumber
},
// Home furnishings (inches)
{
text: `${name1} is comparing three tables. The coffee table is ${mediumNumber} ${getUnit(mediumNumber, 'inch')} tall. The end table is ${smallNumber} ${getUnit(smallNumber, 'inch')} taller. The dining table is ${smallNumber} ${getUnit(smallNumber, 'inch')} taller than the end table. How tall is the dining table?`,
answer: mediumNumber + smallNumber + smallNumber
},
{
text: `Three curtains are hung. The kitchen curtain is ${mediumNumber} ${getUnit(mediumNumber, 'inch')} long. The living room curtain is ${smallNumber} ${getUnit(smallNumber, 'inch')} longer. The dining room curtain is ${smallNumber} ${getUnit(smallNumber, 'inch')} longer than the living room curtain. How long is the dining room curtain?`,
answer: mediumNumber + smallNumber + smallNumber
},
// Construction materials (feet)
{
text: `Three lumber boards are cut. The first board is ${mediumNumber} ${getUnit(mediumNumber, 'foot')} long. The second board is ${smallNumber} ${getUnit(smallNumber, 'foot')} longer. The third board is ${smallNumber} ${getUnit(smallNumber, 'foot')} longer than the second. How long is the third board?`,
answer: mediumNumber + smallNumber + smallNumber
},
{
text: `${name1} needs three pipes. The shortest pipe is ${mediumNumber} ${getUnit(mediumNumber, 'foot')} long. The medium pipe is ${smallNumber} ${getUnit(smallNumber, 'foot')} longer. The longest pipe is ${smallNumber} ${getUnit(smallNumber, 'foot')} longer than the medium pipe. How long is the longest pipe?`,
answer: mediumNumber + smallNumber + smallNumber
},
// Fabric and sewing (inches)
{
text: `Three ribbons are needed for a project. The short ribbon is ${smallNumber} ${getUnit(smallNumber, 'inch')} long. The medium ribbon is ${smallNumber} ${getUnit(smallNumber, 'inch')} longer. The long ribbon is ${smallNumber} ${getUnit(smallNumber, 'inch')} longer than the medium ribbon. How long is the long ribbon?`,
answer: smallNumber + smallNumber + smallNumber
},
{
text: `${name1} is cutting three strips of fabric. The first strip is ${mediumNumber} ${getUnit(mediumNumber, 'inch')} long. The second strip is ${smallNumber} ${getUnit(smallNumber, 'inch')} longer. The third strip is ${smallNumber} ${getUnit(smallNumber, 'inch')} longer than the second. How long is the third strip?`,
answer: mediumNumber + smallNumber + smallNumber
},
// Outdoor spaces (yards)
{
text: `Three hiking trails are marked. The beginner trail is ${mediumNumber} ${getUnit(mediumNumber, 'yard')} long. The intermediate trail is ${smallNumber} ${getUnit(smallNumber, 'yard')} longer. The advanced trail is ${smallNumber} ${getUnit(smallNumber, 'yard')} longer than the intermediate trail. How long is the advanced trail?`,
answer: mediumNumber + smallNumber + smallNumber
},
{
text: `${name1}'s yard has three sections. The front yard is ${mediumNumber} ${getUnit(mediumNumber, 'yard')} long. The side yard is ${smallNumber} ${getUnit(smallNumber, 'yard')} longer. The back yard is ${smallNumber} ${getUnit(smallNumber, 'yard')} longer than the side yard. How long is the back yard?`,
answer: mediumNumber + smallNumber + smallNumber
},
// Pet equipment (inches)
{
text: `Three dog leashes are compared. The short leash is ${mediumNumber} ${getUnit(mediumNumber, 'inch')} long. The medium leash is ${smallNumber} ${getUnit(smallNumber, 'inch')} longer. The long leash is ${smallNumber} ${getUnit(smallNumber, 'inch')} longer than the medium leash. How long is the long leash?`,
answer: mediumNumber + smallNumber + smallNumber
},
{
text: `${name1} has three pet beds. The cat bed is ${smallNumber} ${getUnit(smallNumber, 'inch')} wide. The small dog bed is ${smallNumber} ${getUnit(smallNumber, 'inch')} wider. The large dog bed is ${smallNumber} ${getUnit(smallNumber, 'inch')} wider than the small dog bed. How wide is the large dog bed?`,
answer: smallNumber + smallNumber + smallNumber
}
];
const selectedProblem = problemTypes[Math.floor(Math.random() * problemTypes.length)];
const answer = selectedProblem.answer;
// Generate wrong answers that are close to the correct answer but always positive
function generateUniqueWrongAnswer(correctAnswer, existingAnswers) {
let attempt = 0;
let wrongAnswer;
do {
// Increase the range of wrong answers if we're having trouble finding unique ones
const range = attempt < 5 ? 5 : 10;
const offset = Math.random() < 0.5 ?
Math.floor(Math.random() * range) + 1 : // Always add at least 1
-(Math.min(Math.floor(Math.random() * range), correctAnswer - 1)); // Never subtract more than would make it 0
wrongAnswer = correctAnswer + offset;
attempt++;
} while ((existingAnswers.includes(wrongAnswer) || wrongAnswer <= 0) && attempt < 20);
return wrongAnswer > 0 ? wrongAnswer : correctAnswer + 1; // Fallback to ensure positive
}
// Generate three unique wrong answers
const wrongAnswers = [];
for (let i = 0; i < 3; i++) {
const wrongAnswer = generateUniqueWrongAnswer(answer, [...wrongAnswers, answer]);
if (wrongAnswer > 0 && !wrongAnswers.includes(wrongAnswer) && wrongAnswer !== answer) {
wrongAnswers.push(wrongAnswer);
}
}
// If we couldn't generate enough unique wrong answers, fill in with more distant positive numbers
while (wrongAnswers.length < 3) {
const offset = wrongAnswers.length * 5 + 5;
const wrongAnswer = answer + offset; // Always adding, ensuring positive
if (!wrongAnswers.includes(wrongAnswer) && wrongAnswer !== answer) {
wrongAnswers.push(wrongAnswer);
}
}
return {
text: selectedProblem.text,
answer: answer,
options: shuffleArray([answer, ...wrongAnswers])
};
}
// Game state
let currentProblem = null;
let currentProblemIndex = 0;
const problems = [];
const totalProblems = 50;
// Generate all problems at start
for (let i = 0; i < totalProblems; i++) {
problems.push(generateProblem());
}
// DOM elements
const problemText = document.getElementById('problem-text');
const optionsContainer = document.getElementById('options-container');
const prevButton = document.getElementById('prev-btn');
const nextButton = document.getElementById('next-btn');
// Event handlers
function handleOptionClick(option, index) {
const selectedAnswer = currentProblem.options[index];
const isCorrect = selectedAnswer === currentProblem.answer;
const allOptions = optionsContainer.querySelectorAll('.option');
if (isCorrect) {
animationSystem.handleCorrectAnswer(option, allOptions, () => {
// Auto-proceed to the next problem
if (currentProblemIndex < totalProblems - 1) {
currentProblemIndex++;
displayProblem();
} else {
console.log("Reached end of problems.");
// Optionally disable next button or handle end state
}
});
} else {
animationSystem.handleWrongAnswer(option);
}
}
function displayProblem() {
currentProblem = problems[currentProblemIndex];
problemText.textContent = currentProblem.text;
const options = optionsContainer.getElementsByClassName('option');
Array.from(options).forEach((option, index) => {
option.textContent = currentProblem.options[index];
option.className = 'option';
option.disabled = false;
option.onclick = () => handleOptionClick(option, index);
});
// Update navigation buttons
prevButton.disabled = currentProblemIndex === 0;
nextButton.disabled = currentProblemIndex === totalProblems - 1;
}
// Navigation handlers
prevButton.onclick = () => {
if (currentProblemIndex > 0) {
currentProblemIndex--;
displayProblem();
}
};
nextButton.onclick = () => {
if (currentProblemIndex < totalProblems - 1) {
currentProblemIndex++;
displayProblem();
}
};
// Initialize the first problem
setupScratchpad({ hideToggleWhenOpen: true });
displayProblem();