用C实现的扫雷小游戏

    xiaoxiao2021-12-13  36

    #ifndef __GAME_H__ #define __GAME_H__ #define ROWS 10 #define COLS 10 #define default_count 10 void 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("- ",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)); //初始化为0 memset(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一步步确定整个游戏的过程都是我们所设计的那样来执行的。最后完成这个小游戏。

    转载请注明原文地址: https://ju.6miu.com/read-949991.html

    最新回复(0)