当前位置:网站首页>排雷游戏(解析)
排雷游戏(解析)
2022-07-24 03:39:00 【学Java的冬瓜】
目录
前言
扫雷是我高一上信息技术课,老师让我们自由操作时经常玩的游戏,突然感觉好怀念。
今天就用C语言实现扫雷游戏。
正式开始前先理一下扫雷需要哪些功能,哪些步骤
大致思路:
1、打印菜单
2、创建数组 + 数组初始化
3、打印棋盘
4、布置雷
5、排查雷+ 6、判断胜利+ 打印棋盘
一、代码示例及解析
1、game.h
头文件、define定义常量、函数名
需要一个9*9的数组来存放雷(存放雷的数组元素不能改变),还需要一个相同的数组来存放排查雷的信息,但为了防止排查雷时,访问处于边角位置的目标坐标的周围坐标导致数组越界,所以就设置成11*11的数组,而展示时只展示数组下标为1-9的元素
代码如下(示例):
#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 mine[ROWS][COLS], int row, int col);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
int Count_Around_mine(char mine[ROWS][COLS], int x, int y);
void Spread_Show(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);
int Iswin(char show[ROWS][COLS], int row, int col);
2、test.c
test.c包含menu,game,main三个函数
代码如下(示例):
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void menu()
{
printf("**********************\n");
printf("******* 1.play *******\n");
printf("******* 0.exit *******\n");
printf("**********************\n");
}
// mine数组中:0--非雷 1--雷
void game()
{
char mine[ROWS][COLS] = { 0 };
char show[COLS][COLS] = { 0 };
//初始化
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
DisplayBoard(show, ROW, COL);
//设置雷
SetMine(mine, ROW, COL);
//DisplayBoard(mine, ROW, COL);
//排查雷
FindMine(mine, show, ROW, COL);
}
int main()
{
srand((unsigned int)time(NULL));
//设置随机数的生成起点
int input = 0;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("游戏结束\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
}
while (input);
return 0;
}2、game.c
2.1、初始化
传入一个初始化内容的参数,就可以初始化得到不同结果,即该函数可以复用
代码如下(示例):
//初始化
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.2、打印棋盘
注意格式
代码如下(示例):
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
printf(" --------扫雷-------\n");
int i = 0;
int j = 0;
for (j = 0; j <= col; j++)
{
if (j == 0)
printf("|");
if (j < col)
printf("%d ", j);
else
printf("%d|\n", j);
}
for (i = 1; i <= row; i++)
{
printf("|%d ", i);
for (j = 1; j <= col; j++)
{
if (j < col)
printf("%c ", board[i][j]);
else
printf("%c|\n", board[i][j]);
}
}
printf(" --------扫雷-------\n");
}2.3、布置雷
用rand函数,test.c中用srand函数设置随机数的生成起点
代码如下(示例):
//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col)
{
int count = EASY_COUNT;
while (count)
{
int x = rand() % row + 1;// 1--9
int y = rand() % col + 1;
if (mine[x][y] == '0')
{
mine[x][y] = '1';
count--;
}
}
}2.4、排查雷
排查需要多次输入坐标,所以为循环,每次输入后判断1、是否被排查过,2、是否是雷,3、是否周围有雷,每次循环结束前判断是否胜利
代码如下(示例):
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("请输入坐标,如:1 1\n");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (show[x][y] != '*') //防止输入坐标重复问题
{
printf("坐标已排查,请重新输入其他坐标\n");
}
else
{
if (mine[x][y] == '0')
{
int count = Count_Around_mine(mine, x, y);
//展开一片的功能
//1.自己不是雷 2.周围没有雷 3.自己未被排查过
if (count == 0)
{
Spread_Show(mine, show, x, y);
}
else
{
show[x][y] = count + '0';
}
DisplayBoard(show, ROW, COL);
}
else
{
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine, ROW, COL);
break;
}
}
}
else
{
printf("坐标非法,请重新输入:>\n");
}
if (Iswin(show, ROW, COL) == EASY_COUNT)
{
printf("恭喜你,扫雷成功!\n");
break;
}
}
}2.5、展开功能
当输入的坐标(x,y)满足:1、未被排查,2、不是雷,3、周围没有雷,x,y处元素令为' ',就可以展开去看该坐标周围8个坐标,如x-1,y-1也满足周围8个坐标没有雷,就可以递归,设置递归的停止的条件是,当x-1,y-1周围8个坐标有雷时x-1,y-1这个位置元素就是周围雷的个数
代码如下(示例):
//展开一片(周围坐标无雷时)
void Spread_Show(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
int i = 0;
int j = 0;
int count = 0;
if (x >= 1 && x <= ROW && y >= 1 && y <= COL) //防止深层递归时数组越界
{
for (i = -1; i <= 1; i++) //判断x,y周围是否有雷
{
for (j = -1; j <= 1; j++)
{
if (mine[x + i][y + j] == '0')
{
count = Count_Around_mine(mine, x+i, y+j);
if (count == 0)
{
if (show[x + i][y + j] == '*')// ' '和'0'都不会进入循环,即该数未被排查过
{ //当 i=x,j=y时show[x][y]已经令为'0',不会进入循环
show[x + i][y + j] = ' ';
Spread_Show(mine, show, x + i, y + j);
}
}
else if(count>0)//当x,y周围即x+i,y+j的周围有雷时,x+i,y+j 在show中给出数字字符,结束递归
{ //排除count变成负数的情况
show[x + i][y + j] = count + '0';
}
}
}
}
}
}2.6、判断胜利
遍历,若剩余*的数量等于设置好的雷的数量,就胜利
代码如下(示例):
//排雷胜利判断
Iswin(char show[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
int show_board_mine_count = 0;
for (i = 1; i <= row; i++)
{
for (j = 1; j <= col; j++)
{
if (show[i][j] == '*')
show_board_mine_count++;
}
}
return show_board_mine_count;
}2.7、统计目标坐标的周围雷的个数
代码如下(示例):
//计算周围坐标是雷的个数
int Count_Around_mine(char mine[ROWS][COLS], int x, int y)
{
//法一
int i = 0;
int j = 0;
int count = 0;
for (i = -1; i <= 1; i++)
{
for (j = -1; j <= 1; j++)
{
count += mine[x + i][y + j]-'0';
}
}
return count;
法二
//return (mine[x - 1][y] +
// mine[x - 1][y - 1] +
// mine[x][y - 1] +
// mine[x + 1][y - 1] +
// mine[x + 1][y] +
// mine[x + 1][y + 1] +
// mine[x][y + 1] +
// mine[x - 1][y + 1] - 8 * '0');
}二、成果演示
1、被炸死

2、展开一片

3、扫雷成功

总结
该篇用C语言实现扫雷,实现了一部分功能,由于时间原因,还差一个标记功能未实现,思路是:在FindMine函数中创建一个属于menu的子菜单,功能可为1.排查雷,2.标记雷,3.取消标记,0.退出。模块化设计的思路真的很重要,能用函数经量不要写在主函数中
边栏推荐
- Interviewer: if the order is not paid within 30 minutes after it is generated, it will be automatically cancelled. How to realize it?
- QT custom class uses custom parametric signals and slots
- Svn: e00002: can't convert string from 'UTF-8' to native encoding problem solving
- 一篇搞定CAS,深度讲解,面试实践必备
- 什么是IMU?
- Simulink code generation: variable subsystem and its code
- How to write selenium's testng.xml
- Expressions régulières \ \ B \ \ b compréhension de l'appariement des limites des mots
- Data Lake: introduction to Apache Hudi
- Embedded system transplantation [5] - Cross compilation tool chain
猜你喜欢

Redis transaction learning

Interviewer: if the order is not paid within 30 minutes after it is generated, it will be automatically cancelled. How to realize it?

uniapp H5打包后本地图片无法显示问题

C language classic exercises (2) - "bubble sort"“

What is IMU?

JS Array isaarray () Type of

Okaleido tiger NFT is about to log in to the binance NFT platform. Are you looking forward to it?

错误代码0x80004005

【云原生】快速了解Kubernetes

How does the small program mall refine the operation of members?
随机推荐
C dynamic memory management details
Bingbing learning notes: basic operation of vim tool
Cve-2022-29464 wso2 file upload vulnerability
B. Eastern Exhibition- Codeforces Round #703 (Div. 2)
Do you know how to do interface testing well?
Preliminary exploration of Flink principle and flow batch integration API (II) V2
Why do some people write code so complicated?
4. Hezhou air32f103_ LCD
Lagrange polynomial
C文件操作详解
IO stream sorting
[JS reverse hundred examples] a public resource trading network, reverse analysis of announcement URL parameters
H7-tool serial port offline burning operation instructions, support TTL serial port, RS232 and RS485 (2022-06-30)
Native JS realizes the acquisition and operation of DOM
Read and understand the advantages of the LAAS scheme of elephant swap
C language classic exercises (2) - "bubble sort"“
Paper reading: the perfect match: 3D point cloud matching with smoothed densities
Exttestngireporterlistener all codes
Using global data to realize data sharing in wechat applet
[wepy2.0] installation