elyor-ml commited on
Commit
671ec71
·
1 Parent(s): 55e33a9

addition game

Browse files
Files changed (4) hide show
  1. README.md +79 -120
  2. package-lock.json +2 -2
  3. src/App.css +251 -199
  4. src/App.tsx +163 -224
README.md CHANGED
@@ -1,55 +1,53 @@
1
  ---
2
- title: Equal 2-Step Game
3
- emoji: ⚖️
4
- colorFrom: blue
5
- colorTo: purple
6
  sdk: docker
7
  pinned: false
8
- app_port: 7860
9
  ---
 
10
 
11
- # Equal 2-Step Game ⚖️
12
-
13
- An interactive educational game that teaches equality comparison and counting skills through engaging emoji-based questions. Perfect for children learning basic math concepts!
14
 
15
  ## 🎮 How to Play
16
 
17
- The game consists of **two sequential steps** that help children develop comparison and counting skills:
18
-
19
- ### Step 1: Equality Check
20
- - Look at the two sides with emojis
21
- - Count the items on each side
22
- - Answer the question: **"Are they equal?"**
23
- - Choose between **"Equal"** or **"Not Equal"**
24
-
25
- ### Step 2: Comparison (Only if Not Equal)
26
- - If you correctly answered "Not Equal" in Step 1, you proceed to Step 2
27
- - The game asks either:
28
- - **"Which side has more?"** or
29
- - **"Which side has fewer?"**
30
- - Click on the correct side to answer
31
 
32
- ### Game Flow
33
- 1. **Equal sides**: Step 1 Correct answer New question
34
- 2. **Unequal sides**: Step 1 Step 2 Correct answer → New question
 
 
 
 
 
 
35
 
36
  ## ✨ Features
37
 
38
- - **Visual Learning**: Uses colorful emojis from different categories (animals, fruits, objects, hearts, stars)
39
- - **Two-Step Logic**: Teaches both equality and comparison concepts
40
- - **Immediate Feedback**: Shows "Correct! 🎉" or "Try again! 🤔" messages
41
- - **Auto-Generated Questions**: Random emoji selection and counts (1-10 items)
42
- - **Responsive Design**: Works on desktop, tablet, and mobile devices
43
- - **Clean UI**: Simple, child-friendly interface with large buttons and clear visuals
 
 
 
 
44
 
45
  ## 🚀 How to Run
46
 
47
- ### Option 1: Development Mode
 
 
48
 
49
  ```bash
50
- # Clone the repository
51
- git clone <repository-url>
52
- cd equal-2-step-game
53
 
54
  # Install dependencies
55
  npm install
@@ -58,9 +56,9 @@ npm install
58
  npm run dev
59
  ```
60
 
61
- The game will be available at `http://localhost:5173`
62
 
63
- ### Option 2: Production Build
64
 
65
  ```bash
66
  # Build for production
@@ -70,122 +68,83 @@ npm run build
70
  npm run preview
71
  ```
72
 
73
- ### Option 3: Docker
 
 
74
 
75
  ```bash
76
- # Build Docker image
77
- docker build -t equal-2-step-game .
78
 
79
- # Run container
80
- docker run -p 3000:3000 equal-2-step-game
81
  ```
82
 
83
- The game will be available at `http://localhost:3000`
84
-
85
  ## 🎯 Educational Benefits
86
 
87
- - **Counting Skills**: Children practice counting objects up to 10
88
- - **Equality Concepts**: Understanding when quantities are the same
89
- - **Comparison Skills**: Learning "more than" and "fewer than" concepts
90
- - **Visual Recognition**: Identifying and categorizing different emoji types
91
- - **Logical Thinking**: Following two-step problem-solving processes
92
 
93
- ## 🎨 Game Categories
94
 
95
- The game uses emojis from 5 different categories:
 
96
 
97
- - **Animals**: 🐶 🐱 🐭 🐹 🐰 🦊 🐻 🐼 🐸 🐷
98
- - **Fruits**: 🍎 🍊 🍋 🍌 🍉 🍇 🍓 🫐 🍒 🥝
99
- - **Objects**: ⚽ 🏀 🎾 🏈 🎱 🎪 🎨 🎭 🎪 🎯
100
- - **Hearts**: 💙 💚 💛 💜 🤍 🖤 🤎 💗 💖 💕
101
- - **Stars**: ⭐ 🌟 💫 ✨ 🌠 ⚡ 🔥 ❄️ ☀️ 🌙
102
 
103
  ## 🛠️ Technical Details
104
 
105
  ### Technologies Used
106
- - **React 19** with TypeScript
107
- - **Vite** for build tooling
108
- - **CSS3** with modern features (Grid, Flexbox, Animations)
109
- - **Docker** for deployment
110
 
111
- ### Project Structure
 
 
 
 
 
112
  ```
113
  src/
114
- ├── App.tsx # Main game component
115
- ├── App.css # Game styling
116
- ├── main.tsx # App entry point
117
- └── index.css # Global styles
118
 
119
  public/
120
- ├── favicon.svg # App icon
121
- └── index.html # HTML template
122
- ```
123
-
124
- ### Game Logic
125
- - **Question Generation**: Random emoji selection from categories
126
- - **Count Generation**: Random numbers 1-10 for each side
127
- - **Equality Control**: 50% chance for equal vs unequal questions
128
- - **Step Control**: Step 2 only appears for unequal quantities
129
- - **Safety Checks**: Prevents step 2 from showing with equal sides
130
-
131
- ## 🎨 Customization
132
-
133
- You can easily customize the game by modifying the emoji categories in `src/App.tsx`:
134
-
135
- ```typescript
136
- const emojiCategories = {
137
- animals: ['🐶', '🐱', ...], // Add your animal emojis
138
- fruits: ['🍎', '🍊', ...], // Add your fruit emojis
139
- // Add more categories...
140
- };
141
  ```
142
 
143
  ## 📱 Mobile Support
144
 
145
- The game is fully responsive and optimized for:
146
- - **Desktop**: Full-featured experience with hover effects
147
- - **Tablet**: Touch-friendly interface with optimized sizing
148
- - **Mobile**: Compact layout with large touch targets
149
-
150
- ## 🚀 Deployment
151
-
152
- ### Hugging Face Spaces
153
- This project is configured for easy deployment to Hugging Face Spaces using Docker.
154
-
155
- ### Other Platforms
156
- The built project can be deployed to any static hosting service:
157
- - Vercel
158
- - Netlify
159
- - GitHub Pages
160
- - AWS S3
161
- - And more...
162
 
163
  ## 🤝 Contributing
164
 
165
- 1. Fork the repository
166
- 2. Create a feature branch: `git checkout -b feature-name`
167
- 3. Make your changes
168
- 4. Test thoroughly
169
- 5. Submit a pull request
 
 
170
 
171
  ## 📄 License
172
 
173
- MIT License - feel free to use this project for educational purposes!
174
 
175
  ## 🎓 Age Recommendation
176
 
177
- This game is designed for children ages **3-8** who are learning:
178
- - Basic counting (1-10)
179
- - Equality concepts
180
- - Comparison skills
181
- - Visual recognition
182
 
183
- Perfect for:
184
- - **Preschool** mathematics preparation
185
- - **Kindergarten** counting practice
186
- - **Early elementary** comparison skills
187
- - **Special education** visual learning support
188
 
189
  ---
190
 
191
- Made with ❤️ for young learners everywhere!
 
1
  ---
2
+ title: Addition Game
3
+ emoji:
4
+ colorFrom: green
5
+ colorTo: blue
6
  sdk: docker
7
  pinned: false
8
+ app_port: 7860 # Assuming Vite default port, adjust if different after changes
9
  ---
10
+ # Simple Addition Game ➕
11
 
12
+ An interactive educational game designed to teach basic addition (sums up to 5, extendable) to young children. It uses numbers, colorful emojis, or a combination of both to make learning fun and engaging!
 
 
13
 
14
  ## 🎮 How to Play
15
 
16
+ The game presents a simple addition problem (e.g., `1 + 2 = ?`).
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
+ 1. **Observe the Problem**: See the two numbers to be added.
19
+ 2. **Choose Display Mode**: At the top, select how you want to see the numbers:
20
+ * **Number**: Shows only numerals (e.g., `1` and `2`).
21
+ * **Object**: Shows only emojis (e.g., 🍎 and 🍎🍎).
22
+ * **Both**: Shows numerals in boxes with emojis underneath each.
23
+ 3. **Solve**: Determine the sum of the two numbers.
24
+ 4. **Select Answer**: Click on one of the three answer options provided at the bottom of the screen. One of these options is the correct sum.
25
+ 5. **Feedback**: The game will tell you if your answer is "Correct! 🎉" or "Try again! 🤔".
26
+ 6. **New Question**: After a correct answer, a new addition problem is automatically generated.
27
 
28
  ## ✨ Features
29
 
30
+ - **Visual Learning**: Uses numbers, a variety of emojis (fruits, animals, objects, etc.), or both to represent numbers.
31
+ - **Interactive Display Modes**: Children can switch between seeing problems as numbers, objects, or a combination, catering to different learning preferences.
32
+ - **Clear Question Format**: Presents addition problems in a clear, visual layout (e.g., `Num1 + Num2 = ?`).
33
+ - **Multiple Choice Answers**: Provides three options, making it easy for young children to select their answer.
34
+ - **Immediate Feedback**: Instant confirmation of correct or incorrect answers.
35
+ - **Score Tracking**: Keeps a simple score of correct answers.
36
+ - **Randomized Questions**: Generates addition problems with numbers from 0 to 5, ensuring the sum does not exceed 5 (configurable).
37
+ - **Reduced Zero Probability**: The chance of 0 appearing as an operand is intentionally lowered to provide more varied practice.
38
+ - **Responsive Design**: Adapts to different screen sizes (desktop, tablet, mobile).
39
+ - **Child-Friendly UI**: Large, easy-to-click buttons and clear, colorful visuals.
40
 
41
  ## 🚀 How to Run
42
 
43
+ This project is built with React (using Vite) and TypeScript.
44
+
45
+ ### Development Mode
46
 
47
  ```bash
48
+ # Clone the repository (if you haven't already)
49
+ # git clone <repository-url>
50
+ # cd <repository-name>
51
 
52
  # Install dependencies
53
  npm install
 
56
  npm run dev
57
  ```
58
 
59
+ The game will typically be available at `http://localhost:5173` (Vite's default port).
60
 
61
+ ### Production Build
62
 
63
  ```bash
64
  # Build for production
 
68
  npm run preview
69
  ```
70
 
71
+ ### Docker
72
+
73
+ If a `Dockerfile` is configured (the one from the previous game might need adjustments for port or build steps if they changed significantly):
74
 
75
  ```bash
76
+ # Build Docker image (example name)
77
+ docker build -t addition-game .
78
 
79
+ # Run container (example mapping to port 3000 on host)
80
+ docker run -p 3000:5173 addition-game
81
  ```
82
 
 
 
83
  ## 🎯 Educational Benefits
84
 
85
+ - **Basic Addition Skills**: Children practice adding numbers with sums typically up to 5 (can be easily extended).
86
+ - **Number Recognition**: Reinforces the visual representation of numbers.
87
+ - **Object Counting**: Connects numerals with quantities of objects.
88
+ - **Problem Solving**: Encourages children to think through and solve simple math problems.
89
+ - **Visual-Numeric Association**: Helps bridge the gap between abstract numbers and concrete objects, especially in "Both" mode.
90
 
91
+ ## 🎨 Emoji Pool
92
 
93
+ The game uses a diverse pool of emojis to represent objects, including:
94
+ 🍎 🍊 🍋 🍌 🍉 🍇 🍓 🫐 🍒 🥝 🐶 🐱 🐭 🐹 🐰 🦊 🐻 🐼 🐸 🐷 ⚽ 🏀 🎾 🏈 🎱 🎨 🎭 🎯 🚗 🚕 🚓 🚑 🚁 🚀
95
 
96
+ This pool can be easily modified in `src/App.tsx`.
 
 
 
 
97
 
98
  ## 🛠️ Technical Details
99
 
100
  ### Technologies Used
 
 
 
 
101
 
102
+ - **React** with TypeScript
103
+ - **Vite** for build tooling and development server
104
+ - **CSS3** for styling
105
+
106
+ ### Project Structure (Key Files)
107
+
108
  ```
109
  src/
110
+ ├── App.tsx # Main game component, logic, and JSX structure
111
+ ├── App.css # Styling for the game
112
+ ├── main.tsx # Application entry point
113
+ └── index.css # Global styles (if any beyond App.css)
114
 
115
  public/
116
+ ├── index.html # HTML template
117
+ └── ... # Other static assets like favicons
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  ```
119
 
120
  ## 📱 Mobile Support
121
 
122
+ The game is designed to be responsive and playable on various devices, including desktops, tablets, and mobile phones.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
 
124
  ## 🤝 Contributing
125
 
126
+ Contributions are welcome! Please follow standard Git practices:
127
+
128
+ 1. Fork the repository.
129
+ 2. Create a new branch for your feature (`git checkout -b feature/YourFeature`).
130
+ 3. Commit your changes (`git commit -m 'Add some feature'`).
131
+ 4. Push to the branch (`git push origin feature/YourFeature`).
132
+ 5. Open a Pull Request.
133
 
134
  ## 📄 License
135
 
136
+ This project is typically licensed under the MIT License (please verify if a `LICENSE` file exists or add one as appropriate).
137
 
138
  ## 🎓 Age Recommendation
139
 
140
+ This game is suitable for children typically in **Preschool to early Elementary grades (ages 3-7)** who are beginning to learn:
141
+
142
+ - Number identification
143
+ - Basic counting
144
+ - The concept of addition
145
 
146
+ It can serve as a fun tool for parents and educators to introduce and reinforce these early math skills.
 
 
 
 
147
 
148
  ---
149
 
150
+ Made with ❤️ for young learners everywhere!
package-lock.json CHANGED
@@ -1,11 +1,11 @@
1
  {
2
- "name": "equal-2-step-game",
3
  "version": "1.0.0",
4
  "lockfileVersion": 3,
5
  "requires": true,
6
  "packages": {
7
  "": {
8
- "name": "equal-2-step-game",
9
  "version": "1.0.0",
10
  "dependencies": {
11
  "react": "^19.0.0",
 
1
  {
2
+ "name": "preposition-learning-game",
3
  "version": "1.0.0",
4
  "lockfileVersion": 3,
5
  "requires": true,
6
  "packages": {
7
  "": {
8
+ "name": "preposition-learning-game",
9
  "version": "1.0.0",
10
  "dependencies": {
11
  "react": "^19.0.0",
src/App.css CHANGED
@@ -1,282 +1,334 @@
1
- /* Main container */
2
- .equal-game {
3
- min-height: 100vh;
 
 
4
  display: flex;
5
- flex-direction: column;
6
- align-items: center;
7
  justify-content: center;
8
- padding: 2rem;
9
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
10
- font-family: 'Arial', sans-serif;
 
 
11
  }
12
 
13
- /* Loading state */
14
- .loading {
 
 
 
 
 
 
 
 
 
 
15
  display: flex;
16
- justify-content: center;
17
  align-items: center;
18
- height: 100vh;
19
- font-size: 1.5rem;
20
- font-weight: bold;
21
- color: white;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  }
23
 
24
- /* Question title */
25
- .question-title {
26
- font-size: 3rem;
27
  font-weight: bold;
28
- color: white;
29
- text-align: center;
30
- margin-bottom: 2rem;
31
- text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  }
33
 
34
- /* Comparison container */
35
- .comparison-container {
36
  display: flex;
 
37
  align-items: center;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  justify-content: center;
39
- gap: 3rem;
40
- margin-bottom: 3rem;
41
- flex-wrap: wrap;
42
  }
43
 
44
- /* Side container */
45
- .side-container {
46
- background: white;
47
- border-radius: 20px;
48
- padding: 2rem;
49
- box-shadow: 0 8px 25px rgba(0,0,0,0.15);
50
- min-width: 300px;
51
- max-width: 400px;
52
  display: flex;
53
- flex-direction: column;
 
54
  align-items: center;
55
- gap: 1rem;
56
- transition: transform 0.2s ease, box-shadow 0.2s ease;
 
57
  }
58
 
59
- .side-container.clickable {
60
- cursor: pointer;
 
61
  }
62
 
63
- .side-container.clickable:hover {
64
- transform: scale(1.05);
65
- box-shadow: 0 12px 35px rgba(0,0,0,0.2);
 
 
 
 
 
66
  }
67
 
68
- /* Emoji grid */
69
- .emoji-grid {
70
- display: grid;
71
- grid-template-columns: repeat(auto-fit, minmax(40px, 1fr));
72
- gap: 8px;
73
- max-width: 300px;
74
- justify-items: center;
 
75
  }
76
 
77
- .emoji-item {
78
- font-size: 2rem;
79
- display: block;
80
- animation: popIn 0.3s ease-out;
81
  }
82
 
83
- @keyframes popIn {
84
- 0% {
85
- transform: scale(0);
86
- }
87
- 80% {
88
- transform: scale(1.1);
89
- }
90
- 100% {
91
- transform: scale(1);
92
- }
93
  }
94
 
95
- /* Count display */
96
- .count-display {
97
- font-size: 2.5rem;
98
  font-weight: bold;
99
- color: #333;
100
- background: #f0f0f0;
 
101
  border-radius: 50%;
102
- width: 80px;
103
- height: 80px;
104
  display: flex;
105
- align-items: center;
106
  justify-content: center;
107
- border: 3px solid #ddd;
 
108
  }
109
 
110
- /* VS divider */
111
- .vs-divider {
112
- font-size: 2rem;
113
  font-weight: bold;
114
- color: white;
115
- background: rgba(255,255,255,0.2);
116
- border-radius: 50%;
117
- width: 80px;
118
- height: 80px;
119
  display: flex;
120
- align-items: center;
121
  justify-content: center;
122
- text-shadow: 1px 1px 2px rgba(0,0,0,0.3);
 
 
123
  }
124
 
125
- /* Answer buttons for step 1 */
126
- .answer-buttons {
127
  display: flex;
128
- gap: 2rem;
129
  justify-content: center;
130
- flex-wrap: wrap;
 
131
  }
132
 
133
- .answer-btn {
134
- padding: 1.5rem 3rem;
135
- font-size: 1.5rem;
136
  font-weight: bold;
137
- border: none;
 
 
 
138
  border-radius: 15px;
139
  cursor: pointer;
140
- transition: all 0.3s ease;
141
- min-width: 150px;
142
- box-shadow: 0 4px 15px rgba(0,0,0,0.2);
143
  }
144
 
145
- .equal-btn {
146
- background: linear-gradient(45deg, #4CAF50, #45a049);
147
- color: white;
 
148
  }
149
 
150
- .equal-btn:hover {
151
- background: linear-gradient(45deg, #45a049, #4CAF50);
152
- transform: translateY(-2px);
153
- box-shadow: 0 6px 20px rgba(0,0,0,0.3);
154
- }
155
-
156
- .not-equal-btn {
157
- background: linear-gradient(45deg, #f44336, #d32f2f);
158
- color: white;
159
  }
160
 
161
- .not-equal-btn:hover {
162
- background: linear-gradient(45deg, #d32f2f, #f44336);
163
- transform: translateY(-2px);
164
- box-shadow: 0 6px 20px rgba(0,0,0,0.3);
165
  }
166
 
167
- /* Step 2 instruction */
168
- .step2-instruction {
169
- font-size: 1.2rem;
170
- color: white;
171
  text-align: center;
172
- margin-top: 1rem;
173
- background: rgba(255,255,255,0.1);
174
- padding: 1rem 2rem;
175
- border-radius: 10px;
176
- backdrop-filter: blur(10px);
177
  }
178
 
179
- /* Feedback message */
180
- .feedback-message {
181
- position: fixed;
182
- top: 50%;
183
- left: 50%;
184
- transform: translate(-50%, -50%);
185
- background: white;
186
- color: #333;
187
- font-size: 2rem;
188
- font-weight: bold;
189
- padding: 2rem 3rem;
190
- border-radius: 20px;
191
- box-shadow: 0 10px 30px rgba(0,0,0,0.3);
192
- z-index: 1000;
193
- animation: feedbackPop 0.5s ease-out;
194
- }
195
 
196
- @keyframes feedbackPop {
197
- 0% {
198
- transform: translate(-50%, -50%) scale(0);
 
199
  }
200
- 80% {
201
- transform: translate(-50%, -50%) scale(1.1);
 
202
  }
203
- 100% {
204
- transform: translate(-50%, -50%) scale(1);
205
  }
206
- }
207
-
208
- /* Responsive design */
209
- @media (max-width: 768px) {
210
- .question-title {
211
- font-size: 2rem;
212
- margin-bottom: 1.5rem;
213
  }
214
-
215
- .comparison-container {
216
- gap: 2rem;
217
- flex-direction: column;
218
  }
219
-
220
- .side-container {
221
- min-width: 250px;
222
- max-width: 300px;
223
- padding: 1.5rem;
 
224
  }
225
-
226
- .vs-divider {
227
- width: 60px;
228
- height: 60px;
229
- font-size: 1.5rem;
230
  }
231
-
232
- .emoji-item {
233
- font-size: 1.5rem;
234
  }
235
-
236
- .count-display {
237
- width: 60px;
238
- height: 60px;
239
- font-size: 2rem;
240
  }
241
-
242
- .answer-buttons {
243
- flex-direction: column;
244
- align-items: center;
245
- gap: 1rem;
246
  }
247
-
248
- .answer-btn {
249
- padding: 1rem 2rem;
250
- font-size: 1.2rem;
251
- min-width: 200px;
 
 
 
 
 
 
 
 
 
 
252
  }
253
-
254
  .feedback-message {
255
  font-size: 1.5rem;
256
- padding: 1.5rem 2rem;
257
  }
258
  }
259
 
260
  @media (max-width: 480px) {
261
- .equal-game {
262
- padding: 1rem;
 
263
  }
264
-
265
- .question-title {
266
- font-size: 1.5rem;
267
  }
268
-
269
- .side-container {
270
- min-width: 200px;
271
- max-width: 250px;
272
- padding: 1rem;
 
273
  }
274
-
275
- .emoji-grid {
276
- max-width: 200px;
277
  }
278
-
279
- .emoji-item {
280
- font-size: 1.2rem;
 
281
  }
 
 
 
 
 
 
 
 
 
282
  }
 
1
+ /* General App Styles */
2
+ body {
3
+ font-family: 'Arial', sans-serif;
4
+ background-color: #f0f8ff; /* Light alice blue */
5
+ color: #333;
6
  display: flex;
 
 
7
  justify-content: center;
8
+ align-items: center;
9
+ min-height: 100vh;
10
+ margin: 0;
11
+ padding: 20px;
12
+ box-sizing: border-box;
13
  }
14
 
15
+ .app-container {
16
+ background-color: #fff;
17
+ padding: 30px;
18
+ border-radius: 20px;
19
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
20
+ text-align: center;
21
+ width: 100%;
22
+ max-width: 900px; /* Max width adjusted for new layout */
23
+ }
24
+
25
+ .game-header {
26
+ margin-bottom: 30px;
27
  display: flex;
28
+ justify-content: space-between;
29
  align-items: center;
30
+ padding-bottom: 20px;
31
+ border-bottom: 2px solid #e0e0e0;
32
+ }
33
+
34
+ .game-header h1 {
35
+ font-size: 2.5rem;
36
+ color: #007bff;
37
+ margin: 0;
38
+ }
39
+
40
+ .display-mode-selector button {
41
+ font-size: 1.3rem;
42
+ padding: 10px 18px;
43
+ margin: 0 8px;
44
+ border: 2px solid #007bff;
45
+ background-color: #fff;
46
+ color: #007bff;
47
+ border-radius: 10px;
48
+ cursor: pointer;
49
+ transition: background-color 0.3s, color 0.3s;
50
+ }
51
+
52
+ .display-mode-selector button:hover {
53
+ background-color: #0056b3;
54
+ color: #fff;
55
+ }
56
+
57
+ .display-mode-selector button.active {
58
+ background-color: #007bff;
59
+ color: #fff;
60
  }
61
 
62
+ .score-display {
63
+ font-size: 1.6rem;
 
64
  font-weight: bold;
65
+ color: #28a745;
66
+ }
67
+
68
+ /* Game Area Styles */
69
+ .game-area {
70
+ padding: 20px;
71
+ }
72
+
73
+ /* New Question Container for 5-column layout */
74
+ .question-container-new {
75
+ display: flex;
76
+ justify-content: space-around; /* Distribute columns */
77
+ align-items: flex-start; /* Align tops of columns */
78
+ background-color: #fffacd; /* Light yellow background like image */
79
+ padding: 20px;
80
+ border-radius: 15px;
81
+ margin-bottom: 30px;
82
+ border: 1px solid #ddd; /* Soft border */
83
  }
84
 
85
+ .operand-column, .result-column {
 
86
  display: flex;
87
+ flex-direction: column;
88
  align-items: center;
89
+ justify-content: center; /* Center content like the question mark */
90
+ gap: 15px;
91
+ flex: 1;
92
+ padding: 10px;
93
+ min-height: 150px; /* Ensure it has some height to center the ? vertically */
94
+ }
95
+
96
+ .number-box {
97
+ background-color: #fff;
98
+ border: 1px solid #ccc;
99
+ border-radius: 10px;
100
+ padding: 20px 30px;
101
+ min-width: 80px; /* Minimum width for the number box */
102
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
103
+ display: inline-flex; /* To make it wrap content tightly */
104
  justify-content: center;
105
+ align-items: center;
 
 
106
  }
107
 
108
+ .number-text {
109
+ font-size: 3.5rem; /* Large numbers */
110
+ font-weight: bold;
111
+ color: #333;
112
+ }
113
+
114
+ .objects-display {
 
115
  display: flex;
116
+ flex-direction: column; /* Stack objects vertically as in image */
117
+ justify-content: center;
118
  align-items: center;
119
+ gap: 8px;
120
+ min-height: 60px; /* Base height even if empty */
121
+ width: 100%;
122
  }
123
 
124
+ .item-object {
125
+ font-size: 2.5rem !important; /* Adjusted emoji size */
126
+ padding: 2px;
127
  }
128
 
129
+ .operator-cell {
130
+ display: flex;
131
+ flex-direction: column; /* To center operator and have line above/below */
132
+ align-items: center;
133
+ justify-content: center; /* Center the operator symbol vertically */
134
+ position: relative; /* For pseudo-elements for lines */
135
+ align-self: stretch; /* Make cell take full height of question-container-new */
136
+ padding: 0 20px; /* Horizontal padding around operator */
137
  }
138
 
139
+ .operator-cell::before, .operator-cell::after {
140
+ content: '';
141
+ position: absolute;
142
+ left: 50%;
143
+ transform: translateX(-50%);
144
+ width: 2px; /* Width of the vertical line */
145
+ background-color: #bdbdbd; /* Color of the vertical line */
146
+ height: calc(50% - 25px); /* Adjust based on operator symbol size and desired gap */
147
  }
148
 
149
+ .operator-cell::before {
150
+ top: 0;
 
 
151
  }
152
 
153
+ .operator-cell::after {
154
+ bottom: 0;
 
 
 
 
 
 
 
 
155
  }
156
 
157
+ .operator-symbol {
158
+ font-size: 2rem;
 
159
  font-weight: bold;
160
+ color: #555;
161
+ background-color: #fff;
162
+ border: 2px solid #bdbdbd;
163
  border-radius: 50%;
164
+ width: 40px;
165
+ height: 40px;
166
  display: flex;
 
167
  justify-content: center;
168
+ align-items: center;
169
+ z-index: 1; /* To appear above the pseudo-element lines */
170
  }
171
 
172
+ .answer-placeholder-new {
173
+ font-size: 4rem; /* Large question mark */
 
174
  font-weight: bold;
175
+ color: #dc3545; /* Red color or similar to operand numbers */
 
 
 
 
176
  display: flex;
 
177
  justify-content: center;
178
+ align-items: center;
179
+ /* If it needs a box like numbers, we can add similar styling to .number-box here */
180
+ /* For now, just a large character */
181
  }
182
 
183
+ /* Options Styles - Assuming these are still relevant */
184
+ .options-container {
185
  display: flex;
 
186
  justify-content: center;
187
+ gap: 20px;
188
+ margin-bottom: 30px;
189
  }
190
 
191
+ .option-button {
192
+ font-size: 2.5rem;
 
193
  font-weight: bold;
194
+ padding: 20px 35px;
195
+ border: 3px solid #28a745;
196
+ background-color: #fff;
197
+ color: #28a745;
198
  border-radius: 15px;
199
  cursor: pointer;
200
+ transition: background-color 0.3s, color 0.3s, transform 0.2s;
201
+ min-width: 90px;
 
202
  }
203
 
204
+ .option-button:hover {
205
+ background-color: #218838;
206
+ color: #fff;
207
+ transform: translateY(-3px);
208
  }
209
 
210
+ /* Feedback Message Styles */
211
+ .feedback-message {
212
+ font-size: 1.8rem;
213
+ font-weight: bold;
214
+ margin-top: 25px;
215
+ padding: 15px;
216
+ border-radius: 10px;
217
+ color: #fff;
218
+ /* Assuming JS still sets background color for correct/incorrect, or do it here */
219
  }
220
 
221
+ .feedback-message:empty {
222
+ display: none;
 
 
223
  }
224
 
225
+ /* Loading State */
226
+ .loading {
227
+ font-size: 2rem;
 
228
  text-align: center;
229
+ padding: 50px;
230
+ color: #007bff;
 
 
 
231
  }
232
 
233
+ /* Remove old styles that are no longer used */
234
+ /* .question-container, .operand-stack, .operator, .answer-placeholder (and their media queries if specific) */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
 
236
+ /* Responsive adjustments for the new layout */
237
+ @media (max-width: 768px) {
238
+ .game-header h1 {
239
+ font-size: 2rem;
240
  }
241
+ .display-mode-selector button {
242
+ font-size: 1.1rem;
243
+ padding: 8px 12px;
244
  }
245
+ .score-display {
246
+ font-size: 1.3rem;
247
  }
248
+ .question-container-new {
249
+ flex-direction: column; /* Stack columns vertically on smaller screens */
250
+ align-items: center; /* Center columns when stacked */
251
+ padding: 15px;
 
 
 
252
  }
253
+ .operand-column, .result-column {
254
+ width: 100%; /* Make columns take full width when stacked */
255
+ max-width: 300px; /* Limit width of operand columns */
256
+ gap: 10px;
257
  }
258
+ .operator-cell {
259
+ flex-direction: row; /* Operators side by side with lines */
260
+ align-self: auto; /* Reset self-stretch */
261
+ padding: 10px 0;
262
+ width: 80%;
263
+ max-width: 250px;
264
  }
265
+ .operator-cell::before, .operator-cell::after {
266
+ width: calc(50% - 25px); /* Horizontal lines */
267
+ height: 2px;
268
+ top: 50%;
269
+ transform: translateY(-50%);
270
  }
271
+ .operator-cell::before {
272
+ left: 0;
 
273
  }
274
+ .operator-cell::after {
275
+ right: 0;
276
+ left: auto; /* Override previous left: 50% */
 
 
277
  }
278
+ .number-text {
279
+ font-size: 2.8rem;
 
 
 
280
  }
281
+ .item-object {
282
+ font-size: 2rem !important;
283
+ }
284
+ .operator-symbol {
285
+ font-size: 1.5rem;
286
+ width: 35px;
287
+ height: 35px;
288
+ }
289
+ .options-container {
290
+ flex-direction: column;
291
+ gap: 10px;
292
+ }
293
+ .option-button {
294
+ font-size: 2rem;
295
+ padding: 15px 25px;
296
  }
 
297
  .feedback-message {
298
  font-size: 1.5rem;
 
299
  }
300
  }
301
 
302
  @media (max-width: 480px) {
303
+ .game-header {
304
+ flex-direction: column;
305
+ gap: 10px;
306
  }
307
+ .game-header h1 {
308
+ font-size: 1.6rem;
 
309
  }
310
+ .display-mode-selector button {
311
+ font-size: 1rem;
312
+ padding: 6px 10px;
313
+ }
314
+ .number-text {
315
+ font-size: 2.2rem;
316
  }
317
+ .item-object {
318
+ font-size: 1.8rem !important;
 
319
  }
320
+ .operator-symbol {
321
+ font-size: 1.3rem;
322
+ width: 30px;
323
+ height: 30px;
324
  }
325
+ .option-button {
326
+ font-size: 1.6rem;
327
+ padding: 12px 20px;
328
+ }
329
+ }
330
+
331
+ /* Clean up old, unused styles - This should be done carefully after verifying */
332
+ .question-container, .operand-stack, .operator, .answer-placeholder, .result-objects-display {
333
+ display: none !important; /* Hide them if they are still in the DOM somehow */
334
  }
src/App.tsx CHANGED
@@ -1,263 +1,202 @@
1
  import { useState, useEffect } from 'react'
2
  import './App.css'
3
 
4
- // Game question structure
5
- interface ComparisonQuestion {
6
- leftSide: string[];
7
- rightSide: string[];
8
- isEqual: boolean;
9
- secondStepQuestion: 'more' | 'fewer';
 
 
 
 
10
  }
11
 
12
- // Game states
13
- type GameStep = 'step1' | 'step2' | 'correct-step1' | 'correct-step2';
14
 
15
  function App() {
16
- const [currentQuestion, setCurrentQuestion] = useState<ComparisonQuestion | null>(null);
17
- const [gameStep, setGameStep] = useState<GameStep>('step1');
18
  const [feedback, setFeedback] = useState('');
19
- const [showFeedback, setShowFeedback] = useState(false);
20
 
21
- // Emoji pools for different categories
22
- const emojiCategories = {
23
- animals: ['🐶', '🐱', '🐭', '🐹', '🐰', '🦊', '🐻', '🐼', '🐸', '🐷'],
24
- fruits: ['🍎', '🍊', '🍋', '🍌', '🍉', '🍇', '🍓', '🫐', '🍒', '🥝'],
25
- objects: ['⚽', '🏀', '🎾', '🏈', '🎱', '🎪', '🎨', '🎭', '🎪', '🎯'],
26
- hearts: ['💙', '💚', '💛', '💜', '🤍', '🖤', '🤎', '💗', '💖', '💕'],
27
- stars: ['⭐', '🌟', '💫', '✨', '🌠', '⚡', '🔥', '❄️', '☀️', '🌙']
28
  };
29
 
30
- // Generate a random question
31
- const generateQuestion = (): ComparisonQuestion => {
32
- const categories = Object.keys(emojiCategories) as (keyof typeof emojiCategories)[];
33
- const selectedCategory = categories[Math.floor(Math.random() * categories.length)];
34
- const emojis = emojiCategories[selectedCategory];
35
-
36
- // Pick a random emoji for this question
37
- const emoji = emojis[Math.floor(Math.random() * emojis.length)];
38
-
39
- // Generate counts (1-10)
40
- const leftCount = Math.floor(Math.random() * 10) + 1;
41
- let rightCount = Math.floor(Math.random() * 10) + 1;
42
-
43
- // 50% chance of making them equal
44
- const shouldBeEqual = Math.random() < 0.5;
45
- if (shouldBeEqual) {
46
- rightCount = leftCount;
47
  }
48
-
49
- // Create arrays with repeated emoji
50
- const leftSide = Array(leftCount).fill(emoji);
51
- const rightSide = Array(rightCount).fill(emoji);
52
-
53
- // Determine second step question type
54
- const secondStepQuestion: 'more' | 'fewer' = Math.random() < 0.5 ? 'more' : 'fewer';
55
-
56
- return {
57
- leftSide,
58
- rightSide,
59
- isEqual: leftCount === rightCount,
60
- secondStepQuestion
61
- };
62
  };
63
 
64
- // Initialize with first question
65
- useEffect(() => {
66
- setCurrentQuestion(generateQuestion());
67
- }, []);
68
 
69
- // Safety effect: if we're in step 2 but sides are equal, generate new question
70
- useEffect(() => {
71
- if (currentQuestion &&
72
- (gameStep === 'step2' || gameStep === 'correct-step2') &&
73
- currentQuestion.leftSide.length === currentQuestion.rightSide.length) {
74
- // Generate new question and go back to step 1
75
- setTimeout(() => {
76
- setCurrentQuestion(generateQuestion());
77
- setGameStep('step1');
78
- }, 1000);
79
- }
80
- }, [currentQuestion, gameStep]);
81
 
82
- // Handle step 1 answer (equal/not equal)
83
- const handleStep1Answer = (answer: 'equal' | 'not-equal') => {
84
- if (!currentQuestion) return;
85
-
86
- const isCorrect = (answer === 'equal') === currentQuestion.isEqual;
87
-
88
- if (isCorrect) {
89
- setFeedback('Correct! 🎉');
90
- setShowFeedback(true);
91
- setGameStep('correct-step1');
92
-
93
- // If they correctly identified as "equal", generate new question
94
- // If they correctly identified as "not equal", proceed to step 2
95
- if (answer === 'equal') {
96
- // Generate new question after delay
97
- setTimeout(() => {
98
- setCurrentQuestion(generateQuestion());
99
- setGameStep('step1');
100
- setShowFeedback(false);
101
- setFeedback('');
102
- }, 2000);
103
- } else {
104
- // Proceed to step 2 only if they are NOT equal
105
- setTimeout(() => {
106
- setGameStep('step2');
107
- setShowFeedback(false);
108
- setFeedback('');
109
- }, 1500);
110
  }
111
- } else {
112
- setFeedback('Try again! 🤔');
113
- setShowFeedback(true);
114
- setTimeout(() => {
115
- setShowFeedback(false);
116
- setFeedback('');
117
- }, 1000);
118
  }
119
- };
120
 
121
- // Handle step 2 answer (more/fewer)
122
- const handleStep2Answer = (answer: 'left' | 'right') => {
123
- if (!currentQuestion) return;
124
-
125
- const leftCount = currentQuestion.leftSide.length;
126
- const rightCount = currentQuestion.rightSide.length;
127
-
128
- // Safety check: if sides are equal, this shouldn't happen in step 2
129
- if (leftCount === rightCount) {
130
- // Generate new question and go back to step 1
131
- setCurrentQuestion(generateQuestion());
132
- setGameStep('step1');
133
- return;
134
- }
135
-
136
- let isCorrect = false;
137
-
138
- if (currentQuestion.secondStepQuestion === 'more') {
139
- if (leftCount > rightCount && answer === 'left') isCorrect = true;
140
- if (rightCount > leftCount && answer === 'right') isCorrect = true;
141
- } else { // fewer
142
- if (leftCount < rightCount && answer === 'left') isCorrect = true;
143
- if (rightCount < leftCount && answer === 'right') isCorrect = true;
144
  }
145
-
146
- if (isCorrect) {
147
- setFeedback('Excellent! 🌟');
148
- setShowFeedback(true);
149
- setGameStep('correct-step2');
150
-
151
- // Generate new question after delay
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  setTimeout(() => {
153
- setCurrentQuestion(generateQuestion());
154
- setGameStep('step1');
155
- setShowFeedback(false);
156
- setFeedback('');
157
- }, 2000);
158
- } else {
159
  setFeedback('Try again! 🤔');
160
- setShowFeedback(true);
161
  setTimeout(() => {
162
- setShowFeedback(false);
163
  setFeedback('');
164
  }, 1000);
165
  }
166
  };
167
 
168
- // Render emoji grid
169
- const renderEmojiSide = (emojis: string[], side: 'left' | 'right') => {
170
- const gridClass = `emoji-grid ${side}`;
171
- return (
172
- <div className={gridClass}>
173
- {emojis.map((emoji, index) => (
174
- <span key={index} className="emoji-item">
175
- {emoji}
176
- </span>
177
- ))}
178
- </div>
179
- );
180
- };
181
-
182
  if (!currentQuestion) {
183
- return <div className="loading">Loading...</div>;
184
  }
185
 
 
 
 
186
  return (
187
- <div className="equal-game">
188
- {gameStep === 'step1' || gameStep === 'correct-step1' ? (
189
- // Step 1: Are they equal?
190
- <>
191
- <h1 className="question-title">Are they equal?</h1>
192
-
193
- <div className="comparison-container">
194
- <div className="side-container">
195
- {renderEmojiSide(currentQuestion.leftSide, 'left')}
196
- <div className="count-display">{currentQuestion.leftSide.length}</div>
197
- </div>
198
-
199
- <div className="vs-divider">VS</div>
200
-
201
- <div className="side-container">
202
- {renderEmojiSide(currentQuestion.rightSide, 'right')}
203
- <div className="count-display">{currentQuestion.rightSide.length}</div>
204
- </div>
 
 
 
 
 
 
 
 
 
 
 
205
  </div>
206
-
207
- {gameStep === 'step1' && (
208
- <div className="answer-buttons">
209
- <button
210
- className="answer-btn equal-btn"
211
- onClick={() => handleStep1Answer('equal')}
212
- >
213
- Equal
214
- </button>
215
- <button
216
- className="answer-btn not-equal-btn"
217
- onClick={() => handleStep1Answer('not-equal')}
218
- >
219
- Not Equal
220
- </button>
221
- </div>
222
- )}
223
- </>
224
- ) : (
225
- // Step 2: Which side has more/fewer? (Only if sides are NOT equal)
226
- currentQuestion.leftSide.length !== currentQuestion.rightSide.length ? (
227
- <>
228
- <h1 className="question-title">
229
- Which side has {currentQuestion.secondStepQuestion}?
230
- </h1>
231
-
232
- <div className="comparison-container">
233
- <div className="side-container clickable" onClick={() => handleStep2Answer('left')}>
234
- {renderEmojiSide(currentQuestion.leftSide, 'left')}
235
- <div className="count-display">{currentQuestion.leftSide.length}</div>
236
  </div>
237
-
238
- <div className="vs-divider">VS</div>
239
-
240
- <div className="side-container clickable" onClick={() => handleStep2Answer('right')}>
241
- {renderEmojiSide(currentQuestion.rightSide, 'right')}
242
- <div className="count-display">{currentQuestion.rightSide.length}</div>
243
  </div>
244
- </div>
245
-
246
- <div className="step2-instruction">
247
- Click on the side with {currentQuestion.secondStepQuestion} items
248
- </div>
249
- </>
250
- ) : (
251
- // If somehow we get to step 2 with equal sides, generate new question
252
- <div className="loading">Generating new question...</div>
253
- )
254
- )}
255
-
256
- {showFeedback && (
257
- <div className="feedback-message">
258
- {feedback}
259
  </div>
260
- )}
 
 
 
 
 
 
 
 
 
 
261
  </div>
262
  );
263
  }
 
1
  import { useState, useEffect } from 'react'
2
  import './App.css'
3
 
4
+ // Define the types for the game
5
+ type DisplayMode = 'numbers' | 'objects' | 'both';
6
+
7
+ interface AdditionQuestion {
8
+ num1: number;
9
+ num2: number;
10
+ answer: number;
11
+ options: number[];
12
+ object1: string;
13
+ object2: string;
14
  }
15
 
16
+ // Emoji pool
17
+ const emojis = ['🍎', '🍊', '🍋', '🍌', '🍉', '🍇', '🍓', '🫐', '🍒', '🥝', '🐶', '🐱', '🐭', '🐹', '🐰', '🦊', '🐻', '🐼', '🐸', '🐷', '⚽', '🏀', '🎾', '🏈', '🎱', '🎨', '🎭', '🎯', '🚗', '🚕', '🚓', '🚑', '🚁', '🚀'];
18
 
19
  function App() {
20
+ const [currentQuestion, setCurrentQuestion] = useState<AdditionQuestion | null>(null);
21
+ const [displayMode, setDisplayMode] = useState<DisplayMode>('numbers');
22
  const [feedback, setFeedback] = useState('');
23
+ const [score, setScore] = useState(0);
24
 
25
+ // Generate a random number between min and max (inclusive)
26
+ const getRandomNumber = (min: number, max: number) => {
27
+ return Math.floor(Math.random() * (max - min + 1)) + min;
 
 
 
 
28
  };
29
 
30
+ // Helper function to get an operand (0-5) with a reduced chance of it being 0
31
+ const getOperandWithReducedZero = (maxValue: number): number => {
32
+ const CHANCE_OF_BEING_ZERO = 0.10; // 10% chance the operand is 0
33
+
34
+ if (maxValue < 0) maxValue = 0; // Ensure maxValue is not negative
35
+ if (maxValue === 0) return 0; // If max is 0, operand must be 0
36
+
37
+ if (Math.random() < CHANCE_OF_BEING_ZERO) {
38
+ return 0;
39
+ } else {
40
+ // Generate a number from 1 to maxValue
41
+ return getRandomNumber(1, maxValue);
 
 
 
 
 
42
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  };
44
 
45
+ // Get a random emoji
46
+ const getRandomEmoji = () => {
47
+ return emojis[Math.floor(Math.random() * emojis.length)];
48
+ };
49
 
50
+ // Generate a new question
51
+ const generateQuestion = () => {
52
+ let num1, num2;
53
+ const MAX_OPERAND_VALUE = 5;
54
+ const MAX_SUM = 5;
 
 
 
 
 
 
 
55
 
56
+ do {
57
+ num1 = getOperandWithReducedZero(MAX_OPERAND_VALUE);
58
+ num2 = getOperandWithReducedZero(MAX_OPERAND_VALUE);
59
+ } while (num1 + num2 > MAX_SUM);
60
+
61
+ const answer = num1 + num2;
62
+
63
+ // Generate options, one of which is the correct answer
64
+ const options = new Set<number>();
65
+ options.add(answer);
66
+ while (options.size < 3) {
67
+ const option = getRandomNumber(0, 10); // Options can be up to 10
68
+ if (option !== answer) { // Ensure options are not trivially easy if sum is 0 or 1
69
+ options.add(option);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  }
 
 
 
 
 
 
 
71
  }
 
72
 
73
+ const object1 = getRandomEmoji();
74
+ let object2 = getRandomEmoji();
75
+ // Ensure objects are different if numbers are different, or if it's the same number, it's fine.
76
+ // This logic primarily ensures visual distinction when counts are different.
77
+ if (num1 > 0 && num2 > 0 && num1 !== num2) { // only ensure different emojis if counts are different and non-zero
78
+ while (object2 === object1) {
79
+ object2 = getRandomEmoji();
80
+ }
81
+ } else if (num1 > 0 && num2 > 0 && num1 === num2) { // if numbers are same and non-zero, make sure emojis are same for clarity
82
+ object2 = object1;
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  }
84
+
85
+
86
+ setCurrentQuestion({
87
+ num1,
88
+ num2,
89
+ answer,
90
+ options: Array.from(options).sort(() => Math.random() - 0.5), // Shuffle options
91
+ object1,
92
+ object2,
93
+ });
94
+ setFeedback('');
95
+ };
96
+
97
+ useEffect(() => {
98
+ generateQuestion();
99
+ }, []);
100
+
101
+ // Handle answer submission
102
+ const handleAnswer = (selectedOption: number) => {
103
+ if (currentQuestion && selectedOption === currentQuestion.answer) {
104
+ setFeedback('Correct! 🎉');
105
+ setScore(score + 1);
106
  setTimeout(() => {
107
+ generateQuestion();
108
+ }, 1500);
109
+ } else if (currentQuestion) { // Added currentQuestion check here
 
 
 
110
  setFeedback('Try again! 🤔');
 
111
  setTimeout(() => {
 
112
  setFeedback('');
113
  }, 1000);
114
  }
115
  };
116
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  if (!currentQuestion) {
118
+ return <div className="loading">Loading game...</div>;
119
  }
120
 
121
+ const { num1, num2, answer, options, object1, object2 } = currentQuestion;
122
+ // const sumObject = object1; // No longer needed as sum is not displayed with objects here
123
+
124
  return (
125
+ <div className="app-container">
126
+ <header className="game-header">
127
+ <h1>Addition Game</h1>
128
+ <div className="display-mode-selector">
129
+ <button onClick={() => setDisplayMode('numbers')} className={displayMode === 'numbers' ? 'active' : ''}>Number</button>
130
+ <button onClick={() => setDisplayMode('objects')} className={displayMode === 'objects' ? 'active' : ''}>Object</button>
131
+ <button onClick={() => setDisplayMode('both')} className={displayMode === 'both' ? 'active' : ''}>Both</button>
132
+ </div>
133
+ <div className="score-display">Score: {score}</div>
134
+ </header>
135
+
136
+ <main className="game-area">
137
+ <div className="question-container-new">
138
+ {/* Operand 1 Column */}
139
+ <div className="operand-column">
140
+ {(displayMode === 'numbers' || displayMode === 'both') && (
141
+ <div className="number-box">
142
+ <span className="number-text">{num1}</span>
143
+ </div>
144
+ )}
145
+ {(displayMode === 'objects' || displayMode === 'both') && (
146
+ <div className="objects-display">
147
+ {Array(num1).fill(null).map((_, i) => (
148
+ <span key={`obj1-${i}`} className="item-object">{object1}</span>
149
+ ))}
150
+ </div>
151
+ )}
152
+ {/* If only objects mode and num1 is 0, show nothing or a placeholder if desired*/}
153
+ {displayMode === 'objects' && num1 === 0 && <div className="objects-display" style={{minHeight: '4rem'}}></div>}
154
  </div>
155
+
156
+ {/* Operator + Column */}
157
+ <div className="operator-cell">
158
+ <span className="operator-symbol">+</span>
159
+ </div>
160
+
161
+ {/* Operand 2 Column */}
162
+ <div className="operand-column">
163
+ {(displayMode === 'numbers' || displayMode === 'both') && (
164
+ <div className="number-box">
165
+ <span className="number-text">{num2}</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
  </div>
167
+ )}
168
+ {(displayMode === 'objects' || displayMode === 'both') && (
169
+ <div className="objects-display">
170
+ {Array(num2).fill(null).map((_, i) => (
171
+ <span key={`obj2-${i}`} className="item-object">{object2}</span>
172
+ ))}
173
  </div>
174
+ )}
175
+ {displayMode === 'objects' && num2 === 0 && <div className="objects-display" style={{minHeight: '4rem'}}></div>}
176
+ </div>
177
+
178
+ {/* Operator = Column */}
179
+ <div className="operator-cell">
180
+ <span className="operator-symbol">=</span>
181
+ </div>
182
+
183
+ {/* Result Column - Now displays a question mark */}
184
+ <div className="result-column">
185
+ <span className="answer-placeholder-new">?</span>
186
+ </div>
187
+
 
188
  </div>
189
+
190
+ <div className="options-container">
191
+ {options.map((option) => (
192
+ <button key={option} onClick={() => handleAnswer(option)} className="option-button">
193
+ {option}
194
+ </button>
195
+ ))}
196
+ </div>
197
+
198
+ {feedback && <div className="feedback-message">{feedback}</div>}
199
+ </main>
200
  </div>
201
  );
202
  }