1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-12 20:49:49 +04:00

not use global vars anymore & other fixes

in tictactoe game / snake / arkanoid
This commit is contained in:
MX
2022-08-07 10:52:03 +03:00
parent 044338b8f2
commit baf0214ed1
4 changed files with 173 additions and 139 deletions

View File

@@ -5,6 +5,6 @@ App(
entry_point="arkanoid_game_app", entry_point="arkanoid_game_app",
cdefines=["APP_ARKANOID_GAME"], cdefines=["APP_ARKANOID_GAME"],
requires=["gui"], requires=["gui"],
stack_size=3 * 1024, stack_size=4 * 1024,
order=30, order=30,
) )

View File

@@ -154,7 +154,7 @@ void move_ball(Canvas* canvas, ArkanoidState* st) {
st->score += st->level; st->score += st->level;
// Blink led when we hit some brick // Blink led when we hit some brick
notification_message(st->notify, &sequence_short_sound); notification_message(st->notify, &sequence_short_sound);
notification_message(st->notify, &sequence_blink_white_100); //notification_message(st->notify, &sequence_blink_white_100);
st->brickCount++; st->brickCount++;
st->brick_state.isHit[row][column] = true; st->brick_state.isHit[row][column] = true;

View File

@@ -283,7 +283,7 @@ static void snake_game_process_game_step(SnakeState* const snake_state, Notifica
bool eatFruit = (next_step.x == snake_state->fruit.x) && (next_step.y == snake_state->fruit.y); bool eatFruit = (next_step.x == snake_state->fruit.x) && (next_step.y == snake_state->fruit.y);
if(eatFruit) { if(eatFruit) {
notification_message(notify, &sequence_short_vibro_and_sound); notification_message(notify, &sequence_short_vibro_and_sound);
notification_message(notify, &sequence_blink_white_100); //notification_message(notify, &sequence_blink_white_100);
snake_state->len++; snake_state->len++;
if(snake_state->len >= MAX_SNAKE_LEN) { if(snake_state->len >= MAX_SNAKE_LEN) {

View File

@@ -6,33 +6,28 @@
#define TAG "TicTacToe" #define TAG "TicTacToe"
typedef enum { EventTypeTick, EventTypeKey } EventType;
typedef struct {
FuriTimer* timer;
uint8_t selBoxX; uint8_t selBoxX;
uint8_t selBoxY; uint8_t selBoxY;
uint8_t selX = 2; uint8_t selX;
uint8_t selY = 2; uint8_t selY;
uint16_t scoreX; uint16_t scoreX;
uint16_t scoreO; uint16_t scoreO;
char player = 'X'; char player;
char field[3][3]; char field[3][3];
bool fieldx[3][3]; bool fieldx[3][3];
const uint8_t coords[3] = {6, 27, 48}; uint8_t coords[3];
bool button_state = false; bool button_state;
typedef enum { EventTypeTick, EventTypeKey } EventType;
typedef enum { DirectionUp, DirectionRight, DirectionDown, DirectionLeft } Direction;
typedef enum { GameStatePlaying, GameStateGameOver } GameState;
typedef struct {
GameState game_state;
FuriTimer* timer;
} TicTacToeState; } TicTacToeState;
typedef struct { typedef struct {
@@ -49,15 +44,15 @@ void drawCircle(Canvas* const canvas, uint8_t x, uint8_t y) {
canvas_draw_circle(canvas, x + 4, y + 5, 5); canvas_draw_circle(canvas, x + 4, y + 5, 5);
} }
void player_switch() { void player_switch(TicTacToeState* ts) {
if(player == 'O') { if(ts->player == 'O') {
player = 'X'; ts->player = 'X';
} else if(player == 'X') { } else if(ts->player == 'X') {
player = 'O'; ts->player = 'O';
} }
} }
void tictactoe_draw(Canvas* canvas) { void tictactoe_draw(Canvas* canvas, TicTacToeState* ts) {
// Draws the game field // Draws the game field
canvas_draw_frame(canvas, 0, 0, 64, 64); // frame canvas_draw_frame(canvas, 0, 0, 64, 64); // frame
canvas_draw_line(canvas, 0, 21, 63, 21); // horizontal line canvas_draw_line(canvas, 0, 21, 63, 21); // horizontal line
@@ -68,34 +63,34 @@ void tictactoe_draw(Canvas* canvas) {
// Draws the game field elements (X or O) // Draws the game field elements (X or O)
for(uint8_t i = 0; i <= 2; i++) { for(uint8_t i = 0; i <= 2; i++) {
for(uint8_t j = 0; j <= 2; j++) { for(uint8_t j = 0; j <= 2; j++) {
if(field[i][j] == 'O') { if(ts->field[i][j] == 'O') {
drawCircle(canvas, coords[i], coords[j]); drawCircle(canvas, ts->coords[i], ts->coords[j]);
} else if(field[i][j] == 'X') { } else if(ts->field[i][j] == 'X') {
drawCross(canvas, coords[i], coords[j]); drawCross(canvas, ts->coords[i], ts->coords[j]);
} }
} }
} }
// Draws the selection box // Draws the selection box
if(selX == 1) { if(ts->selX == 1) {
selBoxX = 1; ts->selBoxX = 1;
} else if(selX == 2) { } else if(ts->selX == 2) {
selBoxX = 22; ts->selBoxX = 22;
} else if(selX == 3) { } else if(ts->selX == 3) {
selBoxX = 43; ts->selBoxX = 43;
} }
if(selY == 1) { if(ts->selY == 1) {
selBoxY = 1; ts->selBoxY = 1;
} else if(selY == 2) { } else if(ts->selY == 2) {
selBoxY = 22; ts->selBoxY = 22;
} else if(selY == 3) { } else if(ts->selY == 3) {
selBoxY = 43; ts->selBoxY = 43;
} }
canvas_set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
canvas_draw_frame(canvas, selBoxX, selBoxY, 20, 20); canvas_draw_frame(canvas, ts->selBoxX, ts->selBoxY, 20, 20);
canvas_draw_frame(canvas, selBoxX + 1, selBoxY + 1, 18, 18); canvas_draw_frame(canvas, ts->selBoxX + 1, ts->selBoxY + 1, 18, 18);
// Draws the sidebar // Draws the sidebar
canvas_set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
@@ -103,105 +98,112 @@ void tictactoe_draw(Canvas* canvas) {
canvas_draw_str(canvas, 75, 24, "X:"); canvas_draw_str(canvas, 75, 24, "X:");
char scoreXBuffer[10]; char scoreXBuffer[10];
snprintf(scoreXBuffer, sizeof(scoreXBuffer), "%d", scoreX); snprintf(scoreXBuffer, sizeof(scoreXBuffer), "%d", ts->scoreX);
canvas_draw_str(canvas, 88, 24, scoreXBuffer); canvas_draw_str(canvas, 88, 24, scoreXBuffer);
canvas_draw_str(canvas, 75, 35, "O:"); canvas_draw_str(canvas, 75, 35, "O:");
char scoreOBuffer[10]; char scoreOBuffer[10];
snprintf(scoreOBuffer, sizeof(scoreOBuffer), "%d", scoreO); snprintf(scoreOBuffer, sizeof(scoreOBuffer), "%d", ts->scoreO);
canvas_draw_str(canvas, 88, 35, scoreOBuffer); canvas_draw_str(canvas, 88, 35, scoreOBuffer);
canvas_set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
canvas_draw_str(canvas, 75, 46, "Player:"); canvas_draw_str(canvas, 75, 46, "Player:");
if(player == 'X') { if(ts->player == 'X') {
drawCross(canvas, 93, 50); drawCross(canvas, 93, 50);
} else if(player == 'O') { } else if(ts->player == 'O') {
drawCircle(canvas, 93, 50); drawCircle(canvas, 93, 50);
} }
} }
void clear_game_field() { void clear_game_field(TicTacToeState* ts) {
// Clears the game field arrays // Clears the game field arrays
for(uint8_t i = 0; i <= 2; i++) { for(uint8_t i = 0; i <= 2; i++) {
for(uint8_t j = 0; j <= 2; j++) { for(uint8_t j = 0; j <= 2; j++) {
field[i][j] = ' '; ts->field[i][j] = ' ';
fieldx[i][j] = false; ts->fieldx[i][j] = false;
} }
} }
selX = 2; // Centers the selection box on X axis ts->selX = 2; // Centers the selection box on X axis
selY = 2; // Centers the selection box on Y axis ts->selY = 2; // Centers the selection box on Y axis
} }
void reset_game_data() { void reset_game_data(TicTacToeState* ts) {
scoreO = 0; ts->scoreO = 0;
scoreX = 0; ts->scoreX = 0;
player = 'X'; ts->player = 'X';
} }
void draw_win(Canvas* canvas, char player) { void draw_win(Canvas* canvas, char player, TicTacToeState* ts) {
// Handles the score table // Handles the score table
if(player == 'X') { if(player == 'X') {
scoreX++; ts->scoreX++;
} else if(player == 'O') { } else if(player == 'O') {
scoreO++; ts->scoreO++;
} }
// Switches the players // Switches the players
player_switch(); player_switch(ts);
// Draws the board with players switched // Draws the board with players switched
tictactoe_draw(canvas); tictactoe_draw(canvas, ts);
// Clear the game field // Clear the game field
clear_game_field(); clear_game_field(ts);
// Draw the new board // Draw the new board
tictactoe_draw(canvas); tictactoe_draw(canvas, ts);
} }
static void tictactoe_state_init(TicTacToeState* const tictactoe_state) { static void tictactoe_state_init(TicTacToeState* tictactoe_state) {
// Set the initial game state // Set the initial game state
tictactoe_state->game_state = GameStatePlaying; tictactoe_state->selX = 2;
tictactoe_state->selY = 2;
tictactoe_state->player = 'X';
tictactoe_state->coords[0] = 6;
tictactoe_state->coords[1] = 27;
tictactoe_state->coords[2] = 48;
tictactoe_state->button_state = false;
clear_game_field(); clear_game_field(tictactoe_state);
reset_game_data(); reset_game_data(tictactoe_state);
} }
static void tictactoe_draw_callback(Canvas* const canvas, void* ctx) { static void tictactoe_draw_callback(Canvas* const canvas, void* ctx) {
const TicTacToeState* tictactoe_state = acquire_mutex((ValueMutex*)ctx, 25); TicTacToeState* ticst = acquire_mutex((ValueMutex*)ctx, 25);
if(tictactoe_state == NULL) { if(ticst == NULL) {
return; return;
} }
if(selX > 3) { if(ticst->selX > 3) {
selX = 3; ticst->selX = 3;
} else if(selX < 1) { } else if(ticst->selX < 1) {
selX = 1; ticst->selX = 1;
} }
if(selY > 3) { if(ticst->selY > 3) {
selY = 3; ticst->selY = 3;
} else if(selY < 1) { } else if(ticst->selY < 1) {
selY = 1; ticst->selY = 1;
} }
// Assigns the game field elements their value (X or O) when the OK button is pressed // Assigns the game field elements their value (X or O) when the OK button is pressed
if(button_state) { if(ticst->button_state) {
button_state = false; ticst->button_state = false;
for(uint8_t i = 0; i <= 2; i++) { for(uint8_t i = 0; i <= 2; i++) {
for(uint8_t j = 0; j <= 2; j++) { for(uint8_t j = 0; j <= 2; j++) {
if((selX == i + 1) && (selY == j + 1) && (fieldx[i][j] == false)) { if((ticst->selX == i + 1) && (ticst->selY == j + 1) &&
if(player == 'X') { (ticst->fieldx[i][j] == false)) {
field[i][j] = 'X'; if(ticst->player == 'X') {
fieldx[i][j] = true; ticst->field[i][j] = 'X';
player_switch(); ticst->fieldx[i][j] = true;
} else if(player == 'O') { player_switch(ticst);
field[i][j] = 'O'; } else if(ticst->player == 'O') {
fieldx[i][j] = true; ticst->field[i][j] = 'O';
player_switch(); ticst->fieldx[i][j] = true;
player_switch(ticst);
} }
} }
} }
@@ -209,48 +211,80 @@ static void tictactoe_draw_callback(Canvas* const canvas, void* ctx) {
} }
// Checks the game field for winning combinations // Checks the game field for winning combinations
if((field[0][0] == 'X') && (field[1][0] == 'X') && (field[2][0] == 'X')) { if((ticst->field[0][0] == 'X') && (ticst->field[1][0] == 'X') && (ticst->field[2][0] == 'X')) {
draw_win(canvas, 'X'); draw_win(canvas, 'X', ticst);
} else if((field[0][1] == 'X') && (field[1][1] == 'X') && (field[2][1] == 'X')) {
draw_win(canvas, 'X');
} else if((field[0][2] == 'X') && (field[1][2] == 'X') && (field[2][2] == 'X')) {
draw_win(canvas, 'X');
} else if((field[0][0] == 'X') && (field[0][1] == 'X') && (field[0][2] == 'X')) {
draw_win(canvas, 'X');
} else if((field[1][0] == 'X') && (field[1][1] == 'X') && (field[1][2] == 'X')) {
draw_win(canvas, 'X');
} else if((field[2][0] == 'X') && (field[2][1] == 'X') && (field[2][2] == 'X')) {
draw_win(canvas, 'X');
} else if((field[0][0] == 'X') && (field[1][1] == 'X') && (field[2][2] == 'X')) {
draw_win(canvas, 'X');
} else if((field[2][0] == 'X') && (field[1][1] == 'X') && (field[0][2] == 'X')) {
draw_win(canvas, 'X');
} else if((field[0][0] == 'O') && (field[1][0] == 'O') && (field[2][0] == 'O')) {
draw_win(canvas, 'O');
} else if((field[0][1] == 'O') && (field[1][1] == 'O') && (field[2][1] == 'O')) {
draw_win(canvas, 'O');
} else if((field[0][2] == 'O') && (field[1][2] == 'O') && (field[2][2] == 'O')) {
draw_win(canvas, 'O');
} else if((field[0][0] == 'O') && (field[0][1] == 'O') && (field[0][2] == 'O')) {
draw_win(canvas, 'O');
} else if((field[1][0] == 'O') && (field[1][1] == 'O') && (field[1][2] == 'O')) {
draw_win(canvas, 'O');
} else if((field[2][0] == 'O') && (field[2][1] == 'O') && (field[2][2] == 'O')) {
draw_win(canvas, 'O');
} else if((field[0][0] == 'O') && (field[1][1] == 'O') && (field[2][2] == 'O')) {
draw_win(canvas, 'O');
} else if((field[2][0] == 'O') && (field[1][1] == 'O') && (field[0][2] == 'O')) {
draw_win(canvas, 'O');
} else if( } else if(
(fieldx[0][0] == true) && (fieldx[0][1] == true) && (fieldx[0][2] == true) && (ticst->field[0][1] == 'X') && (ticst->field[1][1] == 'X') &&
(fieldx[1][0] == true) && (fieldx[1][1] == true) && (fieldx[1][2] == true) && (ticst->field[2][1] == 'X')) {
(fieldx[2][0] == true) && (fieldx[2][1] == true) && (fieldx[2][2] == true)) { draw_win(canvas, 'X', ticst);
draw_win(canvas, 'T'); } else if(
(ticst->field[0][2] == 'X') && (ticst->field[1][2] == 'X') &&
(ticst->field[2][2] == 'X')) {
draw_win(canvas, 'X', ticst);
} else if(
(ticst->field[0][0] == 'X') && (ticst->field[0][1] == 'X') &&
(ticst->field[0][2] == 'X')) {
draw_win(canvas, 'X', ticst);
} else if(
(ticst->field[1][0] == 'X') && (ticst->field[1][1] == 'X') &&
(ticst->field[1][2] == 'X')) {
draw_win(canvas, 'X', ticst);
} else if(
(ticst->field[2][0] == 'X') && (ticst->field[2][1] == 'X') &&
(ticst->field[2][2] == 'X')) {
draw_win(canvas, 'X', ticst);
} else if(
(ticst->field[0][0] == 'X') && (ticst->field[1][1] == 'X') &&
(ticst->field[2][2] == 'X')) {
draw_win(canvas, 'X', ticst);
} else if(
(ticst->field[2][0] == 'X') && (ticst->field[1][1] == 'X') &&
(ticst->field[0][2] == 'X')) {
draw_win(canvas, 'X', ticst);
} else if(
(ticst->field[0][0] == 'O') && (ticst->field[1][0] == 'O') &&
(ticst->field[2][0] == 'O')) {
draw_win(canvas, 'O', ticst);
} else if(
(ticst->field[0][1] == 'O') && (ticst->field[1][1] == 'O') &&
(ticst->field[2][1] == 'O')) {
draw_win(canvas, 'O', ticst);
} else if(
(ticst->field[0][2] == 'O') && (ticst->field[1][2] == 'O') &&
(ticst->field[2][2] == 'O')) {
draw_win(canvas, 'O', ticst);
} else if(
(ticst->field[0][0] == 'O') && (ticst->field[0][1] == 'O') &&
(ticst->field[0][2] == 'O')) {
draw_win(canvas, 'O', ticst);
} else if(
(ticst->field[1][0] == 'O') && (ticst->field[1][1] == 'O') &&
(ticst->field[1][2] == 'O')) {
draw_win(canvas, 'O', ticst);
} else if(
(ticst->field[2][0] == 'O') && (ticst->field[2][1] == 'O') &&
(ticst->field[2][2] == 'O')) {
draw_win(canvas, 'O', ticst);
} else if(
(ticst->field[0][0] == 'O') && (ticst->field[1][1] == 'O') &&
(ticst->field[2][2] == 'O')) {
draw_win(canvas, 'O', ticst);
} else if(
(ticst->field[2][0] == 'O') && (ticst->field[1][1] == 'O') &&
(ticst->field[0][2] == 'O')) {
draw_win(canvas, 'O', ticst);
} else if(
(ticst->fieldx[0][0] == true) && (ticst->fieldx[0][1] == true) &&
(ticst->fieldx[0][2] == true) && (ticst->fieldx[1][0] == true) &&
(ticst->fieldx[1][1] == true) && (ticst->fieldx[1][2] == true) &&
(ticst->fieldx[2][0] == true) && (ticst->fieldx[2][1] == true) &&
(ticst->fieldx[2][2] == true)) {
draw_win(canvas, 'T', ticst);
} }
tictactoe_draw(canvas); tictactoe_draw(canvas, ticst);
release_mutex((ValueMutex*)ctx, tictactoe_state); release_mutex((ValueMutex*)ctx, ticst);
} }
static void tictactoe_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { static void tictactoe_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
@@ -310,26 +344,26 @@ int32_t tictactoe_game_app(void* p) {
processing = false; processing = false;
break; break;
case InputKeyRight: case InputKeyRight:
selX++; tictactoe_state->selX++;
break; break;
case InputKeyLeft: case InputKeyLeft:
selX--; tictactoe_state->selX--;
break; break;
case InputKeyUp: case InputKeyUp:
selY--; tictactoe_state->selY--;
break; break;
case InputKeyDown: case InputKeyDown:
selY++; tictactoe_state->selY++;
break; break;
case InputKeyOk: case InputKeyOk:
button_state = true; tictactoe_state->button_state = true;
break; break;
} }
} }
} }
} else { } else {
// Event timeout // Event timeout
FURI_LOG_D(TAG, "osMessageQueue: Event timeout"); FURI_LOG_D(TAG, "furi_message_queue: Event timeout");
} }
view_port_update(view_port); view_port_update(view_port);