C语言实现扫雷小游戏(设定游戏简易程度,实现空白,实现跳过第一次选中雷)

来源:互联网 发布:mac怎么打dota2 编辑:程序博客网 时间:2024/05/28 01:35

首先,演示一下:


要写出扫雷,首先要对扫雷有一个基本的认识。

分析一下:

(1):初始化棋盘

初始化棋盘分为两步:第一步,我们给一个全为“*”的棋盘;第二步,我们考虑到在计算雷周围数目的数目的时候,位于边界的位置不好求,所以我们在棋盘的每一边都增加1行或者1列。


(2)布雷:

布雷我们主要是在随机产生的位置上布雷,所以我们就要用到rand()。

(3):打印棋盘

打印棋盘也分为两步:第一步,我们要计算点开一个格子以后周围雷的数目;

第二步,如果我们点开的格子是0,就用递归调用显示他周围的一片空白区域。


(4):判断

如果踩中雷,我们就说结束了;如果排完雷,我们就说排雷成功了。

这四步呢,一定要捋清楚!

在这里呢,我用到了两个菜单,其实原理很简单,只是把雷的个数改变了



程序代码:

game.h

#ifndef __GAME_H__  #define __GAME_H__  #define COLS 11  #define ROWS 11  #define COL (COLS-2)  #define ROW (ROWS-2)   #include <stdio.h>  #include <stdlib.h>  #include <time.h>  #include <string.h>#pragma warning (disable:4996)void init_board(char mine[ROWS][COLS], char set, int row, int col);//初始化棋盘 void set_mine(char mine[ROWS][COLS],int max, int x, int y);//布雷void display(char mine[ROWS][COLS], int row, int col);//打印棋盘void get_mine_count(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);//统计周围雷的数目以及为0时的处理#endif//__GAME_H__  


game.c

#include"game.h"  void init_board(char mine[ROWS][COLS], char set, int row, int col){memset(mine, set, row*col*sizeof(mine[0][0]));//初始化棋盘,set表示对棋盘布置0还是*}void set_mine(char mine[ROWS][COLS], int max,int x, int y)//布雷定义雷的个数,随机产生一个位置布雷,依次递减{int count = max;while (count>0){int X = rand() % 9 + 1;int Y = rand() % 9 + 1;if ((X != x) && (Y != y) && mine[X][Y] == '0')//避免新的雷步到了原来的位置上{mine[X][Y] = '1';count--;}}}void display(char mine[ROWS][COLS], int row, int col)//打印棋盘,为了美观在这里要注意空格{int x = 0;int y = 0;printf("  ");for (x = 1; x <= 9; x++){printf("%d ", x);}printf("\n");for (x = 1; x <= 9; x++){printf("%d ", x);for (y = 1; y <= 9; y++){printf("%c ", mine[x][y]);}printf("\n");}}void get_mine_count(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)  {//玩家选择了一个位置以后,如果该位置为'0',就把空格赋给它,表示空白。然后通过递归显示周围的一片if ((mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] + mine[x - 1][y] - 7 * '0') == '0'){show[x][y] = ' ';if (((x - 1>=1) && (x - 1<=ROW)) && ((y - 1>=1) && (y - 1<=COL)) && (show[x - 1][y - 1] == '*'))get_mine_count(mine, show, x - 1, y - 1);if (((x >= 1) && (x <= ROW)) && ((y - 1 >= 1) && (y - 1 <= COL)) && (show[x][y - 1] == '*'))get_mine_count(mine, show, x, y - 1);if (((x + 1 >= 1) && (x + 1 <= ROW)) && ((y - 1 >= 1) && (y - 1 <= COL)) && (show[x + 1][y - 1] == '*'))get_mine_count(mine, show, x + 1, y - 1);if (((x + 1 >= 1) && (x + 1 <= ROW)) && ((y >= 1) && (y <= COL)) && (show[x + 1][y] == '*'))get_mine_count(mine, show, x + 1, y);if (((x + 1 >= 1) && (x + 1 <= ROW)) && ((y + 1 >= 1) && (y + 1 <= COL)) && (show[x + 1][y + 1] == '*'))get_mine_count(mine, show, x + 1, y + 1);if (((x >= 1) && (x <= ROW)) && ((y + 1 >= 1) && (y + 1 <= COL)) && (show[x][y + 1] == '*'))get_mine_count(mine, show, x, y + 1);if (((x - 1 >= 1) && (x - 1 <= ROW)) && ((y + 1 >= 1) && (y + 1 <= COL)) && (show[x - 1][y + 1] == '*'))get_mine_count(mine, show, x - 1, y + 1);if (((x - 1 >= 1) && (x - 1 <= ROW)) && ((y >= 1) && (y <= COL)) && (show[x - 1][y] == '*'))get_mine_count(mine, show, x - 1, y);}else show[x][y] = (mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y]+ mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] + mine[x - 1][y] - 7 * '0');}




test.c

#include"game.h"  void menu()//菜单{printf("**********************************\n");printf("********* 1.play  0.exit**********\n");printf("**********************************\n");}void second_menu()//二级菜单显示{printf("**********************************\n");printf("             1.简单               \n");printf("             2.中等               \n");printf("             3.困难               \n");printf("**********************************\n");}void game(num)//游戏环节{   int max = num;//在这里实现了改变雷的个数,也是选择困难度传参的地方int blank = COL*ROW - max;int x = 0;int y = 0;char mine[ROWS][COLS] = { 0 };char show[ROWS][COLS] = { 0 };init_board(mine, '0', ROWS, COLS);//初始化11*11棋盘为0,考虑到最角落统计周围8格的总数init_board(show, '*', ROWS, COLS);//初始化9*9的棋盘为*display(show, ROWS, COLS);//打印棋盘while (blank)//循环条件是你排除的只剩下雷了{int i = 1;printf("请输入一个坐标:");scanf("%d%d", &x, &y);set_mine(mine, max, x, y);//输入坐标以后在布雷,就免去了玩家第一次输入就踩雷if (((x >= 1) && (x <= ROW)) && ((y >= 1) && (y <= COL))){ if (mine[x][y] == '1'){printf("你选中了雷!\n");break;}else{get_mine_count(mine, show, x, y);//统计周围雷的数目以及打开0时的处理}blank--;display(show, ROWS, COLS);//display(mine, ROWS, COLS);//测试雷数,也就是直接看结果}else{printf("你输入的坐标有误!\n");}}if (blank == 0){printf("德玛西亚!\n");}}void test()//对菜单进行选择{int input = 0;srand((unsigned int)time(NULL));do{menu();printf("请选择开始还是退出:");scanf("%d", &input);switch (input){case 1:{  int input = 0;  do{  second_menu();  int easy_mine_num = 10;  int medium_mine_num = 15;  int difficult_mine_num = 20;  printf("请选择困难度:");  scanf("%d", &input);  switch (input)  {  case 1:  game(easy_mine_num);  input = 0;  break;  case 2:  game(medium_mine_num);  input = 0;  break;  case 3:  game(difficult_mine_num);  input = 0;  break;  default:  printf("输入有误,重新开始:\n");  }  } while (input);}break;case 0:break;default:printf("您的选择有误,请重新选择1:\n");}} while (input);}int main(){test();system("pause");return 0;}




1 0
原创粉丝点击