C语言实现扫雷小游戏(扩展版)

Neysa ·
更新时间:2024-11-13
· 1453 次阅读

本文实例为大家分享了C语言实现扫雷小游戏的具体代码,供大家参考,具体内容如下

实现的拓展功能如下:

1.设置游戏难度等级
2.保证玩家在第一把踩雷后不被炸死
3.若排雷的地方无雷,自动扩展到有雷的周围,并给出雷数
4.标记(相当于扫雷游戏中的插旗子)
5.取消标记

分析:

1.用二维字符数组mine[ROWS][COLS]来存储雷,现在我们用字符1来表示有雷,字符0表示无雷。用二维字符数组show[ROWS][COLS]将所有的元素初始化为*,并打印作为展现给玩家的。同时用show数组来表示对应的mine数组中周围雷即字符0的个数。
对于边缘的格子无法计算雷的个数,因此需再增加2行2列,防止数组越界。
2.游戏难度等级的设置即就是雷的个数和棋盘大小不同,即就是Putmine中传的COUNT(雷数)不同,棋盘大小不同也就是在初始化、埋雷、扫雷、打印棋盘等函数中传的行、列数不同,由于是控制台程序,没有将一般模式和困难模式的棋盘打印的过大(因为会丑,也容易眼花),正常情况下扫雷的中级模式是40个雷,16*16格,高级模式是99个雷,16*30格.
3.为了保证玩家体验,保证玩家在第一把踩雷后不被炸死,此时只需要判断玩家第一次排查的坐标是否等于雷的坐标,如果是,将雷悄悄移走(重新生成随机数)
4.若排雷的地方无雷,自动扩展到有雷的周围,并给出雷数,此时需要用到递归,直至递归到周围有雷停止,并计算雷数,显示在棋盘上。
5.标记与取消标记这个是很容易实现的,将标记位置改为P(也可以为其他),取消标记改回*即可。

实现效果:

详细代码如下:

test.c

/* date:2018/12/27 author:Better Me1 program:Mine Clearance compiler:Visual Studio 2013 拓展功能: 1.设置游戏难度等级 2.保证玩家在第一把踩雷后不被炸死 3.若排雷的地方无雷,自动扩展到有雷的周围,并给出雷数 4.标记(相当于扫雷游戏中的插旗子) 5.取消标记 */ /*测试部分*/ #define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" #include <stdio.h> #include <stdlib.h> void menu(){     printf("************  扫雷小游戏  ************\n");     printf("******  1.进入游戏  2.退出游戏  ******\n");     printf("**************************************\n"); } void menu2(){     printf("********  请选择要挑战的模式  ********\n");     printf("********  1.简单模式(10个雷)********\n");     printf("********  2.一般模式(15个雷)********\n");     printf("********  3.困难模式(20个雷)********\n"); } void game(int COUNT ){     if (COUNT == 10){         char mine[ROWS][COLS] = { 0 };         char show[ROWS][COLS] = { 0 };//显示雷,给玩家看         InitBoard(mine, ROWS, COLS, '0');         InitBoard(show, ROWS, COLS, '*');//初始化棋盘         Putmine(mine, ROW-6, COL-6, COUNT);//埋雷         //DisplayBoard(mine, ROW - 6, COL - 6);         DisplayBoard(show, ROW-6, COL-6);//打印棋盘         Findmine(mine, show, ROW-6, COL-6, COUNT);//扫雷     }     else if (COUNT == 15){         char mine[ROWS][COLS] = { 0 };         char show[ROWS][COLS] = { 0 };//显示雷,给玩家看         InitBoard(mine, ROWS, COLS, '0');         InitBoard(show, ROWS, COLS, '*');//初始化棋盘         Putmine(mine, ROW - 2, COL - 2, COUNT);//埋雷         //DisplayBoard(mine, ROW - 2, COL - 2);         DisplayBoard(show, ROW - 2, COL - 2);//打印棋盘         Findmine(mine, show, ROW - 2, COL - 2, COUNT);//扫雷     }     else{         char mine[ROWS][COLS] = { 0 };         char show[ROWS][COLS] = { 0 };//显示雷,给玩家看         InitBoard(mine, ROWS, COLS, '0');         InitBoard(show, ROWS, COLS, '*');//初始化棋盘         Putmine(mine, ROW, COL, COUNT);//埋雷         //DisplayBoard(mine, ROW, COL);         DisplayBoard(show, ROW, COL);//打印棋盘         Findmine(mine, show, ROW , COL, COUNT);//扫雷     } } void test(){     srand((unsigned int)time(0));//随机种子     int input = 0;     int input2 = 0;     int COUNT = 0;     do{         menu();         printf("请选择:>");         scanf("%d", &input);         system("cls");         switch (input){         case 1:             while (1){                 menu2();                 printf("请选择:>");                 scanf("%d", &input2);                 switch (input2){                 case 1:                     COUNT = EASY_COUNT;                     break;                 case 2:                     COUNT = USUAL_COUNT;                     break;                 case 3:                     COUNT = HARD_COUNT;                     break;                 default:                     printf("输入有误,请重新选择!\n");                     break;                 }                 if (input2 >= 1 && input2 <= 3){                     break;                 }             }             system("cls");             game(COUNT);             break;         case 2:             printf("退出游戏!\n");             break;         default:             printf("输入有误,请重新选择!\n");             break;         }     } while ((input - 2)); } void main(){     test();     system("pause"); }

game.h

#ifndef _GAME_H_ #define _GAME_H #define EASY_COUNT 10 //简单级,10个雷 #define USUAL_COUNT 15 //普通级,15个雷 #define HARD_COUNT 20 //单级,20个雷 #define ROW 15//行 #define COL 15 //列 #define ROWS ROW+2 #define COLS COL+2 void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);//初始化棋盘 void DisplayBoard(char board[ROWS][COLS], int row, int col);//打印棋盘 void Putmine(char board[ROWS][COLS], int row, int col, int count);//埋雷 void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col,int count);//扫雷 #endif

game.c

#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" #include <string.h> #include <stdio.h> #include <stdlib.h> #include <Windows.h> void InitBoard(char board[ROWS][COLS], int rows, int cols, char set){     memset(board, set, rows*cols*sizeof(board[0][0])); } void DisplayBoard(char board[ROWS][COLS], int row, int col){     int i, j = 0;     if (row == ROW - 6){         printf("------------------------------\n");     }     if (row == ROW - 2){         printf("-----------------------------------------\n");     }     if (row == ROW){         printf("----------------------------------------------\n");     }     for (i = 0; i <= row; i++){         for (j = 0; j <= col; j++){             if (i == 0 || j == 0){                 if (j == 0){                     if (i < 10){                         printf("%d  ", i);                     }                     else{                         printf("%d ", i);                     }                 }                 else{                     if (j < 10){                         printf("%d  ", j);                     }                     else{                         printf("%d ", j);                     }                 }             }             else{                 printf("%c  ", board[i][j]);             }         }         printf("\n");     }     if (row == ROW - 6){         printf("------------------------------\n");     }     if (row == ROW - 2){         printf("-----------------------------------------\n");     }     if (row == ROW){         printf("----------------------------------------------\n");     } } void Putmine(char board[ROWS][COLS], int row, int col, int count){     int c = 0;//埋好的雷的个数     int i = 0;     int j = 0;     do{         i = rand() % row + 1;         j = rand() % col + 1;         if (board[i][j] =='0'){//保证雷的个数为 count个             board[i][j] = '1';             c++;         }         } while (count-c); } /*统计雷的个数*/ int MineCount(char mine[ROWS][COLS], int i, int j){     return (mine[i - 1][j] +         mine[i - 1][j + 1] +         mine[i][j + 1] +         mine[i + 1][j + 1] +         mine[i + 1][j] +         mine[i + 1][j - 1] +         mine[i][j - 1] +         mine[i - 1][j - 1]) - 8 * '0'; } void ExpansionMine(char mine[ROWS][COLS], char show[ROWS][COLS], int i, int j, int row, int col){     if (MineCount(mine, i, j) == 0){         show[i][j] = ' ';         //再次遍历周围的雷         if (i - 1 > 0 && show[i - 1][j] == '*'){         //    printf("1\n");             ExpansionMine(mine, show, i - 1, j, row, col);//递归         }         if (i - 1 > 0 && j + 1 <= col && show[i - 1][j + 1] == '*'){             ExpansionMine(mine, show, i - 1, j + 1, row, col);         }         if (j + 1 <= col && show[i][j + 1] == '*'){             ExpansionMine(mine, show, i, j + 1, row, col);         }         if (i + 1 <= row && j + 1 <= col && show[i + 1][j + 1] == '*'){             ExpansionMine(mine, show, i + 1, j + 1, row, col);         }         if (i + 1 <= row && show[i + 1][j] == '*'){             ExpansionMine(mine, show, i + 1, j, row, col);         }         if (i + 1 <= row && j - 1 >0 && show[i + 1][j - 1] == '*'){             ExpansionMine(mine, show, i + 1, j - 1, row, col);         }         if (j - 1 > 0 && show[i][j - 1] == '*'){             ExpansionMine(mine, show, i, j - 1, row, col);         }         if (i - 1 > 0 && j - 1 > 0 && show[i - 1][j + 1] == '*'){             ExpansionMine(mine, show, i - 1, j + 1, row, col);         }     }     else{//周边有雷         show[i][j] = MineCount(mine, i, j) + '0';     } } void menu3(){     printf("********   1.标记    2.排查   ********\n");     printf("请选择:>"); } void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int count){     int i, j;//行列坐标     int playcount = 0;//玩家排雷的次数     int remine = 0;//已标记的或没有排查的坐标;     while (remine!=count){         //printf("%d", remine);         int input = 0;         printf("***** 1.标记  2.取消标记  3.排查 *****\n");         printf("请选择:>");         scanf("%d", &input);         if (input == 1){             printf("请输入要标记的坐标(如:a b):>");             scanf("%d %d", &i, &j);             if (i >= 1 && i <= row && j >= 1 && j <= col){                 if (show[i][j] == '*'){                     show[i][j] = 'P';                     system("cls");                     DisplayBoard(show, row, col);                 }                 else if (show[i][j] == 'P'){                     printf("此坐标已被标记过,请重新输入!\n");                 }                 else{                     printf("此坐标已被排查过,请重新输入!\n");                 }             }             else{                 printf("坐标输入有误,请重新输入!\n");             }         }         else if (input == 2){             printf("请输入要取消标记的坐标(如:a b):>");             scanf("%d %d", &i, &j);             if (i >= 1 && i <= row && j >= 1 && j <= col){                 if (show[i][j] == 'P'){                     show[i][j] = '*';                     system("cls");                     DisplayBoard(show, row, col);                 }                 else if (show[i][j] == '*'){                     printf("此坐标还没有被标记过,请重新输入!\n");                 }                 else{                     printf("此坐标已被排查过,请重新输入!\n");                 }             }             else{                 printf("坐标输入有误,请重新输入!\n");             }         }         else if (input == 3){             //printf("%d", remine);             printf("请输入要排查的坐标(如:a b):>");             scanf("%d%d", &i, &j);             if (i >= 1 && i <= row && j >= 1 && j <= col){                 if (show[i][j] == '*'){                     if (mine[i][j] == '1'){                         if (playcount == 0){//此时说明玩家首次排雷且踩到雷了                             mine[i][j] = '0';                             Putmine(mine, row, col, 1);//重新放雷,保证玩家在第一把不踩雷                             playcount = 1;                             ExpansionMine(mine, show, i, j, row, col);//扩展周边的雷                             DisplayBoard(show, row, col);                         }                         else{                             printf("很遗憾,你被炸死了!\n");                             printf("雷阵布局如下:\n");                             DisplayBoard(mine, row, col);                             break;                         }                     }                     else{                         ExpansionMine(mine, show, i, j, row, col);//扩展周边的雷                         system("cls");                         //DisplayBoard(mine, row, col);                         DisplayBoard(show, row, col);                         playcount = 1;                     }                 }                 else if (show[i][j] == 'P'){                     printf("此坐标已被标记过,请重新输入!\n");                 }                 else{                     printf("此坐标已被排查过,请重新输入!\n");                 }             }             else{                 printf("坐标输入有误,请重新输入!\n");             }         }         else{             printf("输入有误,请重新输入!\n");         }         remine = 0;//重新统计;         for (int m = 1; m <= row; m++){             for (int n = 1; n <= col; n++){                 if ((show[m][n] == '*' )||( show[m][n] == 'P')){                     remine++;                 }             }         }     }     //printf("%d", remine);     if (remine == count){         printf("恭喜您,排雷成功!\n");         printf("雷阵布局如下:\n");         DisplayBoard(mine, row, col);     } }



小游戏 扩展 C语言

需要 登录 后方可回复, 如果你还没有账号请 注册新账号