扫雷 (防止第一次被炸死和展开)

来源:互联网 发布:unity3d弯折 编辑:程序博客网 时间:2024/06/15 12:12

写了一个扫雷10*10格子,实现

 1.第一次不会被炸死 。

2.选择坐标后,实现周围没有雷格子的展开。

注:下文中提到  “ 区域 ” 均可理解为  “ 坐标 ”

Mine Clearance.h(头文件)

#ifndef __Mine_Clearance__#define __Mine_Clearance__#define _CRT_SECURE_NO_WARNINGS#include  <stdio.h>#include  <stdlib.h>#include  <time.h>#define M  9                                                      //定义炸弹数量。#define ROW 11                                                    //定义棋盘大小。#define COL 11void init(char mine[ROW][COL], char show[ROW][COL]);            //声明game.c中的函数。void displayboard(char show[ROW][COL]);void displaymine(char mine[ROW][COL]);void  Set_Mine(char mine[ROW][COL], int m);void sweep_Mine(char mine[ROW][COL], int x, int y);int if_success(char mine[ROW][COL], char show[ROW][COL], int m );void prevent_first_death(char mine[ROW][COL], int x, int y);int Num_boms(char mine[ROW][COL], int x, int y);void spread(char mine[ROW][COL], char show[ROW][COL], int x, int y);#endif

game.c(函数文件)

#include "Mine Clearance.h"//printf("%3d\n", ' ');  32//printf("%3d\n", '!');  33//printf("%3d\n", '*');  42//printf("%3d\n", '0');  48//printf("%3d\n", '1');  49//void init(char mine[ROW][COL], char show[ROW][COL])     //初始化雷盘和展示盘数组,大小设置为11*11.{int i, j;for (i = 0; i < ROW-1 ; i++){for (j = 0; j < COL-1; j++)               //ROW-1只设置10*10的雷盘,数组未被初始化的部分会自动设为'0',{mine[i][j] = ' ';                 //方便之后对 边界区域的展开函数 和 雷数统函数 的调用。
show[i][j] = '*';

}}}void displayboard(char show[ROW][COL])             //向用户展示盘。{int i, j;printf("  |");for (i = 1; i <= 10; i++){printf("%d ", i);}printf("\n--|--------------------\n");for (i = 0; i < ROW-1; i++){printf("%2d|", i + 1);for (j = 0; j < COL-1; j++){printf("%c ",show[i][j]);}printf("\n");}}void displaymine(char mine[ROW][COL])                //展示雷盘,测试时使用。 (正常游戏时在test.c中注释掉即可)。

{int i, j;printf("  |");for (i = 1; i <= 10; i++){printf("%d ", i);}printf("\n--|--------------------\n");for (i = 0; i < ROW-1; i++){printf("%2d|", i + 1);for (j = 0; j < COL-1; j++){printf("%c ", mine[i][j]);}printf("\n");}}void  Set_Mine(char mine[ROW][COL], int m)      //随机放置雷,可以通过在头文件中修改 M 的定义值从而修改 m的大小,即改变布置的雷数。
{int x, y;while (m){x = rand() % 10 + 0;    y = rand() % 10 + 0;if (mine[x][y] == ' '){mine[x][y] = '!';m--;}}m = M;}int Num_boms(char mine[ROW][COL], int x, int y)   //统计周边的雷数。{int count = 0;if (mine[x - 1][y - 1] == '!'){count++;}if (mine[x - 1][y] == '!'){count++;}if (mine[x - 1][y + 1] == '!'){count++;}if (mine[x][y + 1] == '!'){count++;}if (mine[x + 1][y + 1] == '!'){count++;}if (mine[x + 1][y] == '!'){count++;}if (mine[x + 1][y - 1] == '!'){count++;}if (mine[x][y - 1] == '!'){count++;}return count;}void spread(char mine[ROW][COL], char show[ROW][COL], const x, const y)   //扩展函数,向(x,y)周边的八个区域进行扩展。
{int ret, i, j;                                                          int a, b;                                                            a = x;b = y;if ((x >=0)                                                //x,y值得大小应在数组坐标内,不做限定的话会造成死循环,使系统崩溃。&& (x <= 9)&& (y >=0)                                                   && (y <=9)){ if (mine[x - 1][y - 1] == ' ')                        //如果该区域不是雷。{a = x - 1;b = y - 1;ret = Num_boms(mine, a, b);                     //返回以该区域为中心雷的数量。if (ret == 0)                                 //若在这八个区域中哪个区域的返回炸弹数值为0,即ret==0,{show[a][b] = ' ';                     //如果周围没有雷就向玩家展示‘ ’空格。mine[a][b] = '0';                        //将雷盘中的区域改为 ‘0’可方便测试用。
spread(mine, show, a, b);              //则将这个区域的坐标赋值个x和y,再次进行展开。}else{show[a][b] = '0' + ret;mine[a][b] = '0';}}if (mine[x][y - 1] == ' ')                                //以下的另外七个区域均相同。{a = x;b = y - 1;ret = Num_boms(mine, a, b);if (ret == 0){show[a][b] = ' ';mine[a][b] = '0';spread(mine, show, a, b);}else{show[a][b] = '0' + ret;mine[a][b] = '0';}}if (mine[x - 1][y] == ' '){a = x - 1;b = y;ret = Num_boms(mine, a, b);if (ret == 0){show[a][b] = ' ';mine[a][b] = '0';spread(mine, show, a, b);}else{show[a][b] = '0' + ret;mine[a][b] = '0';}}if (mine[x + 1][y - 1] == ' '){a = x + 1;b = y - 1;ret = Num_boms(mine, a, b);if (ret == 0){show[a][b] = ' ';mine[a][b] = '0';spread(mine, show, a, b);}else{show[a][b] = '0' + ret;mine[a][b] = '0';}}if (mine[x + 1][y] == ' '){a = x + 1;b = y;ret = Num_boms(mine, a, b);if (ret == 0){show[x + 1][y] = ' ';mine[a][b] = '0';spread(mine, show, a, b);}else{show[x + 1][y] = '0' + ret;mine[a][b] = '0';}}if (mine[x + 1][y + 1] == ' '){a = x + 1;b = y + 1;ret = Num_boms(mine, a, b);if (ret == 0){show[x + 1][y + 1] = ' ';mine[a][b] = '0';spread(mine, show, a, b);}else{show[x + 1][y + 1] = '0' + ret;mine[a][b] = '0';}}if (mine[x][y + 1] == ' '){a = x;b = y + 1;ret = Num_boms(mine, a, b);if (ret == 0){show[x][y + 1] = ' ';mine[a][b] = '0';spread(mine, show, a, b);}else{show[x][y + 1] = '0' + ret;mine[a][b] = '0';}}if (mine[x - 1][y + 1] == ' '){a = x - 1;b = y + 1;ret = Num_boms(mine, a, b);if (ret == 0){show[x - 1][y + 1] = ' ';mine[a][b] = '0';spread(mine, show, a, b);}else{show[x - 1][y + 1] = '0' + ret;mine[a][b] = '0';}}}}void sweep_Mine(char mine[ROW][COL], char show[ROW][COL],   int x, int y)   //该函数为扫雷函数:{int ret = 0;if ( mine[x][y] == ' ')                                            //玩家没有踩到雷,即展示该区域周边的雷数,如果雷数为0就显示‘ ’空格。{ret=Num_boms(mine, x, y);if (ret == 0){show[x][y] = ' ';}else{show[x][y] = '0' + ret;                           //如果有炸弹就显示炸弹的数量。}spread(mine, show, x, y);                               // 并在此调用展开函数,对周边区域进行展开。}else if(mine[x][y] == '!'){show[x][y] = mine[x][y];                             //如果玩家踩到炸弹就显示感叹号。}}void prevent_first_death(char mine[ROW][COL],int x,int y)      //防止玩家第一次被炸死。{int m, n;if(mine[x][y] == '!'){do {m = rand() % 11 + 0;n = rand() % 11 + 0;                  //如果玩家踩到雷,就重新随机一个没有雷的地方,将炸弹移动到那里。  if (mine[m][n] == ' '){mine[x][y] = ' ';             //将该区域设置为空格。mine[m][n] = '!';break;}} while (1);}}int if_success(char mine[ROW][COL], char show[ROW][COL], int m )  //判断是否输赢的函数。{int i, j,num;num = M;for (i = 0; i < ROW; i++){         for (j = 0; j < COL;j++)       { if (show[i][j]=='*')                //如果在展示棋盘上剩余 ‘*’的数量和雷数相同,那么就表示扫雷成功了!    
 { num--; }else if (show[i][j] == '!')         //如果显示盘上出现了 ‘!’说明玩家踩到了雷。         {      return 1;         }        }   }if (num == 0){return 0;}}


test.c(运行文件)

#include "Mine Clearance.h"void mune()     //界面。{printf("  \n  *******************************************************************\n");printf("  ********** Do you want to play the Mine_Clearance Game?  **********\n");printf("  ***********                                          **************\n");printf("  *************   1.play                2.exit        ***************\n");printf("  *******************************************************************\n");}game()                                         //玩游戏的函数。{char mine[ROW][COL];char show[ROW][COL] ;char spread[ROW][COL];int x, y,m;int row, col;int count=0;int ret;row = ROW;    col = COL;m = M;                               //将定义中的M赋值给 minit(mine, show, spread);Set_Mine(mine, m);    displaymine(mine);                   //在测试中使用,游戏中可注释掉。do{   displayboard(show);   count++;   printf("Please enter coordinates(x,y):");   scanf("%d %d", &x, &y);   getchar();   x = x - 1;   y= y - 1;   if (count == 1)  {prevent_first_death(mine, x, y);     }    sweep_Mine(mine, show,  x, y);   ret=if_success(mine,show,x,y);   if (ret == 1)   {   displayboard(show);   printf("\n  Sorry, you were killed by mine.\n");   break;   }   else if (ret == 0)   {   displayboard(show);   printf("\n  Congratulations! Mineclearance success.\n ");   break;   }} while (1);}int main()                              //主函数 ,菜单的选择与游戏的调用。{int n;do{mune();scanf("%d",&n);getchar();if (n == 1){game();}else if (n==2){break;}else{;}    } while (1);return 0;}
 








就这样了 不足之处望大家指出。