用了用了两天时间,写了个扫雷的小程序,是不是有点慢了。不过我是真觉得用c写小东西很有意思。
PS:重新游戏那里还没开始写,后面会补上。
**
感觉最困难,花费时间最多的在棋盘中无雷周边区域显示的算法上。
**
具体程序见下:
头文件
#ifndef __SAOLEI_H
#define __SAOLEI_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<time.h>
#define X 9//棋盘大小
#define Y 9
#define LAND 10//地雷个数
//初始化
int init_game(void);
void menu_game(void);//打印菜单栏
int mode_game(void);//功能
void generate_initgame(void);//生成初始棋盘
void generate_game(void);//生成棋盘
//功能菜单
int start_game(void);//mode1开始游戏
int judge_game(int x,int y);
void explore_game(void);
void updata_game(void);//更新棋盘
void euqal_game(int x,int y);
void extend_game(int x,int y);
int judge_game(int x,int y);
void disappear_game(int x,int y);
void printnew_game(void);
void show_game(int x,int y);
int check_game(int x,int y);
void replay_game(void);//mode2开始游戏
void bye_game(void);//mode0结束游戏
#endif // __SAOLEI_H
主程序
#include "saolei.h"
int a[X][Y]={0} ;
char b[X][Y] ;
int main()
{
int mode,status;//记录用户选择什么功能
memset(b, '*', X*Y*sizeof(char));
mode = init_game();
while(1)
{
switch(mode)
{
case 1:
status = start_game();
if(status == 0) return 0;
break;
case 2: //(并未实现)
replay_game();
break;
case 0:
bye_game();
return 0;
}
}
END:
return 0;
}
主函数中具体代码
#include "saolei.h"
extern int a[X][Y];
extern char b[X][Y];
//初始化棋盘,关键是生成具体棋盘(某坐标可以显示周围地雷个数)
int init_game()
{
int i;
menu_game();//打印菜单栏
generate_initgame();//生成棋盘(看不见地雷)
generate_game();//生成原始地雷
i = mode_game();//选择功能
return i;
}
//初始化棋盘,需要显示具体信息,包括棋盘上每个点周围雷数
//1.打印菜单栏
void menu_game(void)
{
printf("*********************************\n");
printf("***********1. 开始游戏***********\n");
printf("***********2. 重新开始***********\n");
printf("***********0. 结束游戏***********\n");
printf("*********************************\n");
}
//2.生成棋盘
void generate_initgame(void)
{
printf(" 1 2 3 4 5 6 7 8 9\n");
printf(" 1 * * * * * * * * *\n");
printf(" 2 * * * * * * * * *\n");
printf(" 3 * * * * * * * * *\n");
printf(" 4 * * * * * * * * *\n");
printf(" 5 * * * * * * * * *\n");
printf(" 6 * * * * * * * * *\n");
printf(" 7 * * * * * * * * *\n");
printf(" 8 * * * * * * * * *\n");
printf(" 9 * * * * * * * * *\n");
}
// 3.生成看不见棋盘,包含具体信息,重要!
void generate_game(void)
{
int i,j,xc,yc,n;
srand((unsigned) (time(NULL)));//调用time函数来获取随机数
while (!(n == 10))//防止生成雷数少于10个
{
xc = rand()%9;
yc = rand()%9;
a[xc][yc] = 9;
// printf("%d ",a[xc][yc]);
n = 0;
for(i=0; i<X; i++)
{
for(j=0; j<Y; j++)
{
if(a[i][j] == 9)
n++;
}
}
}
//用于调试
// printf(" 1 2 3 4 5 6 7 8 9\n");
// for (i=0; i<=X-1; i++)
// {
// printf("%2d", i+1);
// for(j=0; j<=Y-1; j++)
// {
// printf("%2d", a[i][j]);
// if(j == Y-1) printf("\n");
// }
// }
explore_game();
}
// 3.1这里是实现了具体棋盘的关键程序
void explore_game(void)
{
int n=0;
int i,j;
for(i=0; i<X; i++){
for(j=0; j<Y; j++)
{
if(a[i][j] == 9)
{
if(((i-1)>=0)&((j-1)>=0)) {if(!(a[i-1][j-1]==9)) a[i-1][j-1]++;}
if(((i-1)>=0)&((j)>=0)) {if(!(a[i-1][j]==9)) a[i-1][j]++;}
if(((i-1)>=0)&((j+1)>=0)) {if(!(a[i-1][j+1]==9)) a[i-1][j+1]++;}
if(((i)>=0)&((j-1)>=0)) {if(!(a[i][j-1]==9)) a[i][j-1]++;}
if(((i)>=0)&((j+1)>=0)) {if(!(a[i][j+1]==9)) a[i][j+1]++;}
if(((i+1)>=0)&((j-1)>=0)) {if(!(a[i+1][j-1]==9)) a[i+1][j-1]++;}
if(((i+1)>=0)&((j)>=0)) {if(!(a[i+1][j]==9)) a[i+1][j]++;}
if(((i+1)>=0)&((j+1)>=0)) {if(!(a[i+1][j+1]==9)) a[i+1][j+1]++;}
n++;
//printf("n = %d,", n);
}
}
}
//if(n==10) updata_game();//生成原始棋盘(用于调试,用户不可看到)
if(n != 10) printf("棋盘生成发生错误!\n");
}
//4.选择功能
int mode_game(void)
{
int j;
while(1)
{
printf("请选择想要进行的操作:");
scanf("%d",&j);
fflush(stdin) ;
switch(j)
{
case 1: printf("开始游戏!\n");return j;
case 2: printf("重新开始游戏!\n");return j;
case 0: printf("退出游戏!\n");return j;
default: printf("输入有误,请输入1,2,3来选择相应功能!(1.开始游戏,2.重新开始,0.结束游戏)!\n");
}
}
}
//mode1:开始游戏
int start_game()
{
int x,y,status,isc;
printf("请输入坐标:");
scanf("%d %d",&x,&y);
fflush(stdin);
x=x-1;y=y-1;
//b[x][y] = a[x][y];
isc = check_game(x,y);
if(isc == 1) {
status = judge_game(x, y);
if(status == 1)
printnew_game();
else
updata_game();
}//该点并没有被探索过!,然后打印棋盘
else start_game();
return status;
}
//检测该区域是否被检测过
int check_game(int x,int y)
{
int isc = 1;
if(b[x][y] != '*')
{printf("该点已经被探索过!请重新输入!\n");isc = 0;}
return isc;
}
//检测是否踩到雷
int over_game()
{
printf("踩到地雷了!Game Over!\n");
return 0;
}
//关键!展开算法由此展开
int judge_game(int x,int y)
{
int aa = a[x][y],status;
if(aa == 9) {status = over_game();return status;}
if((x>=0)&(x<=8)&(y>=0)&(y<=8)){
switch(aa)
{
case 0:disappear_game(x,y);show_game(x,y);extend_game(x,y);break;//检测八个方向
case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:euqal_game(x,y);break;//检测八个方向
default: printf("\n未知错误!!\n");return 0;
}
status = 1;
}
return status;
}
//当检测到0,把这个值赋值'$'
void disappear_game(int x,int y)
{
b[x][y] = '$';
}
//若所选位置周围八个方向没有雷(0),把周边值给b;
void show_game(int x,int y)
{
int i ,j;
i = x;j = y;
if(((i-1)>=0)&((j-1)>=0)& (b[i-1][j-1]=='*')) b[i-1][j-1] = a[i-1][j-1];
if(((i-1)>=0)&(b[i-1][j]=='*')) b[i-1][j] = a[i-1][j];
if(((i-1)>=0)&((j+1)<=8)&(b[i-1][j+1]=='*')) b[i-1][j+1] = a[i-1][j+1];
if(((j-1)>=0)&(b[i][j-1]=='*')) b[i][j-1] = a[i][j-1];
if(((j+1)<=8)&(b[i][j+1]=='*')) b[i][j+1] = a[i][j+1];
if(((i+1)<=8)&((j-1)>=0)& (b[i+1][j-1]=='*')) b[i+1][j-1] = a[i+1][j-1];
if(((i+1)<=8)&(b[i+1][j]=='*')) b[i+1][j] = a[i+1][j];
if(((i+1)<=8)&((j+1)<=8)& (b[i+1][j+1]=='*')) b[i+1][j+1] = a[i+1][j+1];
}
//展开,若周围无雷,展开
void extend_game(int x,int y)
{
int i ,j;
i = x;j = y;
if(((i-1)>=0)&((j-1)>=0)){if(b[i-1][j-1]==0) judge_game(i-1,j-1);else euqal_game(i-1,j-1);}
if((i-1)>=0) {if(b[i-1][j]==0) judge_game(i-1,j); else euqal_game(i-1,j);}
if(((i-1)>=0)&((j+1)<=8)){if(b[i-1][j+1]==0) judge_game(i-1,j+1);else euqal_game(i-1,j+1);}
if((j-1)>=0) {if(b[i][j-1]==0) judge_game(i,j-1); else euqal_game(i,j-1);}
if((j+1)<=8) {if(b[i][j+1]==0) judge_game(i,j+1); else euqal_game(i,j+1);}
if(((i+1)<=8)&((j-1)>=0)){if(b[i+1][j-1]==0) judge_game(i+1,j-1);else euqal_game(i+1,j-1);}
if((i+1)<=8) {if(b[i+1][j]==0) judge_game(i+1,j); else euqal_game(i+1,j);}
if(((i+1)<=8)&((j+1)<=8)){if(b[i+1][j+1]==0) judge_game(i+1,j+1);else euqal_game(i+1,j+1);}
}
//把真实棋盘坐标赋值给显示棋盘
void euqal_game(int x,int y)
{
if(b[x][y] != '$')
b[x][y] = a[x][y];
}
//显示看得见的棋盘
void printnew_game()
{
char c[X][Y] = {NULL};
printf(" 1 2 3 4 5 6 7 8 9\n");
for (int i=0; i<=X-1; i++)
{
printf("%2d", i+1);
for(int j=0; j<=Y-1; j++)
{
if (b[i][j] == '*') printf("%2c", b[i][j]);
else if (b[i][j] == '$') printf("%2c", c[i][j]);//'$'表示该点处周边无雷,也就是0,这时候棋盘上显示空
else printf("%2d", b[i][j]);
if(j == Y-1) printf("\n");
}
}
}
//生成看不见的棋盘
void updata_game(void)
{
int i,j;
printf("\n 1 2 3 4 5 6 7 8 9\n");
for (i=0; i<=X-1; i++)
{
printf("%2d", i+1);
for(j=0; j<=Y-1; j++)
{
printf("%2d", a[i][j]);
if(j == Y-1) printf("\n");
}
}
}
//mode2:重新开始游戏
void replay_game(void)
{
printf("重新开始游戏!\n");
}
//mode0:结束游戏
void bye_game(void)
{
printf("成功退出游戏!\n");
}
运行结果显示