C语言小白代码实现扫雷
Posted 张同学吧
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言小白代码实现扫雷相关的知识,希望对你有一定的参考价值。
图解
假设我们的扫雷棋盘是7* 7,但实际上,我们需要一个9* 9的布雷棋盘,因为如果不扩大棋盘,统计在边界的格子的周围雷数就会非常的麻烦。因此我们可以对于用户user的棋盘,我们可以初始化为全’?’。而对于布雷mine的棋盘,我们假设0没雷,1有雷,初始化为全0,之后再随机布雷就好了。这样逻辑就很清晰。
源码
game.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#define ROW 9//小棋盘行数
#define COL 9//小棋盘列数
#define COLS COL+ 2//大棋盘行数
#define ROWS ROW+ 2//大棋盘列数
#define MINE_COUNT 10//雷的数量
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void InitBoard(char board[ROW + 2][COL + 2], int row, int col, char c);//初始化
void SetMine(char board[][COL + 2], int row, int col);//生成雷
void ShowBoard(char board[ROW + 2][COL + 2], int row, int col);//展示棋盘
void JuageMine(char user_display[ROW + 2][COL + 2], char mine[][COL + 2], int row, int col);//判断游戏结果
int GetMineCount(char board[][COL + 2], int x, int y);//获取周围雷的数量
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
extern void Game();
int main()
{
int input = 0;
srand((unsigned)time(NULL));
setvbuf(stdout, NULL, _IONBF, 0);
do
{
printf("**************************\\n");
printf("*** 1. play 0. exit ***\\n");
printf("**************************\\n");
printf("please select:");
scanf("%d", &input);
fflush(stdout);
switch (input)
{
case 1:
Game();
break;
case 0:
printf("退出游戏\\n");
input = 0;
break;
default:
printf("输入内容有误,请重新输入!\\n");
input = 999;
break;
}
} while (input);
return 0;
}
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//两个棋盘,一个用户展示,一个用于计算。
/*展示的棋盘,比计算的棋盘要小两行两列,用于解决边界问题
*/
void Game()
{
char user_display[ROWS][COLS];
char mine[ROWS][COLS];
InitBoard(user_display, ROWS, COLS, '?');
InitBoard(mine, ROWS, COLS, '0');
ShowBoard(user_display, ROW, COL);
SetMine(mine, ROW, COL);
JuageMine(user_display, mine, ROW, COL);
}
void InitBoard(char board[ROWS][COLS], int row, int col, char c)//初始化
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
board[i][j] = c;
}
}
}
void SetMine(char board[][COL+2],int row,int col)//生成雷
{
int mine_count = MINE_COUNT;
while (mine_count > 0) {
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y]=='0')
{
board[x][y] = '1';
mine_count--;
}
}
}
void ShowBoard(char board[ROW+2][COL+2],int row,int col)
{
printf("----------------扫雷游戏--------------\\n");
for (int i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf(" \\n");
for (int j = 1; j <= row; j++)
{
printf("%d ", j);
for (int i = 1; i <= col; i++)
{
printf("%c ", board[j][i]);
}
printf("\\n");
}
printf("\\n");
}
int GetMineCount(char board[][COL + 2], 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 JuageMine(char user_display[ROW+2][COL+2],char mine[][COL+2],int row,int col)
{
int step_count = 0;
while (step_count < row * col-MINE_COUNT)
{
printf("please enter x,y");
fflush(stdout);
int x, y;
scanf("%d,%d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
//是雷
printf("你死了,游戏结束\\n");
ShowBoard(mine, ROW, COL);
break;
}
else
{
//不是雷
int mine_count=GetMineCount(mine,x,y);
user_display[x][y] = mine_count + '0';
ShowBoard(user_display, ROW, COL);
step_count++;
}
}
else
{
printf("输入坐标有错,请重新输入.\\n");
}
}
if (step_count == ROW * COL - MINE_COUNT)
{
printf("你赢了!\\n");
ShowBoard(mine, ROW, COL);
}
}
代码解释
大致思路
1.初始化两个棋盘,给用户展示的棋盘,一个是代码计算是否有雷的棋盘
1.2给用户展示的棋盘全为 ‘?’
1.3字符全部初始化为字符 ‘0’
2.给代码初始化雷区
2.1随机初始化雷区
3.给用户展示棋盘
4.采集用户输入,进行判断。
4.1踩雷,游戏结束
4.2没踩雷,计算当前位置周围8个格雷的位置。并且判断步数是否和没有雷的格子数量相同:如果相同,那么胜利,如果不同,那么继续走
核心部分
扫雷最核心的功能就是JuageMine:
代码的注释都写在下面了
void JuageMine(char user_display[ROW+2][COL+2],char mine[][COL+2],
int row,int col)
{
int step_count = 0;//记录步数
while (step_count < row * col-MINE_COUNT)
{//row * col-MINE_COUNT是你游戏胜利需要走的步数
printf("please enter x,y");//输入坐标
fflush(stdout);
int x, y;
scanf("%d,%d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{//先判断坐标是否合法
if (mine[x][y] == '1')
{
//如果坐标内容为1,那么是雷
printf("你死了,游戏结束\\n");
ShowBoard(mine, ROW, COL);
//向用户展示你的雷在哪
break;
}
else
{
//否则不是雷
int mine_count=GetMineCount(mine,x,y);
//计算周围雷的个数
user_display[x][y] = mine_count + '0';
//把数字通过+0的ASCLL码变为字符
ShowBoard(user_display, ROW, COL);
step_count++;//步进
}
}
else
{
printf("输入坐标有错,请重新输入.\\n");
}
}
if (step_count == ROW * COL - MINE_COUNT)
{
printf("你赢了!\\n");
ShowBoard(mine, ROW, COL);
}
}
int GetMineCount(char board[][COL + 2], 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';
}
以上是关于C语言小白代码实现扫雷的主要内容,如果未能解决你的问题,请参考以下文章