一、序言
创建一个9*9有10个雷的扫雷游戏
文章的顺序是按照我当时的编程顺序写的,顺便写下我当初的一点思路,总的代码在文章最后,前面的都是分散的函数,有需要的朋友直接复制最后的
二、创建
创建一个头文件,一个放游戏的程序,一个放运行测试的程序
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdlib.h>//生成随机数
#include<stdio.h>
#include<time.h>//生成时间戳#define ROW 9//行数
#define COL 9//列数
#define ROWS ROW+2
#define COLS COL+2
#define EASY 10//雷数void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);//初始函数
void DisplayBoard(char board[ROWS][COLS], int row, int col);//展示函数
void SetBoard(char board[ROWS][COLS], int row, int col);//造雷函数
void CheckBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);//扫描函数
三、选择界面
进入游戏,可能出现情况三种,分别是退出,游戏和输入错误
也许有人一局完了还想玩,所以要设置循环,写完代码可以运行一下,避免最后出bug范围太大
#include"game.h"
void test()
{int input = 0;do{menu();printf("input choice:>");scanf("%d", &input);switch (input){case 0:printf("overn");break;case 1:game();break;default:printf("input wrongn");break;}} while (input);
}
void menu()
{printf("*********************n");printf("******* 1.game ******n");printf("****** 0.over ******n");printf("*********************n");
}
int main()
{test();return 0;
}
四、游戏部分
1、声明变量和初始化
建立存储扫雷的元素的数组,这里咱们可以设置两个字符形数组,一个是标识着炸弹‘1’的mine数组,一个是用来给玩家展示的show数组
虽然是99的大小,但是在之后要由电脑扫描咱们选中点周围的区域,如果数组为9行9列,电脑在扫描最外面一行时就跟中间的部分不一样了,为了方便,咱们建立1111的数组
void game()
{srand((unsigned)time(NULL));//这里使用了time.h制造时间戳,以便随机生成数char mine[ROWS][COLS];char show[ROWS][COLS];InitBoard(mine, ROWS, COLS, '0');InitBoard(show, ROWS, COLS, '*');DisplayBoard(show, ROW, COL);SetBoard(mine, ROW, COL);CheckBoard(mine, show, ROW, COL);
}
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{int i = 0;int j = 0;for (i = 0; i < rows; i++){for (j = 0; j < cols; j++){board[i][j] = set;}}
}
2、展示函数
申明和定义好变量,肯定要让玩家看到游戏盘的变化情况才能玩,所以写一个展示函数
mine数组中炸弹用‘1’来表示,不是炸弹用‘0’表示,show数组中我们用‘*’表示一个区域,然后选中的点要是周围无炸弹,就是‘ ’,否则就标识出周围的炸弹数。
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{int i = 0;int j = 0;printf("----------------------------");printf("n");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("----------------------------");printf("n");
}
3、造炸弹
这里咱们在头文件定义炸弹数,以后想玩多点炸弹,修改一个数就行,方便快捷
void SetBoard(char board[ROWS][COLS], int row, int col)
{int x = 0;int y = 0;int num = EASY;while (num){x = rand() % ROW + 1;y = rand() % COL + 1;if (board[x][y] == '0'){board[x][y] = '1';num--;}}
}
4、扫描函数
进入游戏,玩家只有选择了要检查的点才能继续,这里有三种情况,因为要有很多次选择,所以采用循环
(1)选中雷区,那么直接跳出循环,游戏结束
(2)没选中雷区,电脑会扫描周围的区域,把周围无雷的点展开,展开周围有雷的点
这里还要说一下mine数组为什么要用‘0’和‘1’来做标记,因为0和1这两个字符在ascII码表里是连续的,一会在电脑扫描周围时可以直接通过减法算出周围的雷数
void CheckBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int ret = 0;int x = 0;int y = 0;int num = 0;while (ret < ROW*COL - EASY){printf("输入排查坐标n");scanf("%d%d", &x, &y);if (x > 0 && x <= row && y > 0 && y <= col){if (mine[x][y] == '1')//选中雷区,游戏结束{printf("炸死n");DisplayBoard(mine, row, col);//展示mine区域break;//跳出循环}else//没踩中雷区{ZeroLine(mine, show, x, y);//展开周围的区域DisplayBoard(show, row, col);ret++;}}else{printf("input wrongn");}}if (ret == ROW * COL - EASY){printf("胜利n");}
}
void ZeroLine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{int ret = 0;ret = AroundNum(mine, x, y);//扫描函数,扫描该点周围雷数if (x >= 0 && y >= 0 && x < ROWS && y < COLS){if (ret == 0){show[x][y] = ' ';//无雷则为空白if (mine[x][y + 1] == '0' && show[x][y + 1] == '*'){ZeroLine(mine, show, x, y + 1);}if (mine[x][y - 1] == '0' && show[x][y - 1] == '*'){ZeroLine(mine, show, x, y - 1);}if (mine[x - 1][y] == '0' && show[x - 1][y] == '*'){ZeroLine(mine, show, x - 1, y);}if (mine[x + 1][y] == '0' && show[x + 1][y] == '*'){ZeroLine(mine, show, x + 1, y);}if (mine[x + 1][y + 1] == '0' && show[x + 1][y + 1] == '*'){ZeroLine(mine, show, x + 1, y + 1);}if (mine[x - 1][y - 1] == '0' && show[x - 1][y - 1] == '*'){ZeroLine(mine, show, x - 1, y - 1);} if (mine[x + 1][y - 1] == '0' && show[x + 1][y - 1] == '*'){ZeroLine(mine, show, x + 1, y - 1);}if (mine[x - 1][y + 1] == '0' && show[x - 1][y - 1] == '*'){ZeroLine(mine, show, x - 1, y + 1);}}else{show[x][y] = ret + '0';}}
}
int AroundNum(char mine[ROWS][COLS], int x, int y)
{return mine[x - 1][y - 1] + mine[x][y - 1] + mine[x - 1][y] +mine[x + 1][y + 1] + mine[x][y + 1] + mine[x + 1][y] +mine[x - 1][y + 1] + mine[x + 1][y - 1] - 8 * mine[x][y];
}
五、总代码
1、头文件
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdlib.h>
#include<stdio.h>
#include<time.h>#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY 10void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
void DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetBoard(char board[ROWS][COLS], int row, int col);
void CheckBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
2、游戏部分
#include"game.h"void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{int i = 0;int j = 0;for (i = 0; i < rows; i++){for (j = 0; j < cols; j++){board[i][j] = set;}}
}
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{int i = 0;int j = 0;printf("----------------------------");printf("n");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("----------------------------");printf("n");
}
void SetBoard(char board[ROWS][COLS], int row, int col)
{int x = 0;int y = 0;int num = EASY;while (num){x = rand() % ROW + 1;y = rand() % COL + 1;if (board[x][y] == '0'){board[x][y] = '1';num--;}}
}
int AroundNum(char mine[ROWS][COLS], int x, int y)
{return mine[x - 1][y - 1] + mine[x][y - 1] + mine[x - 1][y] +mine[x + 1][y + 1] + mine[x][y + 1] + mine[x + 1][y] +mine[x - 1][y + 1] + mine[x + 1][y - 1] - 8 * mine[x][y];
}
void ZeroLine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{int ret = 0;ret = AroundNum(mine, x, y);if (x >= 0 && y >= 0 && x < ROWS && y < COLS){if (ret == 0){show[x][y] = ' ';if (mine[x][y + 1] == '0' && show[x][y + 1] == '*'){ZeroLine(mine, show, x, y + 1);}if (mine[x][y - 1] == '0' && show[x][y - 1] == '*'){ZeroLine(mine, show, x, y - 1);}if (mine[x - 1][y] == '0' && show[x - 1][y] == '*'){ZeroLine(mine, show, x - 1, y);}if (mine[x + 1][y] == '0' && show[x + 1][y] == '*'){ZeroLine(mine, show, x + 1, y);}if (mine[x + 1][y + 1] == '0' && show[x + 1][y + 1] == '*'){ZeroLine(mine, show, x + 1, y + 1);}if (mine[x - 1][y - 1] == '0' && show[x - 1][y - 1] == '*'){ZeroLine(mine, show, x - 1, y - 1);} if (mine[x + 1][y - 1] == '0' && show[x + 1][y - 1] == '*'){ZeroLine(mine, show, x + 1, y - 1);}if (mine[x - 1][y + 1] == '0' && show[x - 1][y - 1] == '*'){ZeroLine(mine, show, x - 1, y + 1);}}else{show[x][y] = ret + '0';}}
}
void CheckBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int ret = 0;int x = 0;int y = 0;int num = 0;while (ret < ROW*COL - EASY){printf("输入排查坐标n");scanf("%d%d", &x, &y);if (x > 0 && x <= row && y > 0 && y <= col){if (mine[x][y] == '1'){printf("炸死n");DisplayBoard(mine, row, col);break;}else{ZeroLine(mine, show, x, y);DisplayBoard(show, row, col);ret++;}}else{printf("input wrongn");}}if (ret == ROW * COL - EASY){printf("胜利n");}
}
3、检测部分
#include"game.h"
void menu()
{printf("*********************n");printf("******* 1.game ******n");printf("****** 0.over ******n");printf("*********************n");
}
void game()
{srand((unsigned)time(NULL));char mine[ROWS][COLS];char show[ROWS][COLS];InitBoard(mine, ROWS, COLS, '0');InitBoard(show, ROWS, COLS, '*');DisplayBoard(show, ROW, COL);SetBoard(mine, ROW, COL);CheckBoard(mine, show, ROW, COL);
}
void test()
{int input = 0;do{menu();printf("input choice:>");scanf("%d", &input);switch (input){case 0:printf("overn");break;case 1:game();break;default:printf("input wrongn");break;}} while (input);
}
int main()
{test();return 0;
}
本文发布于:2024-02-04 10:09:51,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170704779054638.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |