不同于以前简短的练习作业,即使是简易版扫雷的代码结构,也需要做好规划文件的分装
创建了三个文件
分别是一个头文件->function.h
与两个源文件mainpart.c和function.c
mainpart中含有主函数,主要负责的是设置随机数种子和使用do-while来构成程序的外层运行框架
随后在用户输入选项之后进入相应的操作
进入开始阶段->
1创建相应数组2初始化数组3设置雷
进入扫雷阶段
1用户输入的值2找到对应的元素计算周围的雷数并放置这个数字字符在对应位置
3累计扫雷成功的次数(没被炸死的次数),到达对应数量时跳出扫雷循环(胜利),或者被炸死
其他事项
1注意用户输入的元素不是对应的下标2使用一维数组指针接受二维数组来提升代码的扩展性
代码如下
//function.c
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <Windows.h>
#define height1 9
#define width1 9
void init_board(char*, int, int,char);
void set_mine(char*, int, int);
void print_board(char*, int, int);
void get_mine_count(char*, char*, int, int, int, int);
//function.c
#include "function.h"
void init_board(char* board, int height, int width,char n)
{
for (int i = 0;i < height;i++)
{
for (int j = 0;j < width;j++)
{
*(board+i*width+j) = n;
}
}
}
void set_mine(char* board, int height, int width)
{
int n = 10;
while (n)
{
int x = rand() % 9 + 1;
int y = rand() % 9 + 1;
if (*(board + (x-1) * width + y-1) != '1')
{
*(board + (x-1) * width + y-1) = '1';
}
else
{
continue;
}
n--;
}
}
void print_board(char* board, int height, int width)
{
for (int a = 0; a <= width;a++)
{
printf("%d ", a);
}
printf("\n");
for (int i = 0;i < height;i++)
{
printf("%d ", i+1);
for (int j = 0;j < width;j++)
{
printf("%c ", *(board + i * width + j));
}
printf("\n");
}
printf("\n");
}
void get_mine_count(char* board, char* show_board,int height, int width, int x, int y)
{
int count = 0;
int nx, ny;
for (nx = -1;nx <= 1; nx++)
{
for (ny = -1;ny <= 1;ny++)
{
if (x - 1 + nx >= 0 && x - 1 + nx <9 && y - 1 + ny >= 0 && y - 1 + ny <9)
{
if (*(board + (x-1 + nx) * width + (y-1 + ny)) == '1')
count++;
}
}
}
*(show_board + (x -1) * width + y -1) = (count+'0');
}
//mainpart.c
#define _CRT_SECURE_NO_WARNINGS
#include "function.h"
void menu()
{
printf("********扫雷小游戏********\n");
printf("********1.开始游戏********\n");
printf("********0.退出游戏********\n");
printf("*************************\n");
printf("make choice\n");
}
void game()
{
char mine_board[height1][width1];
char show_board[height1][width1];
init_board((char*)mine_board, height1, width1, '0');
init_board((char*)show_board, height1, width1, '*');
set_mine((char*)mine_board, height1, width1);
printf("输入-1 -1直接退出\n");
int win = 0;
while (1)
{
//#################
//print_board((char*)mine_board,height1,width1);
print_board((char*)show_board,height1,width1);
printf("请输入坐标,例如 a b 代表第a行的第b个位置\n");
int a, b;
scanf("%d %d", &a, &b);
if (a == -1 && b == -1)
{
printf("中途退出\n");
break;
}
if (a < 1 || a > 9 || b < 1 || b > 9)
{
printf("数值不在可输入范围\n");
continue;
}
else if (*((char*)mine_board + (a - 1) * width1 + (b - 1)) == '1')
{
printf("很遗憾,你被炸死了\n");
Sleep(300);
break;
}
else if (*((char*)show_board + (a - 1) * width1 + (b - 1)) != '*')
{
printf("该位置已被扫过\n");
continue;
}
else if (a >= 1 && a <= 9 && b >= 1 && b <= 9)
get_mine_count((char*)mine_board, (char*)show_board, height1, width1, a, b);
else
{
printf("数值错误\n");
break;
}
win++;
if (win == height1 * width1 - 10)
{
printf("恭喜你,你赢了\n");
Sleep(300);
break;
}
}
return;
}
int main()
{
int a = 0;
srand((unsigned int)time(NULL));
do
{
menu();
scanf("%d" ,&a);
switch (a)
{
case 1:
game();
break;
case 0:
{
printf("正在退出\n");
Sleep(750);
printf("已退出本次游玩\n");
return 0;
}
default:
printf("输入错误,请重新输入\n");
}
}
while (1);
return 0;
}