扫雷游戏是根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。
1、首先应该设置两张表。
一个埋雷表(字符0未埋雷 , ‘字符1已埋雷),一个用户可见表。
注意:两张表应该设置为12 * 12,中间10 * 10可用(方便判断每一个数周围雷的个数)。
2、设置雷位置。
用rand随机生成雷的位置(本程序设置20个雷)。
3、用户排雷:
(1) 判断输入坐标是否合法。
(2)判断该位置是否已被占用
4、计算(x,y)周围雷的个数。
1、第一次下子,不炸死。
2、坐标周围没雷,可以实现展开。
使用多文件实现。一个头文件game.h,两个源文件main.c和game.c
在头文件对函数和宏进行声明
#ifndef __GAME_H__
#define __GAME_H__
#include
#include
#include
#include
#pragma warning (disable:4996 )
#define ROW 12
#define COL 12
#define NUM 20
void Game();
void SetMines(char board[][COL], int rol, int col,int *x_p, int *y_p);
void ShowBoard(char board[][COL], int row, int col);
int GetCount(char board[][COL], int x, int y);
#endif
实现菜单函数和游戏的选择和退出。
#include "game.h"
void Menu(){
printf("*******************************\n");
printf("*****欢迎来到我的扫雷游戏 *****\n");
printf("*******************************\n");
printf("**** 1.Play 2.Exit *****\n");
printf("*******************************\n");
printf("Please Select:");
}
int main(){
int quit = 0;
while(!quit) {
Menu();
int select = 0;
scanf("%d", &select);
switch (select){
case 1:
Game();
break;
case 2:
quit = 1;
break;
default:
printf("你选择有错误,请重新输入!");
break;
}
}
printf("Bye Bye!");
system("pause");
return 0;
}
#include "game.h"
游戏函数:
(1)声明并初始化雷表和用户表的表;
(2)初始化雷的位置和指定没有雷的位置坐标。
(3)用户排雷。用户输入是否合法,该是否位置被占用,如果初次遇到雷则和指定没有雷的位置进行交换。
(4)统计(x,y)周围雷的个数。
/‘0’-->未埋雷 ‘1’-->已埋雷
void Game(){
system("cls");
srand((unsigned long)time(NULL)); //种随机数种子
char mine_board[ROW][COL];
char show_board[ROW][COL];
memset(mine_board, '0', sizeof(mine_board)); //初始化表
memset(show_board, '*', sizeof(show_board));
int no_x;
int no_y;
SetMines(mine_board, ROW, COL, &no_x,&no_y); //设置雷函数声明
int x = 0;
int y = 0;
int times = 100 - NUM;
do{
//ShowBoard(mine_board, ROW, COL);
ShowBoard(show_board, ROW, COL);
printf("PLease Enter :" ); //用户排雷
scanf("%d %d", &x, &y);
if (x<1 || x>10 || y<1 || y>10){ //用户输入是否合法
printf("你输入的坐标有误,请重新输入!\n");
continue;
}
if (show_board[x] [y] != '*'){ //该位置是否被占用
printf("该位置已经被排除,请重新输入!\n");
continue;
}
if (mine_board[x][y] == '1'){
if (times == 80){ //初次不被炸
mine_board[x][y] = '0';
mine_board[no_x][no_y] = '1';
}
else{
printf("Game Over!\n");
ShowBoard(mine_board, ROW, COL);
break;
}
}
//统计x和y周围雷的个数
int count = GetCount(mine_board, x, y);
show_board[x][y] = count + '0';
//注意show_board是字符型,count是整型,最后显示字符型。
//‘0’的Ascll是48,0的Ascll是0.
times--;
} while (times>0);
}
设置雷的合法位置和个数,找到一个没有雷的坐标用于和第一次玩有雷的位置交换,保证第一次下子,不炸死。
void SetMines(char board[][COL], int rol, int col,int *no_x,int *no_y){ //设置雷的位置.传两个指针,记录没有雷的位置
int count = NUM;
while (count > 0){
//随即产生坐标(x,y)埋雷
int x = rand() % (rol - 2)+1; //设置中间10行,并随机产生一行x
int y = rand() % (col- 2)+1; //设置中间10列, 并随机产生一列y
if (board[x][y] == '0'){ //如果此坐标未埋雷,则设置雷
count--;
board[x][y] ='1';
}
}
//第i行,第j列没雷,和第一次有雷的位置交换
int i = 1;
for (; i <= 10; i++){
int j = 1;
for (j=1; j <= 10; j++){
if (board[i][j] == '0'){
*no_x = i;
*no_y = j;
return;
}
}
}
}
打印棋盘
void ShowBoard(char board[][COL], int row, int col){
int i = 1;
for (; i <= 10; i++){
printf(" %d", i);
}
printf("\n");
for (i = 1; i <= 11; i++){
printf("-----");
}
printf("\n");
for (i=1; i <= 10; i++){
printf("%2d |", i);
int j = 1;
for (; j <= 10; j++){
printf(" %c |", board[i][j]);
}
printf("\n");
int k = 1;
for (k=1; k <= 11; k++){
printf("-----");
}
printf("\n");
}
}
使用GetCount函数计算(x,y)周围雷的个数
int GetCount(char board[][COL], int x, int y){
return board[x - 1][y - 1] + board[x][y - 1] + board[x+1][y -1] + board[x - 1][y] +\
board[x + 1][y] + board[x - 1][y + 1] + board[x][y + 1] + board[x + 1][y + 1]-8*'0'; //统计周围雷个数
}