📒前言
😜扫雷游戏想必是大家学习C语言写的第一个200+行的代码!
😎那时写完整个程序的自己是不是非常有成就感?
😲今天乔乔也是刚写完这个游戏,虽然有点成就感,但是还是觉得不够好玩,于是爆改了一番!
今天乔乔就把源码无偿分享给大家,如果大家觉得还有什么可以改进,别忘了在评论区留言噢~
你的提议也许会在未来的扫雷游戏Pro Max中加入!
一、游戏异同
经典款的扫雷游戏想必大家都玩过,如果没有玩过的小伙伴也可以点击下方链接尝试一下!
由于乔乔初学的知识有限,先简单讲一下和经典款的异同:
1、都可以选择自定义地雷数量但无法自定义行列数,默认9行9列,可通过修改game.h中ROW和COL值修改
2、都可以选择难度系数,但是无法改变雷区面积
3、添加误输入后可重新输入功能
4、只能够通过输入坐标排查且第一颗可能是雷
5、输入排查坐标时输入0 0重置游戏
6、0代表不是地雷,1代表地雷
7、无标记雷功能,无切换夜间模式、无切换英文模式
虽然可以看出与经典款相比,乔乔的这款功能非常有限,但是相比于老师要求萌新们掌握的那款扫雷还是有些许改进滴!
二、游戏源码
注意事项:乔乔的这款使用的开发工具是微软的Visual Studio 2022
头文件:
game.h
#pragma once
#include <stdio.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
//初始化棋盘
void InitBoard(char arr[ROWS][COLS], int rows, int cols, char set);
//打印棋盘
void DisplayBoard(char arr[ROWS][COLS], int row, int col);
//设置难度系数
int Difficulty();
//布置雷
void SetMine(char arr[ROWS][COLS], int row, int col,int num);
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col,int num);
//游戏核心程序
void MainGame(char mine[ROWS][COLS], char show[ROWS][COLS], int num);
源文件:
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include "game.h"
void menu()
{
printf("** 欢迎来到扫雷游戏 **\n");
printf("************************\n");
printf("***** 1、开始游戏 ******\n");
printf("***** 0、退出游戏 ******\n");
printf("************************\n");
printf("************************\n");
}
//模式选择菜单
void ModeMenu()
{
printf("*********************************\n");
printf("******* 0、自定义雷的数量 *******\n");
printf("******* 1、选择难度系数 *******\n");
printf("*********************************\n");
printf("请选择模式:");
}
void game()
{
//定义棋盘
char mine[ROWS][COLS];
char show[ROWS][COLS];
//初始化棋盘
InitBoard(mine, ROWS, COLS,'0');//'0'
InitBoard(show, ROWS, COLS,'*');//'*'
//打印棋盘
//DisplayBoard(show, ROW, COL);
//DisplayBoard(mine, ROW, COL);
int p = 0;
int j = 0;
do
{
ModeMenu();
scanf("%d", &p);
int num = 0;
j = p != 0 && p != 1;
switch (p)
{
case 1:
num = Difficulty();
//布置雷
MainGame(mine,show,num);
break;
case 0:
do
{
printf("请输入雷的数量:");
scanf("%d", &num);
int n = num > ROW * COL;
if (n == 0)
{
MainGame(mine, show, num);
}
else
{
printf("数量超出限制范围,重新输入吧!\n");
}
} while (num > ROW * COL);
break;
default:
printf("想乱选?不可能!\n");
}
} while (j);
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
//打印菜单界面
do
{
menu();
printf("请输入:");
scanf("%d", &input);
switch (input)
{
case 1:
printf("扫雷游戏开始喽!\n");
printf("有以下两种模式供君选择:\n");
game();//进入游戏
break;
case 0:
printf("拜拜!");
break;
default:
printf("想乱选?不可能!\n");
break;
}
} while (input);
}
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
#include <stdlib.h>
#include <time.h>
//初始化棋盘
void InitBoard(char arr[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
//控制行
for (i = 0; i < rows; i++)
{
int j = 0;
//控制列
for (j = 0; j < cols; j++)
{
arr[i][j] = set;
}
}
}
//打印棋盘
void DisplayBoard(char arr[ROWS][COLS], int row, int col)
{
int i = 1;
for (i = 0; i <= row; i++)
{
printf("%d ", i);//先打印列号
}
printf("\n");
for (i = 1; i <= row; i++)
{
int j = 1;
printf("%d ", i);//再打印行号
for (j = 1; j <= col; j++)
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
//难度系数菜单
void DifficultyMenu()
{
printf("********** 难度系数 **********\n");
printf("*********************************\n");
printf(" 1、超级无敌简单模式(01-20个雷)\n");
printf(" 2、有丢丢简单模式(21-40个雷) \n");
printf(" 3、有丢丢困难模式(41-60个雷) \n");
printf(" 4、一踩就死模式(60个雷以上) \n");
printf("*********************************\n");
}
//难度系数
int Difficulty()
{
int i = 0;
int j = 0;
int n = 0;
do
{
DifficultyMenu();
printf("请输入难度系数:");
scanf("%d", &i);
n = i < 1 || i > 4;
switch (i)
{
case 1:
j = rand() % 20 + 1;//1-20
break;
case 2:
j = rand() % 20 + 21;//21-40
break;
case 3:
j = rand() % 20 + 41;//41-60
break;
case 4:
j = rand() % 20 + 61;//60以上
break;
default:
printf("输入错误,请重新输入!\n");
break;
}
} while (n);
return j;
}
//布置雷
void SetMine(char arr[ROWS][COLS], int row, int col,int num)
{
int count = num;
while (count)
{
//布置雷
int x = rand() % row + 1;//1~9
int y = rand() % col + 1;//1~9
if (arr[x][y] == '0')
{
arr[x][y] = '1';
count--;
}
}
}
//计算周围八格总和
int GetMineCount(char mine[ROWS][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] - 8 * '0';
}
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col,int num)
{
int x = 0;
int y = 0;
int win = 0;
while (win<ROW*COL- num)
{
printf("请输入要排查的坐标:");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("哦豁,踩到雷了!\n");
DisplayBoard(mine, ROW, COL);;
break;
}
else
{
int n = GetMineCount(mine, x, y);
show[x][y] = n + '0';
DisplayBoard(show, ROW, COL);
win++;
}
}
else if (x == 0 && y == 0)
{
printf("回到最初的起点!\n");
main();
break;
}
else
{
printf("坐标有误,请重新输入!\n");
}
}
if (win == ROW * COL - num)
{
printf("恭喜你,排雷成功!\n");
DisplayBoard(mine, ROW, COL);
}
}
void MainGame(char mine[ROWS][COLS], char show[ROWS][COLS],int num)
{
//布置雷
SetMine(mine, ROW, COL, num);
printf("总共地雷数量:%d\n", num);
//DisplayBoard(mine, ROW, COL);//开透视挂
DisplayBoard(show, ROW, COL);
//排查雷
FindMine(mine, show, ROW, COL, num);
}
📝总结
对于和乔乔一样的C语言新手来说,扫雷是熟练掌握C语言的路上必须通过的一关,因为它几乎集合了我们前面所学习的所有知识,包括分支循环语句、数组和函数等等超级重要的内容。可以说,如果你能够理解并且尝试写出比乔乔更好的扫雷代码,那么恭喜你!你就已经将前面的知识理解透彻了!
当然,学习C语言的路还很漫长,后续我们还会学习像贪吃蛇这类更多有趣的小游戏。我也期望大家能够在原有代码的基础上作出一些个性化的改进,写一份独属于你自己的小游戏!这也是我学习C语言的乐趣和成就感的来源!
如果大家能够在乔乔写的小游戏上提出不足或者建议,欢迎在评论区留言,我保证在看到以后会一一回复!
不过,在你打开扫雷小游戏之前,乔乔必须得提醒你:
抵制不良游戏, 拒绝盗版游戏 。
注意自我保护, 谨防受骗上当。
适度游戏益脑, 沉迷游戏伤身。
合理安排时间, 享受健康生活。
😍如果点赞超20,下一期我们就出详细教程!