咱们来用C语言写一个扫雷游戏吧。
棋盘格子是9*9,默认设置10个雷
先设想粗糙的游戏画面
扫雷游戏大体设计、思想架构和代码实现
(1)test.c文件
调用菜单函数实现进入游戏和退出游戏功能的界面,
调用游戏函数嵌套调用初始化棋盘函数,打印棋盘界面函数,布置雷函数,排查雷函数。
代码实现:
#include"game.h"
void menu()
{
printf("**********************\n");
printf("***** 1.开始游戏 *****\n");
printf("***** 0.退出游戏 *****\n");
printf("**********************\n");
}
void game()
{
char mine[ROWS][COLS];
char show[ROWS][COLS];
InitBoard(mine, ROWS, COLS, '0');// 先初始化第一个mine数组,最开始全是'0'
InitBoard(show, ROWS, COLS, '*');// 然后初始化第二个show数组,全是 '*'。
DisplayBoard(show, ROW, COL);
SetMine(mine, ROW, COL);
FindMine(mine, show, ROW, COL);
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
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;
}
(2)game.h游戏头文件
代码实现:
game.h:
#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 cow);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
(3)game.c源文件
1.初始化棋盘函数, 11*11的二维数组board[rows][cols]。(为什么是11行11列后面的GetMineCount函数有说明)
先初始化第一个mine数组,最开始全是‘0’,
然后初始化第二个show数组,全是’ * '。
#include"game.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;
}
}
}
2.打印棋盘界面函数,9*9的二维数组board[rows][cols]棋盘界面,
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
printf("-------扫雷游戏--------\n");
for (i = 0; i <=col; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);
for (j = 1; j <=col; j++)//要注意*的行数和列数,还有和坐标对齐
{
printf("%c ", board[i][j]);
}
printf("\n");
}
}
3.布置雷函数。实现随机10个雷分布在元素全为0的9*9的二维数组board[rows][cols]中,将1~9生成随机的坐标布置成雷。棋盘本来全是0,所以雷赋值为1。
void SetMine(char board[ROWS][COLS], int row, int col)
{
int count = EASY_COUNT;
while (count)
{
int x = 1+rand() % row;//行坐标的随机数
int y = 1+rand() % col;//列坐标的随机数
if (board[x][y] == '0')
{
board[x][y] = '1';
count--;
}
}
}
随机数生成可以观看文章猜数字有详细说明
http://t.csdn.cn/KvfjN
4.排查雷函数。
思路:总空间9*9-10个雷=71,我们要排除完71个空间,排雷成功,游戏结束。
GetMineCount函数,实现返回坐标(x,y)周围雷的个数。(这也是为什么最初的数组要设置成11行11列,因为会超过9行9列范围找雷个数)
数字字符转换成数字规律是,数字字符相减转换成ASCLL码相减。
例如’1’-‘0’=49-48=1 ‘2’-‘0’=50-48=2
所以:
周围雷的个数==除了(x,y)的所有坐标对应的字符’0’或’1’相加-8字符’0’
例如要找这个四个角的周围的雷就会超出99,所以我们实际范围是11*11
当我们用下标显示时,实际是这样的:
代码实现
game.c:
//static保证了该函数仅在game.c文件中实现
static 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 x = 0;
int y = 0;
int win = 0;
while (win < row * col - EASY_COUNT)
{
printf("请输入要查找的坐标:>");
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] == '1')
{
printf("你被炸死了,游戏结束\n");
DisplayBoard(mine, ROW, COL);
break;
}
else
{
int count = GetMineCount(mine, x, y);
show[x][y] = count + '0';
DisplayBoard(show, ROW, COL);
win++;
}
}
else
{
printf("坐标非法,请重新输入\n");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,排雷成功\n ");
DisplayBoard(mine, row, col);
}
}
写代码过程中遇到的问题: