Skip to content

Commit 39f409d

Browse files
committed
Successful - Implemented page that connect to Binary and Addition game in emulator and real hardware
1 parent e4d3516 commit 39f409d

27 files changed

Lines changed: 993 additions & 122 deletions

File tree

addition_game/addition_game.c

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ void initAdditionGame(void) {
4848
overflowOccur += 1;
4949
printf("Question at round %d will cause overflow.\n", currentRound);
5050
}
51-
51+
5252
// Make all LED off first in `led_array`
5353
fill_color(offColor);
5454

@@ -57,7 +57,7 @@ void initAdditionGame(void) {
5757

5858
// The game will keep running until user get the answer correct, unless
5959
// they wish to stop the game
60-
while (!stopPlaying && currentPage == ADDITION_GAME) {
60+
while (!stopPlaying) {
6161
// Activate keyboard I, J, K, L press input
6262
checkMoveButton();
6363

@@ -103,7 +103,6 @@ void initAdditionGame(void) {
103103
// Stop playing and go back to the previous page, namely
104104
// `PAINTING_SPACE`
105105
currentPage = prevPageState;
106-
currentAddGame = ADDITION_GAME_IDLE;
107106
stopPlaying = true;
108107
}
109108
}
@@ -152,8 +151,13 @@ void initAdditionGame(void) {
152151
currentRound += 1;
153152
currentAddGame = ADDITION_GAME_IDLE;
154153

154+
// TODO NEXT: CHECK IF THE HARDWARE CODE WORKS
155+
// ENSURE TO INTEGRATE BOTH BINARYGAME AND ADDITION GAME TOGETHER
156+
157+
// Check if next round questions from Round 1 to 4 will cause overflow or not
158+
// Round 0 has been handled in the beginning
155159
if(currentRound < 5){
156-
// Check if next round questions will cause overflow or not
160+
157161
if(numberA + numberB > 15){
158162
overflowOccur += 1;
159163
printf("Question at round %d will cause overflow.\n", currentRound);
@@ -184,8 +188,10 @@ void initAdditionGame(void) {
184188
roundEntered[i] = 0;
185189
}
186190

187-
// Reset the game state (2nd time)
191+
// Reset the game state
188192
currentAddGame = ADDITION_GAME_IDLE;
193+
// Reset the overflow counter
194+
overflowOccur = 0;
189195

190196
// As soon as the function stop, render back the real saved canvas
191197
for (int i = 0; i < NUM_LEDS; i++) {
@@ -208,6 +214,10 @@ void initAdditionGame(void) {
208214
* @param questionB The 4-bits binary question 2
209215
**/
210216
static inline void handleScenario(uint8_t row, uint8_t idx, uint8_t questionA, uint8_t questionB) {
217+
#ifdef DEBUG_VERBOSE
218+
printf("handleScenario called with row=%d idx=%d\n", row, idx);
219+
#endif
220+
211221
// Handle User Input by changing to selected
212222
// Only works for user input
213223
if (row == 3 && idx >= 1 && idx <= 5) {
@@ -308,19 +318,19 @@ static inline void renderQuestion(uint8_t questionA, uint8_t questionB) {
308318
// Decorative overlay spots, per row
309319
static const uint8_t row7Spots[] = {1, 2, 3, 4, 5, 6};
310320
for (int i = 0; i < 6; i++) {
311-
setColorLEDScaled(7 * 8 + row7Spots[i], greyColor, brightnessDivisor);
321+
setColorLEDScaled(7 * 8 + row7Spots[i], magentaColor, brightnessDivisor);
312322
}
313323

314-
setColorLEDScaled(6 * 8 + 6, greyColor, brightnessDivisor);
315-
setColorLEDScaled(6 * 8 + 1, greyColor, brightnessDivisor);
324+
setColorLEDScaled(6 * 8 + 6, magentaColor, brightnessDivisor);
325+
setColorLEDScaled(6 * 8 + 1, magentaColor, brightnessDivisor);
316326

317-
setColorLEDScaled(5 * 8 + 6, greyColor, brightnessDivisor);
327+
setColorLEDScaled(5 * 8 + 6, magentaColor, brightnessDivisor);
318328
setColorLEDScaled(5 * 8 + 1, onColorBlue, brightnessDivisor);
319329

320-
setColorLEDScaled(4 * 8 + 6, greyColor, brightnessDivisor);
321-
setColorLEDScaled(4 * 8 + 5, greyColor, brightnessDivisor);
322-
setColorLEDScaled(4 * 8 + 4, greyColor, brightnessDivisor);
323-
setColorLEDScaled(4 * 8 + 3, greyColor, brightnessDivisor);
330+
setColorLEDScaled(4 * 8 + 6, magentaColor, brightnessDivisor);
331+
setColorLEDScaled(4 * 8 + 5, magentaColor, brightnessDivisor);
332+
setColorLEDScaled(4 * 8 + 4, magentaColor, brightnessDivisor);
333+
setColorLEDScaled(4 * 8 + 3, magentaColor, brightnessDivisor);
324334

325335
for (int col = 0; col <= 2; col++) {
326336
setColorLEDScaled(4 * 8 + col, onColorBlue, brightnessDivisor);

binary_game/binary_game.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ void initBinaryGame(void) {
4040

4141
// The game will keep running until user get the answer correct, unless
4242
// they wish to stop the game
43-
while (!stopPlaying && currentPage == BINARY_GAME) {
43+
while (!stopPlaying) {
4444

4545
// Activate keyboard I, J, K, L press input
4646
checkMoveButton();
@@ -91,7 +91,7 @@ void initBinaryGame(void) {
9191
}
9292

9393
// Only works after user move the pointer one by one
94-
if ((currentGame == BINARY_GAME_IDLE) && buttonPressed == 1) {
94+
if ((currentGame == BINARY_GAME_IDLE) && (!stopPlaying) && buttonPressed == 1) {
9595
// Render normally
9696
renderBinaryGame(randomNumber);
9797
// printf("currentGame is %d \n", currentGame);

binary_game/multiple_round.c

Lines changed: 133 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1-
#include "multiple_round.h"
1+
#include "./multiple_round.h"
2+
3+
// Function prototype declaration
4+
static inline void renderChooseGameMode(void);
25

36
enum RoundStatus roundStatus[5] = {
47
ROUND_IDLE, ROUND_IDLE, ROUND_IDLE, ROUND_IDLE, ROUND_IDLE};
58

69
int8_t roundEntered[5] = {0};
710

11+
12+
enum GameplayMode playGameMode = CHOOSE_GAME;
13+
14+
// Store the overflow state logo
815
const uint8_t overflowLogo[6][5] = {
916
[0] = {0b10000111, 0b10011101, 0b11011101, 0b10100101, 0b11000111},
1017
[1] = {0b10000010, 0b10011110, 0b11011010, 0b10100010, 0b11000111},
@@ -13,6 +20,129 @@ const uint8_t overflowLogo[6][5] = {
1320
[4] = {0b10000011, 0b10011101, 0b11011111, 0b10100001, 0b11000001},
1421
[5] = {0b10000111, 0b10011100, 0b11011111, 0b10100001, 0b11000110}};
1522

23+
// Store the gameplay screen here
24+
static const char* screenPattern[8] = {
25+
"12120330",
26+
"21213333",
27+
"12123333",
28+
"21210330",
29+
"00000000",
30+
"02200330",
31+
"22223333",
32+
"00000000"
33+
};
34+
35+
uint16_t chooseGamemodeScreen[7] = {0};
36+
37+
void chooseGameMode(void) {
38+
// Will stay in this mode until user presses confirm button to choose the game mode
39+
bool chooseMode = false;
40+
// Reset the buttonPressed variable to be 0 first
41+
buttonPressed = 0;
42+
// Check if the enter has been pressed or not
43+
ChooseEnterPressed enterPressed = CHOOSE_GAME_NOT_ENTERED;
44+
45+
// Print the emulator screen for the first time for this function
46+
renderChooseGameMode();
47+
48+
while(!chooseMode){
49+
// Activate keyboard I, J, K, L press input
50+
checkMoveButton();
51+
52+
// Navigate pointers
53+
if (BTN_JUST_PRESSED(BTN_UP)) {
54+
currentposition = (NUM_LEDS + currentposition + 8) % NUM_LEDS;
55+
buttonPressed = 1;
56+
}
57+
if (BTN_JUST_PRESSED(BTN_DOWN)) {
58+
currentposition = (NUM_LEDS + currentposition - 8) % NUM_LEDS;
59+
buttonPressed = 1;
60+
}
61+
if (BTN_JUST_PRESSED(BTN_LEFT)) {
62+
currentposition = (NUM_LEDS + currentposition + 1) % NUM_LEDS;
63+
buttonPressed = 1;
64+
}
65+
if (BTN_JUST_PRESSED(BTN_RIGHT)) {
66+
currentposition = (NUM_LEDS + currentposition - 1) % NUM_LEDS;
67+
buttonPressed = 1;
68+
}
69+
if (BTN_JUST_PRESSED(Enter_Key)) {
70+
enterPressed = CHOOSE_GAME_ENTERED;
71+
}
72+
73+
// Compute which row and col your pointer is in now
74+
uint8_t row = currentposition / GRID_COLS;
75+
uint8_t col = currentposition % GRID_COLS;
76+
uint8_t ledIndex = row * VERTICAL_BUTTONS + col;
77+
78+
// Update to compare button released and pressed state
79+
updateMoveButton();
80+
81+
if(buttonPressed == 1){
82+
renderChooseGameMode();
83+
// Reset state
84+
buttonPressed = 0;
85+
}
86+
87+
if(enterPressed == CHOOSE_GAME_ENTERED){
88+
// If user has pressed the confirm button, then choose the game mode
89+
if((ledIndex >= 8 && ledIndex <= 11) || ledIndex == 17 || ledIndex == 18){
90+
playGameMode = ADDITION_GAME;
91+
chooseMode = true;
92+
}
93+
else if((ledIndex >= 12 && ledIndex <= 15) || ledIndex == 21 || ledIndex == 22){
94+
playGameMode = BINARY_GAME;
95+
chooseMode = true;
96+
}
97+
98+
// Reset back
99+
enterPressed = CHOOSE_GAME_NOT_ENTERED;
100+
}
101+
102+
}
103+
104+
//Reset values
105+
buttonPressed = 0;
106+
enterPressed = CHOOSE_GAME_NOT_ENTERED;
107+
}
108+
109+
static inline void renderChooseGameMode(void) {
110+
// Clear the screen first
111+
fill_color(offColor);
112+
// Render the game mode selection screen
113+
for (uint8_t arrayRow = 0; arrayRow <= 7; arrayRow++) {
114+
int8_t ledRow = 7 - arrayRow; // top (7) down to row 3
115+
for (uint8_t arrayCol = 0; arrayCol < 8; arrayCol++) {
116+
int ledCol = 7 - arrayCol;
117+
int idx = ledRow * 8 + ledCol;
118+
// '0'-'3' as ASCII characters need to be converted to actual
119+
// numbers 0-3. Subtracting the character '0' does this:
120+
// e.g. '2' - '0' = 50 - 48 = 2
121+
uint8_t state = screenPattern[arrayRow][arrayCol] - '0';
122+
switch(state){
123+
case 0:
124+
setColorLEDScaled(idx, offColor, brightnessDivisor);
125+
break;
126+
case 1:
127+
setColorLEDScaled(idx, onColorBlue, brightnessDivisor);
128+
break;
129+
case 2:
130+
setColorLEDScaled(idx, cyanColor, brightnessDivisor);
131+
break;
132+
case 3:
133+
setColorLEDScaled(idx, solidColorRed, brightnessDivisor);
134+
break;
135+
}
136+
}
137+
}
138+
139+
// Draw pointer ON TOP visually (only effect led_array), doesn't touch
140+
set_color(currentposition, pointerColor);
141+
142+
// Print the emulator screen
143+
WS2812BSimpleSend(LED_PINS, (uint8_t *)led_array, NUM_LEDS * 3);
144+
}
145+
16146
void renderGameRounds(void) {
17147
for (int8_t col = 4; col >= 0; col--) {
18148
// flip to match physical LED ordering
@@ -56,7 +186,7 @@ void handleGameRounds(bool answerCorrect, uint8_t roundIndex) {
56186
currentGame = BINARY_GAME_CONTINUE;
57187
}
58188
else if (currentPage == ADDITION_GAME) {
59-
currentGame = ADDITION_GAME_CONTINUE;
189+
currentAddGame = ADDITION_GAME_CONTINUE;
60190
}
61191
setColorLEDScaled(roundIndex, orangeColor, brightnessDivisor);
62192
printf("I got correct answer the 1st time in round %d.\n", roundIndex);
@@ -84,7 +214,7 @@ void handleGameRounds(bool answerCorrect, uint8_t roundIndex) {
84214
currentGame = BINARY_GAME_CONTINUE;
85215
}
86216
else if (currentPage == ADDITION_GAME) {
87-
currentGame = ADDITION_GAME_CONTINUE;
217+
currentAddGame = ADDITION_GAME_CONTINUE;
88218
}
89219
break;
90220
case false:

binary_game/multiple_round.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,23 @@ extern const uint8_t overflowLogo[6][5];
2525
// roundStatus anymore
2626
extern int8_t roundEntered[5];
2727

28+
// Status for what game is being played
29+
enum GameplayMode {
30+
CHOOSE_GAME, // 0
31+
BINARY_GAME, // 1
32+
ADDITION_GAME // 2
33+
};
34+
35+
// Store the gameplay mode
36+
extern enum GameplayMode playGameMode;
37+
38+
typedef uint8_t ChooseEnterPressed;
39+
#define CHOOSE_GAME_NOT_ENTERED 0
40+
#define CHOOSE_GAME_ENTERED 1
41+
42+
/// @brief Let user choose which game he wants to play. Either `Binary Game` or `Addition Game`.
43+
void chooseGameMode(void);
44+
2845
/**
2946
* @brief Call this everytime emulator screen is printed. This print the user input
3047
* , confirm button and quit button

data/colors.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const color_t lightOrangeColor = {255, 230, 190};
1212
const color_t greyColor = {235, 235, 235};
1313
const color_t pointerColor = {255, 188, 100}; // Orange
1414
const color_t magentaColor = {255, 15, 245}; // Magenta
15+
const color_t cyanColor = {15, 255, 245}; // Cyan
1516
const color_t solidColorRed = {255, 0, 0}; // Solid Red
1617
const color_t lightColorRed = {255, 200, 200}; // Light Red
1718
const color_t whiteColor = {255, 255, 255};

data/colors.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ extern const color_t greyColor;
3535
extern const color_t pointerColor;
3636
extern const color_t magentaColor;
3737
extern const color_t whiteColor;
38+
extern const color_t cyanColor;
3839
extern const color_t solidColorRed;
3940
extern const color_t lightColorRed;
4041

emulator/adriel_2026_work/emulator_driver/emulator_driver.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ typedef enum {
2121
CODING_LOAD_SLOT,
2222
CODING_LOAD_CONFIRM,
2323
BRIGHTNESS_CONTROL,
24-
BINARY_GAME, // Page is only for binary number learning
25-
ADDITION_GAME // Page is only for binary addition learning
24+
CHOOSE_GAME_CONTROL
2625
} PageState;
2726

2827
extern PageState currentPage;

emulator/adriel_2026_work/extra_function.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,15 @@ void handleButtonFunction(void) {
8282
printf("Now page state is %d\n", currentPage);
8383
}
8484
if (BTN_JUST_PRESSED(BTN_5)) {
85-
printf("You selected 'BINARY GAME'.\n");
85+
printf("You selected 'CHOOSE GAME PLAY'.\n");
8686
// Remember previous page: PAINTING_SPACE
8787
prevPageState = currentPage;
8888
// TO DO: Add function to render and handle user choosing which game to play
89-
currentPage = ADDITION_GAME;
89+
currentPage = CHOOSE_GAME_CONTROL;
9090
// Will print the page ID: 14
9191
printf("Now page state is %d\n", currentPage);
92+
// Let user choose which game to play, either binary game or addition game
93+
chooseGameMode();
9294
}
9395
if (BTN_JUST_PRESSED(BTN_6)) {
9496
printf("You selected 'COLOR FOR BACKGROUND'.\n");
@@ -212,12 +214,13 @@ void handleButtonFunction(void) {
212214
renderBrightnessSelectScreen();
213215
}
214216

215-
if(currentPage == BINARY_GAME){
217+
if(currentPage == CHOOSE_GAME_CONTROL && playGameMode == BINARY_GAME){
218+
printf("User has chosen `BINARY_GAME`. \n");
216219
initBinaryGame();
217220
}
218221

219-
if(currentPage == ADDITION_GAME){
220-
// initBinaryGame();
222+
if(currentPage == CHOOSE_GAME_CONTROL && playGameMode == ADDITION_GAME){
223+
printf("User has chosen `ADDITION_GAME`. \n");
221224
initAdditionGame();
222225
}
223226

real_hardware/Makefile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ C_SOURCES := ./User/main.c \
3333
./User/data/colors.c \
3434
./User/data/buttons.c \
3535
./User/data/music.c \
36-
./User/hardware_binary_game/multiple_round.c
36+
./User/hardware_binary_game/multiple_round.c \
37+
./User/hardware_binary_game/addition_game.c
3738

3839
# List of assembly source files
3940
ASM_SOURCES := ./Startup/startup_ch32v00x.S
@@ -69,8 +70,8 @@ ARCH_FLAGS := -march=rv32ec_zicsr_zifencei -mabi=ilp32e
6970
# -MP adds dummy rules to make header dependency handling safer.
7071
CFLAGS := $(COMMON_FLAGS) $(ARCH_FLAGS) $(INCLUDES) -std=gnu11 -MMD -MP
7172

72-
# add this only when you want debug prints:
73-
# CFLAGS += -DEBUG_VERBOSE
73+
# KEEP the critical SDK flag so the hardware libraries don't break
74+
# CFLAGS += -DDEBUG_VERBOSE
7475

7576
# Flags for compiling assembly files.
7677
# "-x assembler-with-cpp": tells GCC to preprocess the assembly source first, \

real_hardware/User/data/colors.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@ const color_t blueColor = {33, 33, 255};
2020
const color_t redColor = {0, 255, 0};
2121
const color_t greenColor = {255, 0, 0};
2222
const color_t yellowColor = {255, 221, 31};
23-
const color_t orangeColor = {255, 150, 15};
23+
const color_t greyColor = {235, 235, 235};
24+
const color_t orangeColor = {152, 255, 16};
2425
const color_t lightOrangeColor = {255, 230, 190};
25-
const color_t purpleColor = {165, 100, 255};
26-
const color_t magentaColor = {255, 15, 245};
27-
const color_t whiteColor = {255, 255, 255};
26+
const color_t purpleColor = {30, 125, 255};
27+
const color_t magentaColor = {15, 255, 245};
28+
const color_t cyanColor = {255, 0, 255};
2829
const color_t offColor = {0, 0, 0};
2930

3031
// clang-format on

0 commit comments

Comments
 (0)