一:游戏介绍

《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输

c语言扫雷语句(C语言扫雷游戏)(1)

二:C语言实现扫雷(1)新建文件

整个游戏需要三个文件,第一个是头文件“Saolei.h”用于声明函数,宏定义等,第二个是“Saolei_game.c”用于实现头文件中所声明函数的功能,第三个是"Saolei_test.c"用于控制整个游戏逻辑。

c语言扫雷语句(C语言扫雷游戏)(2)

(2)逻辑流程

第一:打印主体逻辑框架

c语言扫雷语句(C语言扫雷游戏)(3)

第二:设置雷场

  1. 对于排雷游戏,使用鼠标点击某个小方格后,如果有雷当场暴毙,如果没有累,则会显示出此格子上下左右及四个对角出的格子上总的雷的数目。所以定义一个9×9的字符数组mine,用字符1表示此处有雷,用字符0表示此处无雷。所以定义mine数组,并初始化显示如下
  2. 上述中有一个问题,我们实际玩扫雷游戏的时候,开始界面是空白的,但是如果这样一上来就把mine数组打印出来,岂不是已经排完了吗?所以我们必须还需要一个相同的数组,这个数组的每个元素类似于一个“遮罩”,在遮罩下面到底是雷还是什么无从得知,只有用户输入坐标后才能揭晓,而这个数组也同时作为排雷数组。于是建立一个同大小的show数组,全部元素被初始化为"*"。
  3. 两个数组建立好之后,不得不考虑另外一个问题。我们在排雷时需要判断某个方格周围的类的数目,那么势必就要访问到这些方格,对于中间的方格没有问题,但是对于边缘的方格(如下),在访问其右侧方格时就会出现越界的问题最先想到的方法就是访问之前判断其有效性,但是这样的方法想一想就觉得麻烦。所以我们可以这样:我们的棋盘是9×9,但是我们设置为11×11,也就是多出两行和两列,这样我们在访问时就不会产生越界,反正那多出的两行和两列的元素上一定是没有雷的。

所以我们在宏定义时,要这样定义

c语言扫雷语句(C语言扫雷游戏)(4)

所以部分代码需要修改,这里需要注意打印时是要从(1,1)到(9,9)

c语言扫雷语句(C语言扫雷游戏)(5)

4. 最后,用户排雷时是需要坐标的,但是由于格子太大,不容易一眼看出坐标,所以我们可以加入行号和列号来进行辅助

c语言扫雷语句(C语言扫雷游戏)(6)

第三:布雷我们定义字符1表示此处有雷,字符0表示此处无雷。一般的扫雷游戏均有初级,中级和高级等游戏难度分级,其难度取决于雷的数目,数目越多难度越大。所以在布置雷时首先要决定需要布置多少个雷,然后进入一个循环,利用系统生成随机坐标,判断生成坐标对应的位置是否有雷,如果没有雷,则放置一颗雷同时将类的数目减小1,如果有雷则继续生成下一个随机坐标重复上述过程。直到最后的类全部放置完毕。

c语言扫雷语句(C语言扫雷游戏)(7)

c语言扫雷语句(C语言扫雷游戏)(8)

第四:排雷

  1. 排雷时有一个十分重要的操作就是如果用户没有踩到雷,需要统计该位置周围的雷的数目,我们将其封装为一个函数,参数除了数组外需要接受一个坐标周围对应的坐标关系如下想要探查其周围雷的数目固然可以使用逐个遍历比较的方式进行的,但是这里还有一种更为简单的方法,由于数组里存储的全部都是字符0或字符1,而数字1=字符1-字符0,数字2=字符2-字符0·····依次类推。于是我们可以将其周围的字符全部加起来减去8个字符0就是所得雷的个数

c语言扫雷语句(C语言扫雷游戏)(9)

2. 排查雷时,该函数就要同时传入mine数组和show数组,进入函数后,让用户输入坐标,根据用户输入的坐标对应到雷场中进行判断,如果输入的位置有雷当场炸死,如果没有雷则调用函数探查周围雷的信息并返回,将此信息传递给同位置的show数组,并显示给用户,如下

c语言扫雷语句(C语言扫雷游戏)(10)

c语言扫雷语句(C语言扫雷游戏)(11)

c语言扫雷语句(C语言扫雷游戏)(12)

3. 最后一点,上述还没有实现的一点就是什么时候判断为赢了,9×9的方格有10个雷,则剩余的71个位置没有雷。所以定义个变量win,每次没有碰到雷时win ,循环结束条件是当win>9×9-10。

c语言扫雷语句(C语言扫雷游戏)(13)

三:全部代码

头文件

#pragma once #include <stdio.h>; #include <stdlib.h>; #include <time.h>; #define Row 9 #define Col 9 #define Rows Row 2 #define Cols Col 2 #define EASY_COUNT 10 void initBoard(char board[Rows][Cols],int rows,int cols,char set);//初始化放雷数组 void displayBoard(char board[Rows][Cols],int row,int col);//显示 void setMine(char board[Rows][Cols], int row,int col);//设置雷 void FindMine(char mine[Rows][Cols], char show[Rows][Cols], int row, int col);//找雷 int get_mine_count(char board[Rows][Cols], int x, int y); 123456789101112131415

函数实现文件

#include "Saolei.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; for (i = 0; i <= col; i )//列号 { printf("%d ", i); } printf("\n"); for (i = 0; i <= col; i )//列号下的横线 { printf("—"); } printf("\n"); for (int i = 1; i <=row; i ) { printf("%d", i); printf("|"); for (int j = 1; j <=col; j ) { printf("%c ", board[i][j]); } printf("\n"); } } void setMine(char board[Rows][Cols], int row, int col) { int count = EASY_COUNT;//count个雷 while (count) { int x = rand() % row 1; int y = rand() % col 1;//范围为1-9; if (board[x][y] == '0') { board[x][y] = '1'; count--; } } } int get_mine_count(char board[Rows][Cols], int x, int y) { return board[x - 1][y - 1] board[x - 1][y] board[x - 1][y 1] board[x][y - 1] board[x][y 1] board[x 1][y - 1] board[x 1][y] board[x 1][y 1] - 8 * '0'; } void FindMine(char mine[Rows][Cols], char show[Rows][Cols], int row, int col) { int x, y = 0; int win = 0; while (win<row*col-EASY_COUNT) { printf("请输入你的坐标\n"); scanf_s("%d%d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { //坐标合法 if (mine[x][y] == '1')//遇到雷了 { printf("You Lose!\n"); displayBoard(mine, row, col); break; } else//不是雷,统计信息 { int count = get_mine_count(mine, x, y);//得到该位置周围的雷的个数 show[x][y] = count '0'; displayBoard(show, row, col); win ; } } else { printf("输入有误,重新输入\n"); } } if (win == row * col - EASY_COUNT) { printf("you win\n"); } } 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108

逻辑控制文件

#define _CRT_SECURE_NO_WARNINGS 1 #include "Saolei.h"; void menu() { printf("*************************\n"); printf("**********1.play*********\n"); printf("**********0.exit*********\n"); printf("*************************\n"); } void game() { printf("游戏开始\n"); char mine[Rows][Cols] = {0};//放雷 char show[Rows][Cols] = { 0 };//排雷 initBoard(mine, Rows, Cols,'0');//初始化放雷数组 initBoard(show, Rows, Cols,'*');//初始化排雷数组 printf("\n"); printf("雷场如下\n"); displayBoard(show, Row, Col);//显示 setMine(mine, Row, Col);//报雷 FindMine(mine, show, Row, Col);//排雷 } void test() { srand((unsigned int)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); } int main() { test(); return 0; }

如果需要获取工程文件,请关注公众号【0与1】,并正在后台回复【C语言】

,