正片开始👀
一雷不扫,何以扫天下?
今天主要是实现初级的扫雷游戏,方法比较通俗易懂,制作方面不侧重包装而注重功能实现,只是简单对“扫雷”进行简单表达,后期会进行优化和提升。
接受三子棋洗礼后,其实扫雷和上一篇的三子棋大同小异,但其实真正写过才知道扫雷要比三子棋简单一点点,因为三子棋在空间上操作更多,会更加依赖二维数组的使用,所以过程会更加繁琐。下面就来康康扫雷的具体流程:
为方便使用还是先将数组两个元素在头文件中宏定义一下,也方便后期修改:
# define ROW ROW2+2 # define COL COL2+2 # define ROW2 9 # define COL2 9
上菜单👏
void menu() { printf("------------------------------------\n"); printf("------- M e n u -----------\n"); printf("------- -----------\n"); printf("-------1.P L A Y-----------\n"); printf("-------0.E X I T-----------\n"); printf("------------------------------------\n"); printf("------------------------------------\n"); }
简简单单的小菜单,这是一个菜单函数,由switch语句实现选择功能:
void test() { int input = 0; //输入的值存入input以进行判断 srand((unsigned int)time(NULL)); do { menu(); printf("请选择菜单:>"); scanf("%d", &input); switch (input) { case 1: { printf("开始扫雷:"); saolei(); //进入游戏主体 break; } case 0: { printf("即将退出……"); break; } default: //对付非指定值输入 { printf("玩儿呢这是?\n"); break; } } } while (input); //可反复游玩 }
游戏主体👏
void saolei() { char board[ROW][COL] = { 0 }; //实际矩阵 char real[ROW][COL] = { 0 }; //玩家视角矩阵 Start(board, ROW, COL, '0'); //雷区初始化 Start(real, ROW, COL, '*'); Set(board, ROW, COL); //布雷(埋雷) Show(board, ROW2, COL2); Show(real, ROW2, COL2); //布局(雷区`在这里插入代码片`)展现 Find(board, real, ROW, COL); //逻辑判断 }
初始化👏
首先数组的创建上就与三子棋大不相同,基于游戏本身规则的特性,我们需要实际的设计雷阵和呈现给玩家的雷阵,这也是扫雷的一大特色。因为初始化方式不同,对应的功能也不一样,我们就创建了名为 board 和 real 的数组。
在 game.c中用Start函数进行定义:
void Start(char board[ROW][COL], int row, int col,char set) { int i = 0; int j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { board[i][j] = set; } printf("\n"); } }
这里用一个for循环的嵌套实现数组的初始化,这里的“ set ”是我指定好的两种字符,我们制作需要全零以便埋雷,而玩家需要一个“ * ”来达到猜测的目的。
打印雷区👏
我们先把我们需要的和玩家的打出来对比一下如下:下为玩家视角。
用 Show 函数实现如下:
void Show(char board[ROW2][COL2], int row2, int col2) { int i = 0; int j = 0; for (i = 0; i <= col2;i++) { printf("%d ", i);//打印行列对应数字 } printf("\n"); for (i = 1; i <= row2; i++) { printf("%d ", i); for (j = 1; j <= col2; j++) { printf("%c ", board[i][j]);//存入%c以埋雷 } printf("\n"); } }
埋雷大师👏
void Set(char board[ROW][COL], int row, int col) { int count = degree; while (count) { int x = rand() % row + 1; //生成0~9随机数 int y = rand() % col + 1; //生0~9成随机数 if (board[x][y] == '0') { board[x][y] = '1'; //判断,是空格就可以埋雷 count--;//埋十颗 } } }
这里的重点就只有随机数的应用。这里的随机数是伪随机数,rand函数生成,需要在主函数部分进行初始化,用到 “srand”函数,以时间戳作为随机数的生成标准,不做赘述,不了解的可详见上一篇三子棋的讲解,记住要引用<stdlib.h>和<time.h>头文件。
扫雷专家👏
==一雷不扫,何以扫天下?==扫雷的标准是成功的开山斧,逻辑到位了一切都是信手拈来。判断输赢不难,看有没有踩雷,排没排完的简单逻辑谁不会写?重点是没踩雷也没排完的过程:
当我们走到一个“安全区”时,我们显示出来的是周围8个单位格子的雷数和,我们设置一个 Amount 函数,利用周围8个单位格的返回值进行输入,这里注意,我们算出的返回值是一个整型,但我放入数组的是一个字符类型,将一个数转换成他对应的字符类型怎么办呢?很简单只需+‘ 0 ’即可,由此可知,我们在算8个单位格之和返回值时会事先 -8* ‘ 0 ’。
static Amount(char board[ROW][COL], int x, int y) // 限制为本源文件使用 { return board[x + 1][y] + board[x + 1][y + 1] + board[x][y + 1] + board[x - 1][y + 1] + board[x - 1][y] + board[x - 1][y - 1] + board[x][y - 1] + board[x + 1][y - 1]-8*'0'; //总和计算 } void Find(char board[ROW2][ROW2], char real[ROW2][COL2], int row, int col) { int x = 0; int y = 0; int i = 0; int win = 0; while (win<row*col-10) { printf("请输入排查坐标:>"); scanf("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (board[x][y] == '1') //踩雷判断 { printf("B O O M !!!!\n"); printf("Game Over\n"); Show(board,row-2,col-2); break; } else //未踩雷的雷数计算 { i = Amount(board, x, y); real[x][y] = i+'0'; Show(real,row-2,col-2); win++; } } else //判断越界 { printf("无效坐标!重新输入\n"); } } if (win == row * col - 10) //胜利判断 { printf("Congratulatin,You Win !!!\n"); } }
雷区舞王👏
完整代码,参上:
test.c
# include"saolei.h" void menu() { printf("------------------------------------\n"); printf("------- M e n u -----------\n"); printf("------- -----------\n"); printf("-------1.P L A Y-----------\n"); printf("-------0.E X I T-----------\n"); printf("------------------------------------\n"); printf("------------------------------------\n"); } void saolei() { char board[ROW][COL] = { 0 };//扫雷矩阵 char real[ROW][COL] = { 0 };//排雷矩阵 Start(board, ROW, COL, '0');//初始化 Start(real, ROW, COL, '*'); Set(board, ROW, COL);//布置 Show(board, ROW2, COL2); Show(real, ROW2, COL2);//布局 Find(board, real, ROW, COL); } void test() { int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("请选择菜单:>"); scanf("%d", &input); switch (input) { case 1: { printf("开始扫雷:"); saolei(); break; } case 0: { printf("即将退出……"); break; } default: { printf("玩儿呢这是?\n"); break; } } } while (input); } int main() { test(); return 0; }
game.c
# define _CRT_SECURE_NO_WARNINGS # include"saolei.h" void Start(char board[ROW][COL], int row, int col,char set) { int i = 0; int j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { board[i][j] = set; } printf("\n"); } } void Show(char board[ROW2][COL2], int row2, int col2) { int i = 0; int j = 0; for (i = 0; i <= col2;i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <= row2; i++) { printf("%d ", i); for (j = 1; j <= col2; j++) { printf("%c ", board[i][j]); } printf("\n"); } } void Set(char board[ROW][COL], int row, int col) { int count = degree; while (count) { int x = rand() % row + 1; int y = rand() % col + 1; if (board[x][y] == '0') { board[x][y] = '1'; count--; } } } static Amount(char board[ROW][COL], int x, int y) { return board[x + 1][y] + board[x + 1][y + 1] + board[x][y + 1] + board[x - 1][y + 1] + board[x - 1][y] + board[x - 1][y - 1] + board[x][y - 1] + board[x + 1][y - 1]-8*'0'; } void Find(char board[ROW2][ROW2], char real[ROW2][COL2], int row, int col) { int x = 0; int y = 0; int i = 0; int win = 0; while (win<row*col-10) { printf("请输入排查坐标:>"); scanf("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (board[x][y] == '1') { printf("B O O M !!!!\n"); printf("Game Over\n"); Show(board,row-2,col-2); break; } else { i = Amount(board, x, y); real[x][y] = i+'0'; Show(real,row-2,col-2); win++; } } else { printf("无效坐标!重新输入\n"); } } if (win == row * col - 10) { printf("Congratulatin,You Win !!!\n"); }
game.h
#pragma once # define ROW ROW2+2 # define COL COL2+2 # define ROW2 9 # define COL2 9 # define degree 10 # include<stdio.h> # include<stdlib.h> # include <time.h> void menu(); void saolei(); void Start(char board[ROW][COL], int row, int col,char set); void Show(char board[ROW2][COL2], int row2, int col2); void Set(char board[ROW][COL], int row2, int col2); void Find(char board[ROW][ROW], char real[ROW][COL], int row, int col);
实战效果:(模拟踩雷)
设置标签