在正式写代码前,简单说一下对这个简单小游戏的分析: 1.游戏是玩家来玩,因此必须有一个提示玩家玩的信息。
2.为了增加代码的可读性,逻辑性,游戏应该由一个个函数组成。
3.为了提高程序的简洁性,提高编程的效率,可对一些必要的,比如函数声明、宏定义等放在一个头文件中。
4.函数功能实现后,应该有一个可测试的代码,便于对程序进行测试。
因此,经过分析,整个游戏又三部分组成:头文件部分、函数实现部分、测试部分。
在头文件中:将所有的函数的声明和相关的宏定义封装在一个game.h头文件中。
#define __GAME_H__
#ifdef __GAME_H__
#define _CRT_SECURE_NO_WARNINGS 1
#define ROWS 10
#define COLS 10
#define MINE 30
#include <time.h>
void init_board(char arr[ROWS][COLS]); //初始化棋盘
void print_board(char arr[ROWS][COLS]); //打印雷棋盘
void set_mines(char arr[ROWS][COLS]); //设置雷
void print_board2(char arr[ROWS+2][COLS+2]);//打印显示棋盘
void mine_sweepe(char arr[ROWS][COLS],char mine[ROWS][COLS]);//扫雷
#endif __GAME_H__
#include <stdio.h>
#include "game.h"
#include <time.h>
#include <stdlib.h>
#define _CRT_SECURE_NO_WARNINGS 1
void init_board(char arr[ROWS+2][COLS+2])
{
int rows = 0;
int cols = 0;
for (rows=0;rows<ROWS+2;rows++)
{
for (cols=0; cols<COLS+2; cols++)
{
arr[rows][cols] = arr[0][0];
}
}
}
void print_board(char arr[ROWS+2][COLS+2])
{
int rows = 0;
int cols = 0;
printf(" "); //对其
for (rows=1; rows<ROWS+1; rows++) //输出行的标号
{
printf("%2d ",rows);
}
printf("\n");
for (rows=1; rows<=ROWS; rows++)
{
printf("%2d ",rows);
for (cols=1; cols<=COLS; cols++)
{
printf(" %c ",arr[rows][cols]);
}
printf("\n");
}
}
void set_mines(char arr[ROWS+2][COLS+2])
{
int cols = 0;
int rows = 0;
int count = MINE;
srand((int)time(NULL));
while(count)
{
rows = rand()%10+2;
cols = rand()%10+2;
rows--;
cols--;
if (arr[rows][cols] == '_')
{
arr[rows][cols] = '1';
count--;
}
}
}
void mine_sweepe(char arr[ROWS+2][COLS+2],char mine[ROWS+2][COLS+2])
{
int rows = 0;
int cols = 0;
printf("请输入坐标:>");
scanf("%d%d",&rows,&cols);
if (arr[rows][cols] == '1') //第一次是雷
{
int rows1 = 0;
int cols1 = 0;
srand((unsigned)time(NULL));
while (1)
{
rows1 = rand()%10+1;
cols1 = rand()%10+1;
if (arr[rows1][cols1] == '_')
{
char tmp = arr[rows1][cols1];
arr[rows1][cols1] = arr[rows][cols];
arr[rows][cols] = tmp;
break;
}
}
}
if (arr[rows][cols] != '1')
{
int count = 0; //统计周围雷的个数
int i = 0;
int j = 0;
for (j=cols-1; j<=cols+1; j++)
{
if (arr[rows-1][j] == '1')
{
count++;
mine[rows-1][j] = '*';
}
if (arr[rows+1][j] == '1')
{
count++;
mine[rows+1][j] = '*';
}
}
if (arr[rows][cols-1] == '1' )
{
count++;
mine[rows][cols-1] = '*';
}
if (arr[rows][cols+1] == '1' )
{
count++;
mine[rows][cols+1] = '*';
}
mine[rows][cols] = count+'0';
print_board(mine); //打印第一次不是雷 周围雷的个数
while (1)
{
int rows = 0;
int cols = 0;
printf("请输入坐标:>");
scanf("%d%d",&rows,&cols);
if (arr[rows][cols] == '1')
{
mine[rows][cols] = '*';
print_board(mine);
printf("很遗憾,你被炸死了!!!\n");
break;
}
if (arr[rows][cols] == '_')
{
int count = 0;
int i = 0;
int j = 0;
for (j=cols-1; j<=cols+1; j++)
{
if (arr[rows-1][j] == '1')
{
count++;
mine[rows-1][j] = '*';
}
if (arr[rows+1][j] == '1')
{
count++;
mine[rows+1][j] = '*';
}
}
if (arr[rows][cols-1] == '1' )
{
count++;
mine[rows][cols-1] = '*';
}
if (arr[rows][cols+1] == '1' )
{
count++;
mine[rows][cols+1] = '*';
}
mine[rows][cols] = count+'0';
print_board(mine);
}
}
}
}
对整个代码进行测试,在这部分中,关键体现各个函数之间的顺序和整个程序的逻辑关系:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include "game.h"
void menu()
{
printf("**************************************************\n");
printf("******* 1.PLAY 2.EXIT *************\n");
printf("**************************************************\n");
}
int main()
{
int input = 0;
char arr[ROWS+2][COLS+2] = {'_'}; //雷的位置
char mine[ROWS+2][COLS+2] = {'_'}; //展示
do
{
menu();
printf("请选择:>");
scanf("%d",&input);
switch(input)
{
case 1:
init_board(arr);
init_board(mine);
set_mines(arr);
print_board(arr);
print_board(mine);
mine_sweepe(arr,mine);
break;
case 0:
break;
}
} while (input);
return 0;
}
程序运行结果:数字统计周围雷的个数,雷用*号表示
( 注:为了程序的逻辑清楚,我将雷的位置先打印出来,也可不打印)