用C语言实现扫雷
程序员文章站
2024-03-18 17:49:40
...
扫雷小游戏大家应该都玩过,今天,我要用C语言来实现这个游戏。
那么,如何完成扫雷小游戏?我之前写过一个三子棋的代码,扫雷的完成中很多函数都可以模仿我们三子棋的函数。
首先,需要顺一下扫雷的思路:
- 需要一个菜单,让玩家选择开始游戏或者退出游戏
- 初始化数组
- 打印棋盘
- 设置雷
- 玩家扫雷
有一些细节我们需要注意:需要两个棋盘,一个是展现给玩家的,一个是让电脑生成雷的,在坐标周围没雷的时候可以实现展开,让玩家第一次不踩雷。
有了思路,就可以上手了。
game.h中的函数声明
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define mine 10
void menu();
void InitBoard(char board[ROWS][COLS], int rows, int cols, char put);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char save[ROWS][COLS], int row, int col);
void PlayerMove(char save[ROWS][COLS], char show[ROWS][COLS], int row, int col);
game.c实现函数
#include"game.h"
void menu(){
printf("////////////////////////////\n");
printf("///1.开始游戏 0.退出游戏///\n");
printf("////////////////////////////\n");
}
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char put){
int i = 0;
int j = 0;
for (i = 0; i < rows; i++){
for (j = 0; j < cols; j++)
board[i][j] = put;
}
}
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col){
int i = 0;
int j = 0;
for (i = 0; i <= row; i++){
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++){
printf("%d ", i);
for (j = 1; j <= col; j++){
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("\n");
}
//设置雷
void SetMine(char save[ROWS][COLS], int row, int col){
int i = 0;
int j = 0;
int count = mine;
while (count){
i = rand() % 9 + 1;//randmax 32767
j = rand() % 9 + 1;
if (save[i][j] == '0'){
save[i][j] = '1';
count--;
}
}
}
//检测雷的个数
int AllMine(char save[ROWS][COLS],int x,int y){
return save[x - 1][y] + save[x - 1][y - 1] + save[x - 1][y + 1] + save[x][y - 1] +
save[x][y + 1] + save[x + 1][y] + save[x + 1][y + 1] + save[x + 1][y - 1]-8*'0';
}
//实现展开周边非雷部分
void Open(char save[ROWS][COLS],char show[ROWS][COLS],int row,int col,int x,int y){
int ret = 0;
ret = AllMine(save, x, y);
if (ret == 0){
show[x][y] = ' ';
if (x - 1 > 0 && y - 1 > 0 && show[x - 1][y - 1] == '*'){
Open(save, show, row, col, x-1, y-1);
}
if (x > 0 && y - 1 > 0 && show[x][y - 1] == '*'){
Open(save, show, row, col, x, y - 1);
}
if (x + 1 > 0 && y - 1 > 0 && show[x + 1][y - 1] == '*'){
Open(save, show, row, col, x + 1, y - 1);
}
if (x + 1 > 0 && y > 0 && show[x + 1][y] == '*'){
Open(save, show, row, col, x + 1, y);
}
if (x + 1 > 0 && y + 1 > 0 && show[x + 1][y + 1] == '*'){
Open(save, show, row, col, x + 1, y + 1);
}
if (x > 0 && y + 1 > 0 && show[x][y + 1] == '*'){
Open(save, show, row, col, x, y + 1);
}
if (x - 1 > 0 && y + 1 > 0 && show[x - 1][y + 1] == '*'){
Open(save, show, row, col, x - 1, y + 1);
}
if (x - 1 > 0 && y > 0 && show[x - 1][y] == '*'){
Open(save, show, row, col, x - 1, y);
}
}
else{
show[x][y] = AllMine(save, x, y) + '0';
}
}
//第一次不踩雷
void FirstMove(char save[ROWS][COLS],int x, int y)
{
if (save[x][y] == '1')
{
save[x][y] = '0';
while (1){
x= rand() % 9 + 1;
y = rand() % 9 + 1;
if (save[x][y] != '0')
{
save[x][y] = '0';
break;
}
}
}
}
//玩家扫雷
void PlayerMove(char save[ROWS][COLS], char show[ROWS][COLS], int row, int col){
int i = 0;
int j = 0;//判断坐标是否合法
int n = 0;
int m = 0;
while (m<ROW * COL - mine){
printf("输入一个坐标:");
scanf("%d%d", &i, &j);
if ((i <= row) && (i > 0) && (j <= col) && (j > 0)){
if (save[i][j] == '1'){
if (m == 0)
FirstMove(save, i, j);
else{
printf("踩到雷啦!游戏结束!\n");
DisplayBoard(save, ROW, COL);
break;
}
}
else{
n = AllMine(save, i, j);
show[i][j] = n + '0';
Open(save, show, row, col, i, j);
DisplayBoard(show, ROW, COL);
m++;
}
}
else
printf("坐标非法!请重新输入!\n");
}
if (m >= ROW*COL - mine){
printf("你真厉害!成功排掉了所有的雷!\n");
DisplayBoard(save, ROW, COL);
}
}
在test.c中使用
#include"game.h"
void game(){
char save[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
InitBoard(save, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
SetMine(save, ROW, COL);
DisplayBoard(show, ROW, COL);
PlayerMove(save, show, ROW, COL);
}
int main(){
int n = 0;
srand((unsigned int)time(NULL));
do{
menu();
printf("输入你的选择:");
scanf("%d", &n);
switch (n){
case 1:
game();
break;
case 0:
printf("退出游戏!");
break;
default:
printf("非法输入,请重新选择!\n");
break;
}
} while (n);
system("pause");
return 0;
}
总的来说,扫雷相比较三子棋还是难了一些,如果大家发现有什么问题,帮忙在评论区提醒我一下<.<
上一篇: FPGA设计中对输入信号的处理(转)
下一篇: 对于浮点型的一些看法