在学习过二维数组 简单的递归调用 ,之后很容易写一个扫雷小游戏。
主函数:
主函数所写的是玩家玩游戏的大致步骤。
所其中包括游戏菜单,游戏选项 ,游戏 ,输赢结果的判断及显示 ,while或do...while循环实现游戏循环
#include "gmine.h"
void menu()
{
printf("************ 扫雷 ************\n");
printf("********> 1. play <********\n");
printf("********> 0. exit <********\n");
printf("********************************\n");
}
void game()
{
srand((unsigned)time(NULL));
printf("设置雷的个数: ");
int num;
scanf("%d", &num);
char panel[ROW][COL]; //有记录雷的界面
char panel2[ROW][COL]; //对玩家显示界面
int row = 0, col = 0, flag = 0;
InitBoard(num, panel, panel2); //初始化panel,panel2
FillNum(panel); //填充雷周围的数字
//ShowBoard(panel);
ShowBoard(panel2);
int i = 0;
int step = 0;
for (i = 0; i < num; i++)
{
printf("请输入坐标并标记是否是雷(1代表是,0代表不是):");
scanf("%d%d%d", &row, &col, &flag);
int mine = Find(panel, panel2, row - 1, col - 1, flag);
//如果踩到雷
if (mine == 2)
{
//第一次就踩雷,将雷挪走
if (step == 0)
{
mine = MoveMine(panel, panel2,row - 1,col - 1 );
}
else
break;
}
//如果找到雷
else if (mine)
{
ShowBoard(panel2);
continue;
}
step = 1;
i--;
ShowBoard(panel2); //显示盘
}
if (i < num)
{
printf(" 遗憾 > < 游戏结束. \n");
}
else
{
printf("!!恭喜,玩家胜利 !!\n");
}
}
int main()
{
int input = 0;
menu();
printf("请输入:> ");
scanf("%d", &input);
do
{ switch (input)
{
case 1: game(); break;
case 0: exit(0); break;
default: printf("输入错误,请输入0 or 1\n"); break;
}
printf("再来一局??(1: 继续 0: 退出 ) ");
int again = 0;
scanf("%d", &again);
if (again == 1)
{
input = 1;
}
else if (again == 0)
{
input = 0;
}
else
{
printf("输入错误\n");
}
} while (input);
return 0;
}
扫雷的具体实现:
写这一模块时应该注重梳理,应该一步步写,如:绘制界面 --> 显示界面 --> 初始化盘 --> 检测雷周围的数字 --> 打印数字(0或其他)--> 标记雷 --> 扩展功能
#include "gmine.h"
//输出横向坐标
void PrintX() {
int row = 0;
printf(" ");
for (row = 0; row < ROW; row++)
{
printf("%4d", row + 1);
}
printf("\n");
}
//输出横向框
void PrintH() {
int col = 0;
printf(" +");
for (col = 0; col < COL *2; col++)
{
if (!((col + 1) % 2)){
printf("+");
}
else {
printf("---");
}
}
printf("\n");
}
//显示盘
void ShowBoard(char panel[ROW][COL])
{
int row = 0, col = 0;
PrintX();
PrintH();
for (row = 0; row < ROW; row++)
{
printf("%2d ", row + 1); //输出竖向坐标
printf("| ");
for (col = 0; col < COL; col++)
{
printf("%c ", panel[row][col]);
printf("| ");
}
printf("%d\n", row +1); //输出竖向坐标
PrintH(); //横向框
}
PrintX();
}
//初始化盘
void InitBoard(int num, char panel[ROW][COL], char panel2[ROW][COL])
{
int i = 0;
int row = 0;
int col = 0;
for (row = 0; row < ROW; row++)
{
for (col = 0; col < COL; col++)
{
panel[row][col] = ' ';
panel2[row][col] = ' ';
}
}
for (i = 0; i < num; i++)
{
row = rand() % ROW;
col = rand() % COL;
if (panel[row][col] == '*')
{
i--;
}
else
{
panel[row][col] = '*';
}
}
}
//根据布置好的雷计算雷周围的数字
void FillNum(char panel[][COL])
{
//填充数字
int row = 0, col = 0;
for (row = 0; row < ROW; row++)
{
for (col = 0; col < COL; col++)
{
int count = 0;
//如果是雷,则不需要计算该位置周围的雷数
if (panel[row][col] == '*')
continue;
if ((row - 1) >= 0 && (col - 1) >= 0)
{
//检测左上角是否在盘内
if (panel[row - 1][col - 1] == '*')
count++; //检测到雷,则count加1
}
if ((row + 1) < ROW && (col - 1) >= 0)
{
//左下角
if (panel[row + 1][col - 1] == '*')
count++;
}
if ((row - 1) >= 0 && (col + 1) < COL)
{
//右上角
if (panel[row - 1][col + 1] == '*')
count++;
}
if ((row + 1) < ROW && (col + 1) < COL)
{
//右下角
if (panel[row + 1][col + 1] == '*')
count++;
}
if ((row - 1) >= 0)
{
//正上方
if (panel[row - 1][col] == '*')
count++;
}
if ((row + 1) < ROW)
{
//正下方
if (panel[row + 1][col] == '*')
count++;
}
if ((col - 1) >= 0)
{
//左边
if (panel[row][col - 1] == '*')
count++;
}
if ((col + 1) < COL)
{
//右边
if (panel[row][col + 1] == '*')
count++;
}
panel[row][col] = '0' + count; //将计算出的周围的雷数整型转换成字符型
}
}
}
//点到0,显示多个数字
void ShowNum(char panel[][COL], int row, int col, char panel2[][COL])
{
panel2[row][col] = panel[row][col]; //显示数字
//检测相邻点是否超出棋盘 若相邻点为0且没有雷则以该点为中心继续显示
//正上方
if ((row - 1) >= 0)
{
if (panel[row - 1][col] == '0' && panel2[row - 1][col] == ' ')
ShowNum(panel, row - 1, col, panel2);
else
panel2[row - 1][col] = panel[row - 1][col];
}
//正下方
if ((row + 1) < ROW)
{
if (panel[row + 1][col] == '0' && panel2[row + 1][col] == ' ')
ShowNum(panel, row + 1, col, panel2);
else
panel2[row + 1][col] = panel[row + 1][col];
}
//左边
if ((col - 1) >= 0)
{
if (panel[row][col - 1] == '0' && panel2[row][col - 1] == ' ')
ShowNum(panel, row, col - 1, panel2);
else
panel2[row][col - 1] = panel[row][col - 1];
}
//右边
if ((col + 1) < COL)
{
if (panel[row][col + 1] == '0' && panel2[row][col + 1])
ShowNum(panel, row, col + 1, panel2);
else panel2[row][col + 1] = panel[row][col + 1];
}
//左上角
if ((row - 1) >= 0 && (col - 1) >= 0)
{
if (panel[row - 1][col - 1] == '0' && panel2[row - 1][col - 1] == ' ')
ShowNum(panel, row - 1, col - 1, panel2);
else
panel2[row - 1][col - 1] = panel[row - 1][col - 1];
}
//左下角
if ((row + 1) < ROW && (col - 1) >= 0)
{
if (panel[row + 1][col - 1] == '0' && panel2[row + 1][col - 1] == ' ')
ShowNum(panel, row + 1, col - 1, panel2);
else panel2[row + 1][col - 1] = panel[row + 1][col - 1];
}
//右上角
if ((row - 1) >= 0 && (col + 1) < COL)
{
if (panel[row - 1][col + 1] == '0' && panel2[row - 1][col + 1] == ' ')
ShowNum(panel, row - 1, col + 1, panel2);
else panel2[row - 1][col + 1] = panel[row - 1][col + 1];
}
//右下角
if ((row + 1) < ROW && (col + 1) < ROW)
{
if (panel[row + 1][col + 1] == '0' && panel2[row + 1][col + 1] == ' ')
ShowNum(panel, row + 1, col + 1, panel2);
else
panel2[row + 1][col + 1] = panel[row + 1][col + 1];
}
}
//找雷
int Find(char panel[][COL], char panel2[][COL],int row, int col, int flag)
{
if (flag == 1)
{
//标记可能是雷的位置
//是雷返回 1 不是返回 0
panel2[row][col] = 'F'; //如果是雷标记‘F'
if (panel[row][col] == '*')
{
return 1;
}
else
{
return 0;
}
}
else
{
//猜测不是雷
if (panel[row][col] == '*')
{
//点到雷,游戏失败
return 2;
}
else if (panel[row][col] == '0')
{
//点击到0,显示多个数字
ShowNum(panel, row, col, panel2);
return 0;
}
else
{
panel2[row][col] = panel[row][col]; //显示数字
return 0;
}
}
}
//防止第一次踩雷
int MoveMine(char panel[][COL], char panel2[][COL], int row, int col)
{
int row2 = 0;
int col2 = 0;
//找到没有雷的位置与输入位置交换
for (row2 = 0; row2 < ROW; row++)
{
for (col2 = 0; col2 < COL; col++)
{
int tmp = 0;
if (panel[row2][col2] == '*')
continue;
else
{
//将雷移走
tmp = panel[row][col];
panel[row][col] = panel[row2][col2];
panel[row2][col2] = tmp;
//更新
FillNum(panel);
//ShowBoard(panel);
panel2[row][col] = panel[row][col];
return panel2[row][col];
}
}
}
}
头文件:
#ifndef _GAME_H_
#define _GAME_H_
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 10
#define COL 10
void ShowaBoard (char panel[ROW][COL]);
void InitBoard (int num, char panel[ROW][COL], char panel2[ROW][COL]);
void FillNumber(char panel[][COL]);
void ShowNum(char panel[][COL], int row, int col, char panel2[][COL]);
int Find(char panel[][COL], char panel2[][COL], int row, int col, int flag);
int MoveMine(char panel[][COL], char panel2[][COL],int row,int col);
#endif //_GAME_H_
由于多次修改过,可能代码有很多地方很乱,而且应该有许多地方写的比较挫,然后功能比较简单,之后希望能有好的建议。