赞
踩
目录
为了代码的可读性和可操作性,开始前要定义一些值,后续有讲解:
- #define ROW 9
- #define COL 9
-
- #define ROWS ROW+2
- #define COLS COL+2
-
- #define Set 10
我们要创建两个字符串二维数组,一个用来存储雷的位置,一个用来给玩家提示信息的位置,玩家输入一个坐标,如果这个坐标是雷,就提示玩家被炸了,如果这个坐标不是雷,则提示玩家周围雷的数量,供玩家进行排雷。
如果设计一个棋盘,则排雷和提示用户雷容易被干扰,代码可读性不强,而假设选择两个数组,把存储雷和排雷分开放,就可以在完成项目的同时还能使得代码可读性增强。
在统计数量时,我们统计的是以该点为中心周围八个点的雷的个数,如果数组设置为9*9,那么在统计周围雷的个数时会导致越界访问,产生不必要的麻烦,因此在设计时选择11*11可以避免这样的问题。
棋盘被创建好了,那么就该进行初始化了,初始化后的内容就是要让用户看到的内容,在本实验的思路中,我们选择的是让用户看到的棋盘被*覆盖,但用来存放的棋盘也需要被初始化,于是初始化函数中可以加入新的参数。
便于统计个数,后续的代码实现中会发现这样设置的优越性。
函数的实现:
- void Initboard(char board[][COLS], int rows, int cols, char c)
- {
- for (int i = 0; i < rows; i++)
- {
- for (int j = 0; j < cols; j++)
- board[i][j] = c;
- }
- }
棋盘被设置和初始化后,就可以进行打印棋盘的函数实现了,只需要打印出数组的内容即可,要注意的是为了可读性,要打印出行和列对应的数字,代码实现如下:
- void Displayboard(char board[][COLS], int row, int col)
- {
- for (int i = 0; i <= row; i++)
- {
- if (i == 0)
- printf("%d|",i);
- else
- printf("%d ", i);
- }
- printf("\n");
- for (int i = 0; i < row; i++)
- {
- printf("--");
- }
- printf("\n");
- for (int i = 1; i <= row; i++)
- {
- printf("%d|", i);
- for (int j = 1; j <= col; j++)
- {
- printf("%c ", board[i][j]);
- }
- printf("\n");
- }
- printf("\n");
- }

开头定义中我们定义了雷的个数,那么在实现函数时,基本思路是运用while循环,如果布置成功了就让雷的个数减一,直到雷的个数为0,此时判断结果为假,则此时就跳出循环,在进行判断时增加一些限制条件,判断坐标合法性等,综合考量就能得出下面的代码实现原理:
- void Setmine(char mineboard[][COLS], int row, int col)
- {
- int num = Set;
- while (num)
- {
- int x = rand() % row + 1;
- int y = rand() % col + 1;
- if (mineboard[x][y] == '0')
- {
- mineboard[x][y] = '1';
- num--;
- }
- }
- }
来看实现的基本思路,玩家输入坐标,如果恰好是雷的位置那么玩家就被淘汰出局,如果不是雷的位置就显示周围雷的个数。
在统计雷的个数的时候,统计的是周围八个格子的数据,如果先前我们选择的是#等作为雷的标记,那么在统计雷的时候就非常麻烦,但如果选择的是0和1,只需要把这些数据加起来最后减去一个'0'即可,这样就能把char类型的数据转换成int类型的数据,再返回到函数中即可。
那么具体的实现为:
- int Count(char board[][COLS], int x, int y)
- {
- return (board[x - 1][y] + board[x - 1][y - 1] + board[x - 1][y + 1] + board[x][y - 1] +
- board[x][y + 1] + board[x + 1][y] + board[x + 1][y - 1] + board[x + 1][y + 1]- 8*'0');
- }
-
- void FindSets(char mineboard[][COLS], char showboard[][COLS], int row, int col)
- {
- int x=0, y=0;
- int nums = row * col - Set;
- while (nums)
- {
- printf("请输入坐标:-->");
- scanf("%d %d", &x, &y);
- if (x >= 1 && x <= 9 && y >= 1 && y <= 9)
- {
- if (mineboard[x][y] == '1')
- {
- printf("被炸死了\n");
- break;
- }
- else
- {
- int ret = Count(mineboard, x, y);
- showboard[x][y] = ret + '0';
- Displayboard(showboard, ROW, COL);
- nums--;
- }
- }
- else
- {
- printf("坐标不合法,重新输入\n");
- }
- }
- if (nums == 0)
- {
- printf("扫雷成功,游戏结束\n");
- }
-
- }

在实际的游戏过程中,在玩家点击一块没有雷的方格时,会将周围的部分都展开,而本文写的这个代码游戏不能达成这个效果,这里可以进行一定程度的优化,可以使用递归函数进行每个九宫格的展开。
在实际游戏中是用了图形库的,这里只是一个简单的游戏实现,不包括图形库,图形库也可以作为代码的优化。
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
-
- #define ROW 9
- #define COL 9
-
- #define ROWS ROW+2
- #define COLS COL+2
-
- #define Set 10
-
- void Initboard(char board[][COLS], int rows, int cols, char c)
- {
- for (int i = 0; i < rows; i++)
- {
- for (int j = 0; j < cols; j++)
- board[i][j] = c;
- }
- }
-
- void Displayboard(char board[][COLS], int row, int col)
- {
- for (int i = 0; i <= row; i++)
- {
- if (i == 0)
- printf("%d|",i);
- else
- printf("%d ", i);
- }
- printf("\n");
- for (int i = 0; i < row; i++)
- {
- printf("--");
- }
- printf("\n");
- for (int i = 1; i <= row; i++)
- {
- printf("%d|", i);
- for (int j = 1; j <= col; j++)
- {
- printf("%c ", board[i][j]);
- }
- printf("\n");
- }
- printf("\n");
- }
-
- void Setmine(char mineboard[][COLS], int row, int col)
- {
- int num = Set;
- while (num)
- {
- int x = rand() % row + 1;
- int y = rand() % col + 1;
- if (mineboard[x][y] == '0')
- {
- mineboard[x][y] = '1';
- num--;
- }
- }
- }
-
- int Count(char board[][COLS], int x, int y)
- {
- return (board[x - 1][y] + board[x - 1][y - 1] + board[x - 1][y + 1] + board[x][y - 1] +
- board[x][y + 1] + board[x + 1][y] + board[x + 1][y - 1] + board[x + 1][y + 1]- 8*'0');
- }
-
- void FindSets(char mineboard[][COLS], char showboard[][COLS], int row, int col)
- {
- int x=0, y=0;
- int nums = row * col - Set;
- while (nums)
- {
- printf("请输入坐标:-->");
- scanf("%d %d", &x, &y);
- if (x >= 1 && x <= 9 && y >= 1 && y <= 9)
- {
- if (mineboard[x][y] == '1')
- {
- printf("被炸死了\n");
- break;
- }
- else
- {
- int ret = Count(mineboard, x, y);
- showboard[x][y] = ret + '0';
- Displayboard(showboard, ROW, COL);
- nums--;
- }
- }
- else
- {
- printf("坐标不合法,重新输入\n");
- }
- }
- if (nums == 0)
- {
- printf("扫雷成功,游戏结束\n");
- }
-
- }
-
-
- void menu()
- {
- printf("*****************************\n");
- printf("********* 1.game **********\n");
- printf("********* 0.exit **********\n");
- printf("*****************************\n");
- }
-
- void game()
- {
- srand((unsigned int)time(NULL));
- char mineboard[ROWS][COLS];
- char showboard[ROWS][COLS];
- Initboard(mineboard, ROWS, COLS, '0');
- Initboard(showboard, ROWS, COLS, '*');
- Displayboard(showboard, ROW, COL);
- Setmine(mineboard, ROW, COL);
- FindSets(mineboard, showboard, ROW, COL);
-
-
-
- }
-
- int main()
- {
- int input = 0;
- do
- {
- menu();
- printf("请输入:->");
- scanf("%d", &input);
- switch (input)
- {
- case 1:
- game();
- break;
- case 0:
- printf("结束游戏\n");
- break;
- default:
- printf("重新输入\n");
- }
- } while (input);
- return 0;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。