C语言实现经典游戏扫雷
目录
C语言实现经典游戏——扫雷!
扫雷游戏 是一款大众类的益智小游戏,于1992年发行。
游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷。我们可以通过C语言编程来实现游戏。我们可以把文件代码分别分在三个不同的文件下,game.h:头文件,game.c:用来具体完成函数代码,test.c:主要写逻辑函数。
写扫雷程序刚开始很多人可能没有思绪,我们可以先思考输入一个坐标而屏幕显示是否有雷,或者显示这个点的附近有几个雷
仔细思考我们可以想到可以用两个数组完成,一个数组存放当,一个数组用来显示。当玩家输入坐标后,需判断这个坐标是有有雷然后把它信息存放在另一个数组显示出来。
int get_num(int x,int y)//雷的坐标
{
return rand() % (y - x + 1) + x;//x-y的随机数
}
void set_mine(char mine[ROWS][COLS])//初始化雷
{
int x = 0;
int y = 0;
int i = LEI;
srand((unsigned)time(NULL));
while (i)
{
x = get_num(1, 9);
y = get_num(1, 9);
if (mine[x][y] == '0')
{
mine[x][y] = '1';
i--;
}
}
}
雷的问题解决了,剩下的问题就好办了,开始时我们可以设置一个菜单函数供玩家选择是否进行游戏。
void menu()
{
printf("**********************************\n");
printf("******** 1.PLAY *************\n");
printf("******** 0.EXIT *************\n");
printf("**********************************\n");
}
当玩家开始玩游戏前,我们需要把两个数组进行初始化:
void init_game(char mine[ROWS][COLS], char show[ROWS][COLS])//数组初始化
{
memset(mine, '0', ROWS*COLS*sizeof(char));
set_mine(mine);//初始化雷的位置
memset(show, '*', ROWS*COLS*sizeof(char));
}
然后我们可以把界面的数组打印出来(不要把雷的数组打印出来
)
void display(char show[ROWS][COLS])//打印数组
{
int i = 0;
int j = 0;
// for (i = 0; i < ROWS; i++)
// {
//
// for (j = 0; j < COLS; j++)
// {
// printf(" %c ", mine[i][j]);
//
// }
// printf("\n");
// }
printf(" ");
for (i = 1; i < COLS - 1; i++)
{
printf(" %d ", i);
}
printf("\n");
for (i = 1; i < ROWS-1; i++)
{
printf("%d ", i);
for (j = 1; j < COLS - 1; j++)
{
printf(" %c ", show[i][j]);
}
printf("\n");
}
}
下一步就是进行扫雷了,扫雷时我们需要判断是否猜到
void sweep(char mine[ROWS][COLS], char show[ROWS][COLS])//开始扫雷
{
int x = 0;
int y = 0;
int i = (ROWS-2)*(COLS-2)-LEI;
while (i)
{
printf("请输入坐标:");
scanf("%d%d", &x, &y);
int ret = get_lei_nums(mine, x, y);
if ((x > 0 && x<ROWS - 1) && (y > 0 && y<COLS-1))
{
if (mine[x][y] == '1')
{
printf("您炸了,游戏结束\n");
return;
}
else
{
show[x][y]=ret+'0';
display(show);
i--;
}
}
else
{
printf("您输入的坐标不合法");
}
}
printf("Win!!!!!!!!!!!\n");
}
int get_lei_nums(char mine[ROWS][COLS],int x,int y)//判断附近雷的个数
{
int count = 0;
if (mine[x - 1][y - 1] == '1')
count++;
if (mine[x][y - 1] == '1')
count++;
if (mine[x + 1][y - 1] == '1')
count++;
if (mine[x - 1][y] == '1')
count++;
if (mine[x + 1][y] == '1')
count++;
if (mine[x - 1][y + 1] == '1')
count++;
if (mine[x][y + 1] == '1')
count++;
if (mine[x + 1][y + 1] == '1')
count++;
return count;
}
game.h
#define _CRT_SECURE_NO_WARNINGS 1
#ifndef __GAME__H__
#define __GAME__H__
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
enum CH
{
EXIT,
PLAY
};
#define ROWS 11
#define COLS 11
#define LEI 10
void set_mine(char mine[ROWS][COLS]);
void init_game(char mine[ROWS][COLS], char show[ROWS][COLS]);
void display(char show[ROWS][COLS]);
void play_game(char mine[ROWS][COLS], char show[ROWS][COLS]);
void sweep(char mine[ROWS][COLS], char show[ROWS][COLS]);
int get_lei_nums(char mine[ROWS][COLS], int x,int y);
#endif
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
int get_num(int x,int y)//雷的坐标
{
return rand() % (y - x + 1) + x;//x-y的随机数
}
void set_mine(char mine[ROWS][COLS])//初始化雷
{
int x = 0;
int y = 0;
int i = LEI;
srand((unsigned)time(NULL));
while (i)
{
x = get_num(1, 9);
y = get_num(1, 9);
if (mine[x][y] == '0')
{
mine[x][y] = '1';
i--;
}
}
}
void init_game(char mine[ROWS][COLS], char show[ROWS][COLS])//数组初始化
{
memset(mine, '0', ROWS*COLS*sizeof(char));
set_mine(mine);//初始化雷的位置
memset(show, '*', ROWS*COLS*sizeof(char));
}
void display(char show[ROWS][COLS])
{
int i = 0;
int j = 0;
// for (i = 0; i < ROWS; i++)
// {
//
// for (j = 0; j < COLS; j++)
// {
// printf(" %c ", mine[i][j]);
//
// }
// printf("\n");
// }
printf(" ");
for (i = 1; i < COLS - 1; i++)
{
printf(" %d ", i);
}
printf("\n");
for (i = 1; i < ROWS-1; i++)
{
printf("%d ", i);
for (j = 1; j < COLS - 1; j++)
{
printf(" %c ", show[i][j]);
}
printf("\n");
}
}
void sweep(char mine[ROWS][COLS], char show[ROWS][COLS])//开始扫雷
{
int x = 0;
int y = 0;
int i = (ROWS-2)*(COLS-2)-LEI;
while (i)
{
printf("请输入坐标:");
scanf("%d%d", &x, &y);
int ret = get_lei_nums(mine, x, y);
if ((x > 0 && x<ROWS - 1) && (y > 0 && y<COLS-1))
{
if (mine[x][y] == '1')
{
printf("您炸了,游戏结束\n");
return;
}
else
{
show[x][y]=ret+'0';
display(show);
i--;
}
}
else
{
printf("您输入的坐标不合法");
}
}
printf("Win!!!!!!!!!!!\n");
}
int get_lei_nums(char mine[ROWS][COLS],int x,int y)//判断附近雷的个数
{
int count = 0;
if (mine[x - 1][y - 1] == '1')
count++;
if (mine[x][y - 1] == '1')
count++;
if (mine[x + 1][y - 1] == '1')
count++;
if (mine[x - 1][y] == '1')
count++;
if (mine[x + 1][y] == '1')
count++;
if (mine[x - 1][y + 1] == '1')
count++;
if (mine[x][y + 1] == '1')
count++;
if (mine[x + 1][y + 1] == '1')
count++;
return count;
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void play_game()
{
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
init_game(mine, show);
display(show);
sweep(mine, show);
}
void menu()
{
printf("**********************************\n");
printf("******** 1.PLAY *************\n");
printf("******** 0.EXIT *************\n");
printf("**********************************\n");
}
void game()
{
int input = 0;
menu();
printf("请选择:");
scanf("%d", &input);
while (input)
{
switch (input)
{
case PLAY:
play_game();
break;
case EXIT:
break;
}
menu();
printf("请选择:");
scanf("%d", &input);
}
}
int main()
{
game();
system("pause");
return 0;
}
注意:
1.在选择是否游戏时引用了枚举类型,方便以后对程序扩展
enum CH
{
EXIT,
PLAY
};
2.在设置雷的坐标时是随机数生成的。需要用到下面两条语句,头函数是<time.h>
srand((unsigned)time(NULL));
rand() % (y - x + 1) + x;//生成x-y的随机数。
3.再把数组初始化时用到了memset()函数:头文件是<string.h>
memset(mine, '0', ROWS*COLS*sizeof(char));
数组 要赋值的值 数组的大小