扫雷代码(包含扩展函数)

以下为本人十几天之前写的扫雷代码,没有看教程,从构思到完成全是自己做的(很有成就感!)

当时Expand扩展函数那里总是出错,老是栈溢出还找不到哪里错了

今天突然发现错了一行代码,改了之后果然能正常运行了

不做其他介绍(因为太懒了),有的介绍文字都在注释里,大家自己看吧

(ps.本代码没有写插旗函数)

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

void menu()
{
	printf("*************************************************\n");
	printf("*************************************************\n");
	printf("*****    1.play    ************   0.exit    *****\n");
	printf("*************************************************\n");
	printf("*************************************************\n");
}

void game()
{
	//设定二维数组
	char board[ROW][COL] = { 0 };
	char minesboard[ROW][COL] = { 0 };
	//初始化
	InitBoard(board, ROW, COL);
	InitMinesBoard(minesboard, ROW, COL);
	//生成雷
	GenerateMines(minesboard, ROW, COL, MINES);
	//打印表盘
	DisplayBoard(board, ROW, COL);
	//扫雷
	SweepMines(board,minesboard,ROW,COL);
}
void test()
{
	srand((unsigned int)time(NULL));
	int input;
	do
	{
		menu();
		printf("请选择>\t");
		scanf("%d", &input);
		printf("\n");
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
}

int main()
{
	test();
}

game.h

#pragma once
#define ROW 10		//行
#define COL 10		//列
#define MINES 10		//雷数
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<windows.h>
void InitBoard(char board[ROW][COL], int row, int col);//初始化表盘
void InitMinesBoard(char minesboard[ROW][COL], int row, int col);//初始化雷盘
void DisplayBoard(char board[ROW][COL], int row, int col);//打印表盘
void GenerateMines(char minesboard[ROW][COL], int row, int col, int mines);//生成雷
void SweepMines(char board[ROW][COL], char minesboard[ROW][COL], int row, int col);//扫雷
char Count(char minesboard[ROW][COL], int x, int y);//数雷
void Expand(char board[ROW][COL],char minesboard[ROW][COL], int x, int y);
int Win(char board[ROW][COL],int row,int col);//判断是否胜利

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void InitBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			board[i][j] = '@';
		}
	}
}
void InitMinesBoard(char minesboard[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			minesboard[i][j] = '0';
		}
	}
}

void DisplayBoard(char board[ROW][COL], int row, int col)
{
	system("cls");//每次打印之前清屏一遍
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		for (j = 0; j < col; j++)
		{
			if (i < row - 1)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
		}
		printf("\n");
	}
}
void GenerateMines(char minesboard[ROW][COL], int row, int col, int mines)
{
	int n = 0;
	for (n = 0; n < mines; n++)
	{
		int i = rand() % row;
		int j = rand() % col;
		if (minesboard[i][j] == '1')//防止重复布雷
		{
			n--;
			continue;
		}
		minesboard[i][j] = '1';
	}
}
void SweepMines(char board[ROW][COL], char minesboard[ROW][COL], int row, int col)
{
	int x, y;
	while (Win(board,ROW,COL))
	{
		printf("请输入您要扫的坐标>\n");
		scanf("%d%d", &x, &y);
		if (x - 1 >= 0 && x - 1 <= row && y - 1 >= 0 && y - 1 <= col)
		{
			if (minesboard[x - 1][y - 1] == '1')
			{
				DisplayBoard(minesboard, ROW, COL);
				printf("很遗憾,您被炸死了!\n");
				Sleep(2000);
				break;
			}
			else
			{
				Expand(board, minesboard, x-1, y-1);
				DisplayBoard(board, ROW, COL);
			}
		}
		else
		{
			printf("非法坐标,请重新输入!\n");
		}
	}
}
char Count(char minesboard[ROW][COL], int x, int y)
{
	int count = 0;
	if (minesboard[x + 1][y + 1] == '1')
	{
		count++;
	}
	if (minesboard[x + 1][y] == '1')
	{
		count++;
	}
	if (minesboard[x + 1][y - 1] == '1')
	{
		count++;
	}
	if (minesboard[x][y + 1] == '1')
	{
		count++;
	}
	if (minesboard[x][y - 1] == '1')
	{
		count++;
	}
	if (minesboard[x - 1][y + 1] == '1')
	{
		count++;
	}
	if (minesboard[x - 1][y] == '1')
	{
		count++;
	}
	if (minesboard[x - 1][y - 1] == '1')
	{
		count++;
	}
	return count+'0';
}
int Win(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	int o = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] != '@')
			{
				o++;
			}
		}
	}
	if (o == row * col - MINES)
	{
		printf("游戏结束,扫雷成功!\n");
		return 0;
	}
	else
	{
		return 1;
	}
}
void Expand(char board[ROW][COL], char minesboard[ROW][COL], int x, int y)
{
	if (Count(minesboard, x, y) == '0')
	{
		board[x][y] = ' ';
		int i = 0, j = 0;
		for (i = x - 1; i <= x + 1; i++)
		{
			for (j = y - 1; j <= y + 1; j++)
			{
				if (i >= 1 && i <= ROW && j >= 1 && j <= COL)
				{
					if (board[i][j] == '@')//???改了半天就差在这一行条件代码上???(原代码是minesboard[i][j]=='0',总是导致栈溢出)
					{						//原来如此,minesboard[i][j]=='0'并不是必要的条件,因为最上面的if已经限定了只有不是雷的时候才能进入循环,这就说明只要进入递归了,就一定不会是雷,而board[i][j]=='@'却是必要条件,因为如果没有这个条件,那么Expand函数就会反复递归所有已经递归过的格子,最终导致栈溢出,虽然我在改代码的时候曾经尝试加上 i=x,j=y 就不进行递归的条件,但仍然无法限制住,因为在扩展到一定的数量的格子之后,会有重叠的格子,这些格子也会造成无限递归
						Expand(board, minesboard, i, j);
					}
				}
			}
		}
	}
	else
	{
		board[x][y] = Count(minesboard, x, y);
	}
}

希望对您有所帮助,如有学术问题敬请纠正。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值