这个小游戏也分为三个部分的代码,分别是头文件,测试代码和游戏代码。
1.注意初始化以及使用GetWinCount函数的时候字符1和字符0的使用。
2.为了玩家的体验,第一步不可以被炸死。
3.要扩展,这时会用到递归,注意递归的使用。
4.可以添加标记,优化游戏。
头文件:game.h
#ifndef __GAME_H__ #define __GAME_H__ #include<stdio.h> #include<stdlib.h> #include<time.h> #include<String.h> #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define EASY_COUNT 10 #define MID_COUNT 30 #define HARD_COUNT 60 void InitBoard(char board[ROWS][COLS], int rows, int cols, char set); void DisplayBoard(char board[ROWS][COLS], int row, int col); void SetMine(char board[ROWS][COLS], int row, int col); void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col); void MoveMine(char mine[ROWS][COLS], int i, int j); void GetMineCount(char mine[ROWS][COLS],char show[ROWS][COLS], int i, int j); void Mark(char show[ROWS][COLS]); #endif //__GAME_H__
测试代码:test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" void menu() { printf("************************\n"); printf("*** 1. play 2. exit ***\n"); printf("************************\n"); } void game() { int input = 0; int DIF = 0;//游戏的难度 char mine[ROWS][COLS] = {0};//布雷的棋盘 char show[ROWS][COLS] = {0};//要打印的棋盘 InitBoard(mine, ROWS, COLS, '0'); InitBoard(show, ROWS, COLS, '*');//初始化 printf("**********************************\n"); printf("***** 1.EASY 2.MIDIUM 3.HARD *****\n"); printf("**********************************\n"); printf("请选择相关难度:>"); scanf("%d",&input); switch(input){ case 1: DIF = EASY_COUNT; break; case 2: DIF = MID_COUNT; break; case 3: DIF = HARD_COUNT; break; default:printf("选择错误!\n"); } printf("这个棋盘有%d处雷!\n",DIF); SetMine(mine, ROW, COL, DIF);//设置雷 //DisplayBoard(mine, ROW, COL); DisplayBoard(show, ROW, COL);//输出 FindMine(mine, show, ROW, COL, DIF);//扫雷 } void test() { int input = 0; srand((unsigned int)time(NULL)); do{ menu(); printf("请输入:>"); scanf("%d",&input); switch(input) { case 1: game(); break; case 0: printf("退出游戏!\n"); break; default: printf("选择错误!\n"); break; } }while(input); } int main() { test(); return 0; }
游戏代码:game.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.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 = 0; int j = 0; for(i=0; i<=col; i++) { printf("%d ",i);//添加列号,从0开始 } printf("\n"); for(i=1; i<=row; i++) { printf("%d ",i);//添加行号 for(j=1; j<=col; j++) { printf("%c ",board[i][j]); } printf("\n"); } printf("\n"); } void SetMine(char board[ROWS][COLS], int row, int col ,int DIF)//设置雷 { int i = 0; int j = 0; while(DIF) { i = rand()%9+1; j = rand()%9+1; if(board[i][j] = '0') { board[i][j] = '1';//‘1’代表有雷 DIF--; } } } void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col , int DIF)//扫雷 { int i = 0; int j = 0; int tmp = 0;//表示扫雷的次数 int n = 0;//输入的坐标总数 while(n<(row*col-DIF)) { Mark(show);//标记 DisplayBoard(show, ROW, COL); printf("请输入要排查的坐标:>"); scanf("%d %d",&i,&j); tmp++; if(i>=1 && i<=row && j>=1 && j<=col) { if(tmp == 1 && mine[i][j] == '1')//如果第一次输入坐标有雷,就移走它,保证玩家第一次不会被炸死 { MoveMine(mine, i, j);//移雷 } if(mine[i][j] == '1') { printf("很不幸,你被炸死了!\n"); DisplayBoard(mine, row, col); break; } else { GetMineCount(mine,show, i, j);//获取雷的个数 DisplayBoard(show, row, col); } } else { printf("坐标非法!\n"); } } if(n == (row*col-DIF)) { printf("恭喜你,排雷成功!\n"); } } void GetMineCount(char mine[ROWS][COLS],char show[ROWS][COLS], int i, int j) { if ((mine[i][j] == '0')) { int count = 0; if (mine[i-1][j] == '1') count++; if (mine[i-1][j-1] == '1') count++; if (mine[i][j-1] == '1') count++; if (mine[i+1][j-1] == '1') count++; if (mine[i+1][j] == '1') count++; if (mine[i+1][j+1] == '1') count++; if (mine[i][j+1] == '1') count++; if (mine[i-1][j+1] == '1') count++; //排查输入坐标周围是否有雷 show[i][j] = (count + '0');//数字+‘0’=‘该数字’ } if(show[i][j] == '0')//如果输入的坐标没有雷,就扩展 { if(show[i-1][j] == '*') GetMineCount(mine, show, i-1,j); if(show[i-1][j-1] == '*') GetMineCount(mine, show, i-1, j-1); if(show[i][j-1] == '*') GetMineCount(mine, show, i, j-1); if(show[i+1][j-1] == '*') GetMineCount(mine, show, i+1, j-1); if(show[i+1][j] == '*') GetMineCount(mine, show, i+1, j); if(show[i+1][j+1] == '*') GetMineCount(mine, show, i+1, j+1); if(show[i][j+1] == '*') GetMineCount(mine, show, i, j+1); if(show[i-1][j+1] == '*') GetMineCount(mine, show, i-1, j+1);//递归 } } void MoveMine(char mine[ROWS][COLS], int i, int j, int DIF)//移雷 { mine[i][j] = '0'; i = rand()%9+1; j = rand()%9+1; if(mine[i][j] == '0') { mine[i][j] = '1'; }//只移走第一次输入有雷的那个雷 } void Mark(char show[ROWS][COLS])//标记 { int i = 0; int j = 0; printf("请输入你要标记的位置(若不想标记,请输入0 0):>"); scanf("%d %d",&i,&j); if(i==0 && j==0) { return 0;//不标记,返回 } else show[i][j] = '!';//标记 }
结果展示: