2019年9月9日月曜日

Open Source] Simple CUI Minesweeper in C Language(with Spreading Zeros)

I have uploaded my code to GitHub:
https://github.com/ka373/SimpleCUIMinesweeperWithSpreadingZeros

__________________________________________
This program is a simple CUI minesweeper in C.

Many people want to implement a Minesweeper game before learning data structures or algorithms in detail. This program is made to be recognizable and implementable to them as well.

I implemented the Spreading Zeros feature that many people who implement minesweeper games don't make.

* Spreading Zeros: When there are no mines in the eight blocks around a stepped block, the 8 blocks are also gradually treated as stepped on.


I. Purpose of the game
You can clear the game by stepping on all the ground except for the mines on the board.


II. Progress of the game
There is a board, and the game is played by stepping on it, marking a mine or "?".


__________________________________________
[Some production processes]


0. Structure of the game
Repeat 1) ~ 4) while the game continues
 1) Input block position and type.
 2) Enter the location and type of the block in the game progress function.
 3) Determine whether the player lived or died.
 4) Print the progress (board).


1. Create boards
Since the game is played on board, we need boards.
 1) the visible board I'm exploring(board_visible)
 2) the answer board (board_kotae).

int board_visible[NUM_OF_ROWS][NUM_OF_COLUMNS];    // Similar to the board seen by the user
int board_kotae[NUM_OF_ROWS][NUM_OF_COLUMNS];    //Board with numbers and mines (correct answer board)
cs



2. Configure the answer board (board_kotae)

2.1. Build and deploy mines
Generate as many random numbers as the number of blocks on the board, and place mines on the board according to the random numbers.

    //mine planting
    if (process_NUM_MINE_randoms() == 1) {
        for (i = 0; i < NUM_MINE; i++) {
            int mine_row = obtained_randoms[i] / NUM_OF_ROWS;
            int mine_column = obtained_randoms[i] % NUM_OF_ROWS;
            board_kotae[mine_row][mine_column] = MINE;
            //printf("\nLocation of mines: row: %d column: %d\n", mine_row, mine_column);
        }
    }
cs


2.2. Number setting
Searching through the array, assigning numbers by counting the number of mines in the block around them.


3. Create a game progress function (process_game)

3.1. If the input location is already visited, it is invalidated.

3.2. If the user stepped on a new block
Refer to the answer board and enter the value in the visible board.
Here the value entered in the visible board is used to print the board.

3.2.1. User stepped on: A number between 1 and 8
Enter the number on the visible board.

3.2.2. User stepped on: Landmine
Enter the number corresponding to the visible board.
Returns a value indicating gameover (in my case, is_live = 0;)

3.2.3. User stepped on: 0 (If there are no zeros around the block)
If the number of the selected block is 0, 0 is spread out, and the surrounding 0 is also treated as stepped on.

I think this part is harder to implement than other parts. therefore, If you want to implement minesweeper on your own, please try to solve it yourself before referring to this section.
.
.
.
.
.
.
.
.
.
.
In my case, I implemented it through recursive function as follows.

If the step is 0, the process is performed recursively in the upper left, upper, upper right, left, right, lower left, lower, and lower right directions.

It's a bit of a hobby development, so you can't be sure it's an optimized algorithm. However, It doesn't seem to be a big problem just for the performance we need.

I hope someone reading this article also thinks about other good algorithms.



        //spreading zeros(0の連鎖爆弾!0의 연쇄폭탄!)
        if (board_visible[row_entered][column_entered] == 0) {
            if (can_go(row_entered - 1, column_entered - 1)) {
                process_game(row_entered - 1, column_entered - 1, STEPPED);    //Spread to left upper diagonal ↖
            }
            if (can_go(row_entered - 1, column_entered + 1)) {
                process_game(row_entered - 1, column_entered + 1, STEPPED);    //Spread across the upper right diagonal ↗
            }
            if (can_go(row_entered + 1, column_entered - 1)) {
                process_game(row_entered + 1, column_entered - 1, STEPPED);    //Spread to left lower diagonal ↙
            }
            if (can_go(row_entered + 1, column_entered + 1)) {
                process_game(row_entered + 1, column_entered + 1, STEPPED);    //Spread across the lower right diagonal ↘
            }
            if (can_go(row_entered - 1, column_entered)) { process_game(row_entered - 1, column_entered, STEPPED); }//Spread up ↑
            if (can_go(row_entered + 1, column_entered)) { process_game(row_entered + 1, column_entered, STEPPED); }//Spread down ↓
            if (can_go(row_entered, column_entered - 1)) { process_game(row_entered, column_entered - 1, STEPPED); }//Spread left ←
            if (can_go(row_entered, column_entered + 1)) { process_game(row_entered, column_entered + 1, STEPPED); }//Spread to the right →
        }// end of if연쇄폭탄
cs



__________________________________________
So far, I've organized a little bit about the minesweeper game I've implemented.

Through recursive processing, I implemented the Spreading Zeros feature, one of the charms of implementing minesweeper games.

By implementing games such as minesweeper and other programs, we can practice and improve our programming and implementation skills. And we will be able to contribute a little bit to the world.

0 件のコメント:

コメントを投稿