用C实现的扫雷小游戏

来源:互联网 发布:人工智能最好的大学 编辑:程序博客网 时间:2024/05/17 01:14
#ifndef __GAME_H__#define __GAME_H__#define ROWS 10#define COLS 10#define default_count 10void display(char arr[ROWS+2][COLS+2],int rows,int cols);void display(char arr[ROWS+2][COLS+2],int rows,int cols);void set_mine(char arr[ROWS+2][COLS+2],int rows,int cols);int get_mine_count(char arr[ROWS+2][COLS+2],int x,int y);void get_null(char arr[ROWS+2][COLS+2],int x,int y);void move_mine(char arr[ROWS+2][COLS+2],int rows,int cols);int win_game(char arr[ROWS+2][COLS+2],int x,int y);#endif __GAME_H__#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>#include "game.h"#include <stdlib.h>#include <time.h>#include <string.h>void menu(){//打印菜单。printf("            扫雷            \n");printf("****************************\n");printf("********   1.play>  ********\n");printf("********   0.exit>  ********\n");printf("****************************\n");}enum Option{EXIT,  //枚举开始退出PLAY};//打印游戏坐标void display(char arr[ROWS+2][COLS+2],int rows,int cols){int i = 0;int j = 0;int k = 0;printf("    ");for(k = 1;k<=rows;k++){printf("%-d  ",k);}printf("\n");printf("\n");for(i = 1;i<=rows;i++){printf("%2d  ",i);for(j = 1;j<=cols;j++){printf("%c  ",arr[i][j]);}printf("\n");printf("\n");    }}//随机函数放置雷void set_mine(char arr[ROWS+2][COLS+2],int rows,int cols){int count = 0;count = default_count;while(count){int i = rand()%ROWS+1;int j = rand()%COLS+1;if(arr[i][j] == '0'){arr[i][j] = '1';count--;}     }}//统计周围雷的数量int get_mine_count(char arr[ROWS+2][COLS+2],int x,int y){ return (arr[x-1][y-1]-'0'+arr[x][y-1]-'0'+arr[x+1][y-1]-'0'+arr[x+1][y]-'0'+         arr[x+1][y+1]-'0'+arr[x][y+1]-'0'+arr[x-1][y+1]-'0'+arr[x-1][y]-'0');}//第一下点中雷的话移走void move_mine(char arr[ROWS+2][COLS+2],int rows,int cols){    int count = 1;while(count){int i = rand()%ROWS+1;int j = rand()%COLS+1;if(arr[i][j] == '0'){arr[i][j] = '1';count--;}}}//检查游戏进度int win_game(char arr[ROWS+2][COLS+2],int rows,int cols){int i = 0;int j = 0;int count = 0;for(i = 1;i<=rows;i++){for(j = 1;j<=cols;j++){if(arr[i][j] == '*')count++;}    }return count;}void game(){int i = 0;int j = 0;int x = 0;int y = 0;int win = 0;char mine[ROWS+2][COLS+2] = {0};  char show[ROWS+2][COLS+2] = {0};srand((unsigned int)time(NULL));memset(mine,'0',sizeof(char)*(ROWS+2)*(COLS+2)); //初始化为0memset(show,'*',sizeof(char)*(ROWS+2)*(COLS+2));display(show,ROWS,COLS); //打印坐标set_mine(mine,ROWS,COLS);//布雷display(mine,ROWS,COLS);  //展示雷的位置while(1){printf("请输入坐标:");scanf("%d%d",&x,&y);++j;if(mine[x][y] == '1'){if(j == 1){mine[x][y] = '0';show[x][y] = '0';move_mine(mine,x,y);//第一个是雷移走//display(mine,ROWS,COLS);}else{printf("噗!!!炸死了\n");break;}}else{int count = 0;count = get_mine_count(mine,x,y);show[x][y] = count+'0';//计算放置位置周围的雷数for(i = x-1;i<=x+1;i++){if(mine[i][y-1]=='0')show[i][y-1] = '0';}i = 0;for(i = x-1;i<=x+1;i+=2){if(mine[i][y]=='0')show[i][y] = '0';}i = 0;for(i = x-1;i<=x+1;i++){if(mine[i][y+1]=='0')show[i][y+1] = '0';}}display(show,ROWS,COLS);if(win_game(show,ROWS,COLS) == default_count)//计算游戏进程函数break;}if(win_game(show,ROWS,COLS) == default_count)printf("恭喜你排雷成功\n");}int main(){int input = 0;do{menu();printf("请选择:");scanf("%d",&input);switch(input){case EXIT:break;case PLAY:game();break;default:printf("输入错误,请重新输入\n");break;}}while(input);return 0;}



这个小游戏的实现主要在于理清游戏逻辑,对各个步骤封装成函数,一步一步来实现。

1.游戏菜单函数,因为每一次的游戏执行都要打印菜单,所以把它封装成函数放在首部。而且用一个swtich语句加枚举类型,使得游戏逻辑更加清晰,把所有的游戏步骤都放在game()函数中。把所有游戏过程都放在while中,因为要连续玩只是在退出的时候退出。

2.game()函数里边封装游戏所有逻辑步骤,display()函数,打印游戏坐标,使用简单的双重for循环实现,为了使玩家填写坐标的时候更加方便添加数字坐标,一目了然。接下来是游戏的随机雷,在最开始define 定义雷的个数和游戏坐标的大小增加游戏的可玩性和可移植性。 用srand随机函数产生坐标,就是随机雷了,为了后期统计雷数方便我们用0代表非雷。再就是统计一个非雷周围的雷数,用了函数get_mine()函数,对周围八个坐标是雷的金星加和返回。

3.为了增加游戏的可玩性,所以觉定如果第一个是雷的话移走,所以就用到了函数move_mine()还是用随机函数srand把第一个雷随机移到其他非雷处。最后是检查排掉的雷的个数是check_win()函数,利用双重for循环记录所有*的个数来判断游戏进程。

4。最后回到游戏的主逻辑部分,设置变量的来接收函数的返回值,进行判断,为了游戏更好的测试,排除不定性,我们打印出雷阵来测试效率更高,反复调试用F10一步步确定整个游戏的过程都是我们所设计的那样来执行的。最后完成这个小游戏。


0 0
原创粉丝点击