用c语言编写扫雷游戏:
1.扫雷的基本功能
2.第一次扫,不被炸死
3.当周围没有雷的时候可以向外延伸扩展。
完成这个游戏需要构造几个函数:
a.初始化雷盘;
b.打印雷盘;
c.设雷的数目;
d.统计点击之处雷的个数;
e.重新布雷;
f.扩展式排雷
game.h //头文件部分
#ifndef __GAME_H__
#define __GAME_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#define ROW 12 //实际行数
#define COL 12 //实际列数
#define ROWS (ROW-2)//雷盘行数
#define COLS (COL-2)//雷盘列数
#define MINE 10 //雷数
void init_board(char arr[ROW][COL],char set,int row,int col);//初始化棋盘
void print_board(char arr[ROW][COL],int row,int col);//打印棋盘
void set_mine(char arr[ROW][COL],int row,int col);//布雷
int get_count(char arr[ROW][COL],int x,int y);//统计点击之处雷的个数
void reset_mine(char arr[ROW][COL],int x,int y,int row,int col);//重新布雷
void expend(char arr1[ROW][COL], int x, int y, int *ret, char arr2[ROW][COL]);//扩展排雷
#endif //__GAME_H__
game.c //游戏部分
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void init_board(char arr[ROW][COL],char set,int row,int col)//初始化棋盘
{
memset(arr,set,row*col*sizeof(arr[0][0]));//memset初始化,括号内为:数组名,初始化目标,初始化字节数
}
void print_board(char arr[ROW][COL],int row,int col)//打印棋盘
{
int i = 0;
int j = 0;
printf(" ");
for(i=1;i<row-1;i++)//打印列号
{
printf("%d ",i);
}
printf("\n");
for(i=1;i<row-1;i++)
{
printf("%2d ",i);
for(j=1;j<col-1;j++)
{
printf("%c ",arr[i][j]);
}
printf("\n");
}
}
void set_mine(char arr[ROW][COL],int row,int col)
{
int count = MINE;
int x = 0;
int y = 0;
while(count>0)
{
x = rand() % ROWS+1;//产生随机数
y = rand() % COLS+1;
if(arr[x][y]=='0')
{
arr[x][y]='1';
count--;
}
}
}
void reset_mine(char arr[ROW][COL],int x,int y,int row,int col)
{
int count = 1;;
arr[x][y] = '0';
while (count)
{
int i = rand() % ROWS + 1;
int j = rand() % COLS + 1;
if ((arr[i][j] != '1') && (i != x) && (j != y))
{
arr[i][j] = '1';
count--;
}
}
}
int get_count(char arr[ROW][COL],int x,int y)
{
return arr[x-1][y-1]
+arr[x+1][y+1]+arr[x][y-1]
+arr[x][y+1]+arr[x-1][y]
+arr[x+1][y-1]+arr[x+1][y]
+arr[x-1][y+1]-8*'0';//雷周围8个数,返回雷数int值
}
void expend(char arr1[ROW][COL],int x,int y,int* ret,char arr2[ROW][COL])
{
int i = 0;
int j = 0;
int count = 0;//点击之处周围雷数
if(arr2[x][y]=='*')//未被排雷
{
(*ret)++;
count = get_count(arr1,x,y);
if(count!=0)//周围雷数不为0
{
arr2[x][y]=count+'0';//显示雷数
}
else // 周围八个位置扩展排雷
{
arr2[x][y]='0';
for(i=-1;i<=1;i++)
{
for(j=-1;j<=1;j++)
{
if((x+i>=1)&&(x+i<=ROWS)&&(y+j>=1)&&(y+j<=COLS))
{
if(i!=0||j!=0)
expend(arr1,x+i,y+j,ret,arr2);
}
}
}
}
}
}
test.c //测试部分
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu()
{
printf("***********************\n");
printf("***** 1.play *****\n");
printf("***** 0.exit *****\n");
printf("***********************\n");
}
void game()
{
int x = 0;
int y = 0;
int ret = 0;//找到非雷的次数
char mine[ROW][COL] = {0};
char show[ROW][COL] = {0};
init_board(mine,'0',ROW,COL);
init_board(show,'*',ROW,COL);
set_mine(mine,ROW,COL);//布雷
print_board(show,ROW,COL);
printf("\n");
print_board(mine,ROW,COL);//打印棋盘
while(ret<(ROWS*COLS-MINE)) //开始排雷
{
printf("请输入坐标(x,y)-> ");
scanf("%d%d",&x,&y);
if(((x>=1)&&(x<=ROWS))&&(y>=1)&&(y<=COLS))//输入有效坐标
{
if(mine[x][y]=='1')//所选位置有雷
{
if(ret!=0)
{
printf("很遗憾,你被炸死了!\n");
print_board(mine,ROW,COL);
return;
}
else
{
mine[x][y]='0';
reset_mine(mine,x,y,ROWS,COLS);//重新布雷
expend(mine,x,y,&ret,show);
}
}
else
{
expend(mine,x,y,&ret,show);
}
print_board(show,ROW,COL);
}
else
{
printf("输入的坐标无效,请重新输入!\n");
}
}
if(ret=(ROWS*COLS-MINE))
{
printf("恭喜你,排雷成功!\n");
}
}
void test()
{
int input = 0;
srand((unsigned)time(NULL));//初始化时间种子
do
{
menu();
printf("请输入->");
scanf("%d",&input);
switch(input)
{
case 1:game();
break;
case 0:
break;
default:printf("输入错误,请重新输入!\n");
break;
}
}while(input);
}
int main()
{
test();
system("pause");
return 0;
}
游戏结果为:
#ifndef _GAME_H_
#endif // _GAME_H_
作用:防止头文件被重复引用
代码中用 memset函数初始化雷盘,
这里扩展一下此函数 memset函数原型为:
void *memset( void *dest,int c,size_t count );//扩号中分别为要初始化的目标,初始化内容,初始化个数
更多内容可以在MSDN上查询。
如代码:
#include <stdio.h>
int main( void )
{
char buffer[] = "This is a test of the memset function";
printf( "Before: %s\n", buffer );
memset( buffer, '*', 4 );
printf( "After: %s\n", buffer );
}
结果如图:
当我们写代码的时候会或多或少的遇到编译上的问题,这是我们不要急着去问老师或者度娘,应该自己先试着调试,这样下次就会避免再犯同类错误。vs2008上调试方法有:快捷键f5开始调试,f10 逐过程调试,f11逐语句调试。同样可以在窗口里看不同变量的变化,这些编译器里都有,我们应该熟练使用。
最后祝大家天天开心,下次再会!