赞
踩
本系列博文仅为博主个人学习笔记,通过博客理清学习思路用于复习。如有记述不周到的地方请谅解;如能指出,更加感谢。
扫雷游戏它是由row * col的格子拼起来,游戏规则:这款游戏的玩法是在一个99(初级),1616(中级),16*30(高级),或自定义大小的方块矩阵中随机布置一定量的地雷(初级为10个,中级为40个,高级为99个)。由玩家逐个翻开方块,以找出所有地雷为最终游戏目标。如果玩家翻开的方块有地雷,则游戏结束。
// 本程序采用两个二维数组存储棋盘 char mine[row][col] ; // 用来存储雷的信息 char show[row][col] ; // 用来展示当前玩家展开棋盘的信息 ```![扫雷](https://img-blog.csdnimg.cn/20210429214450977.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMjQ5NzYw,size_16,color_FFFFFF,t_70) ## 1.该如何用c语言实现这样一款游戏 ---- 代码分析 该游戏主要步骤就是两步1.如何设置雷2.如何排查雷。 1. 设置雷 ```c //随机产生一对坐标,存储在x ,y当中 int x = rand() % row + 1 ; int y = rand() % col + 1 ; //若存储地雷的二维数组该坐标不是雷,则将其设置成雷 if(mine[x][y] == '0'){ mine[x][y] = '1'; }
2、排查雷
玩家输入一对坐标,对坐标进行判断是否是合法输入,如果是合法输入,则继续判断该坐标对应的mine数组是否为雷,若为雷,则结束游戏,提示玩家您不小心踩到啦雷,游戏结束;若没有踩到雷,则继续游戏,并将该格子对应坐标周围所有的雷数展示出来,玩家继续挖雷,直到所有的不是雷的格子被玩家全部挖出,则游戏结束,提示玩家获胜。
playerMove(char mine[][COLS],char show[][COLS], int row, int col) { int x = 0; int y = 0; int count = 0; while (count < row * col - NUM_MINE) { printf("请输入您要排除的雷的坐标:"); scanf("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (mine[x][y] == '1') { printf("不好意思,你被炸啦,游戏结束\n"); break; } /*int ret = count_mine(mine, x, y); show[x][y] = ret + '0'; count++;*/ else { //对代码的递归优化,详细请见下文,功能是将与输入坐标周围8个格子所有不是雷的展开,提高用户游戏体验。 OpenMine(mine, show, row, col, x, y, &count); //打印当前游戏棋盘的状态 Display(show, row, col); } } else { printf("输入坐标非法:\n"); } } if (count >= (col * row - NUM_MINE)) { printf("恭喜您,扫雷成功\n"); } }
本程序分为三个文件 game.h 头文件,game.c 具体实现文件,test.c测试文件 。
#include <stdio.h> #define NUM_MINE 10 #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 //initial array 1. mine 2. show initial(char board[][COLS], int rows, int col,char set); //display 1. mine 2. show Display(char board[][COLS], int row, int col); //set mine set_mine(char mine[][COLS], int row, int col); //remove mine playerMove(char mine[][COLS],char show[][COLS], int row, int col);
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" //initial array 1. mine 2. show initial(char board[][COLS], int rows, int cols,char set) { for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { board[i][j] = set; } } } //display 1. mine 2. show Display(char board[][COLS], int row, int col) { printf("------扫雷游戏------\n"); for (int i = 0; i <= row; i++) { printf("%d ", i); } 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"); } //set mine set_mine(char board[][COLS], int row, int col) { int count = NUM_MINE; while (count) { int x = rand() % row + 1; int y = rand() % col + 1; if (board[x][y] == '0') { board[x][y] = '1'; count--; } } } //count mine by every grid static int count_mine(char mine[][COLS], int x, int y) { return mine[x - 1][y - 1] + mine[x-1][y] + mine[x - 1][y + 1] + mine[x][y - 1] + mine[x][y + 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] - '0' * 8; } //open mines one by one static void OpenMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y,int *level) { (*level)++; if (mine[x][y] == '1' || x < 1 || x > row || y < 1 || y > col || show[x][y] != '*') { (*level)--; return; } int ret = count_mine(mine, x, y); //调用统计雷个数的函数。 if (!ret) { show[x][y] = ' '; //要确定周围8个坐标本身不是雷,才递归它周围的。 OpenMine(mine, show, row, col, x - 1, y - 1,level); OpenMine(mine, show, row, col, x, y - 1,level); OpenMine(mine, show, row, col, x + 1, y - 1, level); OpenMine(mine, show, row, col, x - 1, y, level); OpenMine(mine, show, row, col, x + 1, y, level); OpenMine(mine, show, row, col, x - 1, y + 1, level); OpenMine(mine, show, row, col, x, y + 1, level); OpenMine(mine, show, row, col, x + 1, y + 1, level); } else { show[x][y] = ret + '0'; //显示该坐标周围有几个雷 return; } } //playermoving playerMove(char mine[][COLS],char show[][COLS], int row, int col) { int x = 0; int y = 0; int count = 0; while (count < row * col - NUM_MINE) { printf("请输入您要排除的雷的坐标:"); scanf("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (mine[x][y] == '1') { printf("不好意思,你被炸啦,游戏结束\n"); break; } /*int ret = count_mine(mine, x, y); show[x][y] = ret + '0'; count++;*/ else { OpenMine(mine, show, row, col, x, y, &count); Display(show, row, col); } } else { printf("输入坐标非法:\n"); } } if (count >= (col * row - NUM_MINE)) { printf("恭喜您,扫雷成功\n"); } }
#include "game.h" #include <stdlib.h> #include <time.h> void menu() { printf("*********************\n"); printf("******1. play *****\n"); printf("******0. exit *****\n"); printf("*********************\n"); } void game() { //定义两数组来存储数据 char mine[ROWS][COLS] = { 0 }; char show[ROWS][COLS] = { 0 }; //initial array initial(mine, ROWS, COLS,'0'); initial(show, ROWS, COLS,'*'); //Display(mine, ROW, COL); Display(show, ROW, COL); //set mine set_mine(mine, ROW, COL); playerMove(mine,show, ROW, COL); Display(mine, ROW, COL); } int main() { srand((unsigned)time(NULL)); int input = 0; do { menu(); printf("请选择:> "); scanf("%d",&input); switch (input) { case 1: game(); break; case 0: printf("退出\n"); break; default : printf("输入错误\n"); break; } } while (input); return 0; }
此处重点来说说openmine 这个函数,功能是一个一个的展开周围的8个格子,若该格子的坐标不合法,曾访问过或者是雷,则满足条件,return返回,若满足以上条件均不满足,则将该格子周围的雷数进行统计,若统计数不为零,则不将其周围格子进行展开,只将其格子周围的雷数展示出来;若统计数为0,则将该格子置为‘ ’,并进入下一个格子 的判断:将该格子的左上,左,左下,正上,正下,右上,右,右下8个格子继续进行以上三个判断,并用一个变量count计数,依次判断,直到所有相邻的格子判断完毕。若count < row * col - 雷数, 则玩家继续输入坐标进行下一轮判断。重复上述动作,在玩家没有踩到雷的情况下正常,直到 count < row* col - 雷数不满足条件,跳出循环 ,提示玩家胜利。
游戏界面展示
扫雷游戏还是比较简单的,希望同学们一起努力,从c语言青铜慢慢变成c语言王者,我们一起在山顶相遇。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。