Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #3

Merged
merged 5 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions scenes/confirmation_scene.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,8 @@ bool minesweeper_scene_confirmation_screen_on_event(void* context, SceneManagerE
app->settings_info.difficulty = app->t_settings_info.difficulty;
app->is_settings_changed = false;

mine_sweeper_game_screen_set_board_dimensions(
app->game_screen,
app->settings_info.board_width,
app->settings_info.board_width);

// Reset the game board
mine_sweeper_game_screen_reset(app->game_screen);
mine_sweeper_game_screen_reset(app->game_screen, app->settings_info.board_width, app->settings_info.board_height);

// Go to reset game view
scene_manager_search_and_switch_to_another_scene(app->scene_manager, MineSweeperSceneGameScreen);
Expand Down
1 change: 0 additions & 1 deletion scenes/start_screen_scene.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,4 @@ void minesweeper_scene_start_screen_on_exit(void* context) {

MineSweeperApp* app = context;
start_screen_reset(app->start_screen);
mine_sweeper_game_screen_reset(app->game_screen);
}
91 changes: 53 additions & 38 deletions views/minesweeper_game_screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,10 @@ void mine_sweeper_game_screen_view_draw_callback(Canvas* canvas, void* _model) {
for (uint8_t y_rel = 0; y_rel < MINESWEEPER_SCREEN_TILE_WIDTH; y_rel++) {
uint16_t y_abs = (model->right_boundary - MINESWEEPER_SCREEN_TILE_WIDTH) + y_rel;

uint16_t board_buffer_pos_abs = x_abs * MINESWEEPER_BOARD_TILE_WIDTH + y_abs;
uint16_t board_buffer_pos_abs = x_abs * model->board_width + y_abs;
MineSweeperTile tile = model->board[board_buffer_pos_abs];

if (model->curr_pos.x_abs * MINESWEEPER_BOARD_TILE_WIDTH + model->curr_pos.y_abs == board_buffer_pos_abs) {
if (model->curr_pos.x_abs * model->board_width + model->curr_pos.y_abs == board_buffer_pos_abs) {
inverted_canvas_white_to_black(
canvas,
{
Expand Down Expand Up @@ -201,12 +201,12 @@ bool mine_sweeper_game_screen_view_input_callback(InputEvent* event, void* conte
instance->view,
MineSweeperGameScreenModel * model,
{
model->curr_pos.x_abs = (model->curr_pos.x_abs+1 >= MINESWEEPER_BOARD_TILE_HEIGHT) ?
MINESWEEPER_BOARD_TILE_HEIGHT-1 : model->curr_pos.x_abs+1;
model->curr_pos.x_abs = (model->curr_pos.x_abs+1 >= model->board_height) ?
model->board_height-1 : model->curr_pos.x_abs+1;

bool is_outside_boundary = model->curr_pos.x_abs >= model->bottom_boundary;

if (is_outside_boundary /**&& model->bottom_boundary+1 <= MINESWEEPER_BOARD_TILE_HEIGHT*/) {
if (is_outside_boundary /**&& model->bottom_boundary+1 <= model->board_height*/) {
model->bottom_boundary++;
}
},
Expand Down Expand Up @@ -236,12 +236,12 @@ bool mine_sweeper_game_screen_view_input_callback(InputEvent* event, void* conte
instance->view,
MineSweeperGameScreenModel * model,
{
model->curr_pos.y_abs = (model->curr_pos.y_abs+1 >= MINESWEEPER_BOARD_TILE_WIDTH) ?
MINESWEEPER_BOARD_TILE_WIDTH-1 : model->curr_pos.y_abs+1;
model->curr_pos.y_abs = (model->curr_pos.y_abs+1 >= model->board_width) ?
model->board_width-1 : model->curr_pos.y_abs+1;

bool is_outside_boundary = model->curr_pos.y_abs >= model->right_boundary;

if (is_outside_boundary /**&& model->right_boundary+1 <= MINESWEEPER_BOARD_TILE_WIDTH*/) {
if (is_outside_boundary /**&& model->right_boundary+1 <= model->board_width*/) {
model->right_boundary++;
}
},
Expand All @@ -267,31 +267,46 @@ bool mine_sweeper_game_screen_view_input_callback(InputEvent* event, void* conte
static void setup_board(MineSweeperGameScreen* instance) {
furi_assert(instance);

// We can use a temporary buffer to set the tile types initially
// and manipulate then save to actual model
MineSweeperGameScreenTileType tiles[MINESWEEPER_BOARD_TILE_COUNT];
uint16_t board_tile_count = 0;
uint8_t board_width = 0, board_height = 0;

with_view_model(
instance->view,
MineSweeperGameScreenModel * model,
{
board_width = model->board_width;
board_height = model->board_height;
board_tile_count = (model->board_width*model->board_height);
},
false);

/** We can use a temporary buffer to set the tile types initially
* and manipulate then save to actual model
*/

MineSweeperGameScreenTileType tiles[MINESWEEPER_BOARD_MAX_TILES];
memset(&tiles, 0, sizeof(tiles));

for (uint16_t i = 0; i < MINESWEEPER_STARTING_MINES; i++) {
uint16_t rand_pos;

do {
rand_pos = furi_hal_random_get() % MINESWEEPER_BOARD_TILE_COUNT;
rand_pos = furi_hal_random_get() % (board_tile_count);
} while (tiles[rand_pos] == MineSweeperGameScreenTileMine);

tiles[rand_pos] = MineSweeperGameScreenTileMine;
}

// All mines are set so we look at each tile for surrounding mines
for (uint16_t i = 0; i < MINESWEEPER_BOARD_TILE_COUNT; i++) {
/** All mines are set so we look at each tile for surrounding mines */
for (uint16_t i = 0; i < (board_tile_count); i++) {
MineSweeperGameScreenTileType tile_type = tiles[i];

if (tile_type == MineSweeperGameScreenTileMine) {
continue;
}

uint16_t x = i / MINESWEEPER_BOARD_TILE_WIDTH;
uint16_t y = i % MINESWEEPER_BOARD_TILE_WIDTH;
uint16_t x = i / board_width;
uint16_t y = i % board_width;

uint8_t offsets[8][2] = {
{-1,1},
Expand All @@ -310,11 +325,11 @@ static void setup_board(MineSweeperGameScreen* instance) {
int16_t dx = x + (uint16_t)offsets[j][0];
int16_t dy = y + (uint16_t)offsets[j][1];

if (dx < 0 || dy < 0 || dx >= MINESWEEPER_BOARD_TILE_HEIGHT || dy >= MINESWEEPER_BOARD_TILE_WIDTH) {
if (dx < 0 || dy < 0 || dx >= board_height || dy >= board_width) {
continue;
}

uint16_t pos = dx * MINESWEEPER_BOARD_TILE_WIDTH + dy;
uint16_t pos = dx * board_width + dy;
if (tiles[pos] == MineSweeperGameScreenTileMine) {
mine_count++;
}
Expand All @@ -324,20 +339,19 @@ static void setup_board(MineSweeperGameScreen* instance) {

}


// Save tiles to view model
// Because of way tile enum and Icon* array is set up we can
// index tile_icons with the enum type to get the correct Icon*
with_view_model(
instance->view,
MineSweeperGameScreenModel * model,
{
for (uint16_t i = 0; i < MINESWEEPER_BOARD_TILE_COUNT; i++) {
for (uint16_t i = 0; i < (model->board_width*model->board_height); i++) {
model->board[i].tile_type = tiles[i];
model->board[i].tile_state = MineSweeperGameScreenTileStateUncleared;
model->board[i].icon_element.icon = tile_icons[ tiles[i] ];
model->board[i].icon_element.x_abs = (i/MINESWEEPER_BOARD_TILE_WIDTH);
model->board[i].icon_element.y_abs = (i%MINESWEEPER_BOARD_TILE_WIDTH);
model->board[i].icon_element.x_abs = (i/model->board_width);
model->board[i].icon_element.y_abs = (i%model->board_width);
}

model->mines_left = MINESWEEPER_STARTING_MINES;
Expand All @@ -349,7 +363,19 @@ static void setup_board(MineSweeperGameScreen* instance) {

},
true);
}

static void mine_sweeper_game_screen_set_board_dimensions(MineSweeperGameScreen* instance, uint8_t width, uint8_t height) {
furi_assert(instance);

with_view_model(
instance->view,
MineSweeperGameScreenModel * model,
{
model->board_width = width;
model->board_height = height;
},
true);
}

MineSweeperGameScreen* mine_sweeper_game_screen_alloc(uint8_t width, uint8_t height) {
Expand Down Expand Up @@ -396,11 +422,13 @@ void mine_sweeper_game_screen_free(MineSweeperGameScreen* instance) {

// This function should be called whenever you want to reset the game state
// This should NOT be called in the on_exit in the game scene
void mine_sweeper_game_screen_reset(MineSweeperGameScreen* instance) {
void mine_sweeper_game_screen_reset(MineSweeperGameScreen* instance, uint8_t width, uint8_t height) {
furi_assert(instance);

instance->input_callback = NULL;


mine_sweeper_game_screen_set_board_dimensions(instance, width, height);

setup_board(instance);

}
Expand All @@ -420,19 +448,6 @@ void mine_sweeper_game_screen_set_context(MineSweeperGameScreen* instance, void*
instance->context = context;
}

void mine_sweeper_game_screen_set_board_dimensions(MineSweeperGameScreen* instance, uint8_t width, uint8_t height) {
furi_assert(instance);

with_view_model(
instance->view,
MineSweeperGameScreenModel * model,
{
model->board_width = width;
model->board_height = height;
},
false);
}

bool mine_sweeper_is_tile_mine(MineSweeperGameScreen* instance, uint16_t x, uint16_t y) {
furi_assert(instance);
bool is_mine = false;
Expand All @@ -441,7 +456,7 @@ bool mine_sweeper_is_tile_mine(MineSweeperGameScreen* instance, uint16_t x, uint
instance->view,
MineSweeperGameScreenModel * model,
{
uint16_t pos = x * MINESWEEPER_BOARD_TILE_WIDTH + y;
uint16_t pos = x * model->board_width + y;
if (model->board[pos].tile_type == MineSweeperGameScreenTileMine) {
is_mine = true;
}
Expand Down
19 changes: 3 additions & 16 deletions views/minesweeper_game_screen.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,10 @@

// These defines represent how many tiles
// can be visually representen on the screen
#define MINESWEEPER_SCREEN_TILE_HEIGHT 8
#define MINESWEEPER_SCREEN_TILE_HEIGHT 7
#define MINESWEEPER_SCREEN_TILE_WIDTH 16

// These defines currently represent the actual
// width and hight in tiles for the board.
// This should be replaced with uint8_t members in the
// view model that can be changed by the user
#define MINESWEEPER_BOARD_TILE_HEIGHT 8
#define MINESWEEPER_BOARD_TILE_WIDTH 128

#define MINESWEEPER_BOARD_TILE_COUNT (MINESWEEPER_BOARD_TILE_HEIGHT * MINESWEEPER_BOARD_TILE_WIDTH)
#define MINESWEEPER_STARTING_MINES (MINESWEEPER_BOARD_TILE_COUNT * .20f)
#define MINESWEEPER_STARTING_MINES (44)

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -56,7 +48,7 @@ void mine_sweeper_game_screen_free(MineSweeperGameScreen* instance);
*
* @param instance MineSweeperGameScreen instance
*/
void mine_sweeper_game_screen_reset(MineSweeperGameScreen* instance);
void mine_sweeper_game_screen_reset(MineSweeperGameScreen* instance, uint8_t width, uint8_t height);

/** Get MineSweeperGameScreen view
*
Expand All @@ -82,11 +74,6 @@ void mine_sweeper_game_screen_set_input_callback(
*/
void mine_sweeper_game_screen_set_context(MineSweeperGameScreen* instance, void* context);

/**
* ADD LATER
*/
void mine_sweeper_game_screen_set_board_dimensions(MineSweeperGameScreen* instance, uint8_t width, uint8_t height);

/** Return true/false if tile is a mine
*
* @param instance MineSweeperGameScreen instance
Expand Down