迷宫游戏c语言编程

趣味编程之迷宫游戏

昨天正式开始带两个孩子学习c语言编程,为了让他们能主动的记录下来进步成长的足迹,要求他们进入csdn 程序开发者社区,注册,并发布他们的第一个hello world 程序的博客文章,布置完作业后才想到自己作为12年社区成员还没有都没有在社区发布过一篇文章,惭愧呀,万一孩子们不会问我,我也不会,还怎么当孩子们的老师呀,赶快试着模拟做了一遍我留给孩子的作业。让人欣慰的是两个孩子很积极的完成了作业,很高兴。希望两个孩子在这个开发者社区,好好学习天天向上。
今天作为第二个作业,我就想起了大学时肖老师教我们的经典迷宫程序,想起来当时刚学编程的同学们很是兴奋。所以今天就选这个题目吧
关于迷宫的背景知识我在开发者社区找了一下
https://blog.csdn.net/weixin_43401438/article/details/84110307?
这个链接比较经典。感谢作者。
孩子们的作业是
1 下载该代码,在你的电脑上调试成功运行。
2 然后把原文中的算法思路用csdn 插入流程图的形式表达出来
3 你认为代码中那一段写的比较精彩,为什么
4.自己消化吸收,三个月后,自己从一个空白的文件开始写出自己的迷宫程序

另外我在社区里找到一段代码,调试了一下,感觉很新颖,可惜忘记是哪个链接了,如果你发现我用了你的代码,可以告诉我。我把你的链接见到这里。
这个类似最早期游戏的程序,可以用光标移动上下左右键,实现单步迷宫前进,写的很是简洁,用递归的方法实现了迷宫的随机初始化。我增加了一段小代码,完成自动寻路的表达,当按下空格键,实现自动的寻找路径的过程。
希望两个同学
1.增加上一个示例中路径标示
2.增加查找最优路径的,什么是最优路径,就是从入口到出口路径最短的一条通路。

以下代码是在vc2017下编译调试通过的

// mazedemo.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <time.h> 

#define Height 25 //迷宫的高度,必须为奇数
#define Width 25 //迷宫的宽度,必须为奇数
#define Wall 1
#define Road 0
#define Start 2
#define End 3
#define Esc 5
#define Up 1
#define Down 2
#define Left 3
#define Right 4
#define Auto  6

int map[Height + 2][Width + 2];
int mask[Height + 2][Width + 2];
int RecordX[(Height + 2)*(Width + 2) + 10];
int RecordY[(Height + 2)*(Width + 2) + 10];
int RecordFX[(Height + 2)*(Width + 2) + 10];

int StepX[4];
int StepY[4];

void gotoxy(int x, int y) //移动坐标
{
	COORD coord;
	coord.X = x;
	coord.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void hidden()//隐藏光标
{
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO cci;
	GetConsoleCursorInfo(hOut, &cci);
	cci.bVisible = 0;//赋1为显示,赋0为隐藏
	SetConsoleCursorInfo(hOut, &cci);
}
void create(int x, int y) //随机生成迷宫
{
	int c[4][2] = { 0,1,1,0,0,-1,-1,0 }; //四个方向
	int i, j, t;
	//将方向打乱
	for (i = 0; i < 4; i++)
	{
		j = rand() % 4;
		t = c[i][0]; c[i][0] = c[j][0]; c[j][0] = t;
		t = c[i][1]; c[i][1] = c[j][1]; c[j][1] = t;
	}
	map[x][y] = Road;
	for (i = 0; i < 4; i++)
		if (map[x + 2 * c[i][0]][y + 2 * c[i][1]] == Wall)
		{
			map[x + c[i][0]][y + c[i][1]] = Road;
			create(x + 2 * c[i][0], y + 2 * c[i][1]);
		}

}
int get_key() //接收按键
{
	char c;
	while (c = _getch())
	{
		if (c == ' ') return Auto;//空格
		if (c == 27) return Esc; //Esc
		if (c != -32)continue;
		c = _getch();
		if (c == 72) return Up; //上
		if (c == 80) return Down; //下
		if (c == 75) return Left; //左
		if (c == 77) return Right; //右
	}
	return 0;
}
void paint(int x, int y) //画迷宫
{
	gotoxy(2 * y - 2, x - 1);
	switch (map[x][y])
	{
	case Start:
		printf("入"); break; //画入口
	case End:
		printf("出"); break; //画出口
	case Wall:
		printf("▇"); break; //画墙
	case Road:
		printf("  "); break; //画路
	}
}
void game()
{
	int x = 2, y = 1; //玩家当前位置,刚开始在入口处
	int c; //用来接收按键
	int  curr_step = 0;
	int failflag = 0;
	//右方向
	StepX[0] = 0;
	StepY[0] = 1;
	//左方向
	StepX[2] = 0;
	StepY[2] = -1;
	//下方向
	StepX[1] = -1;
	StepY[1] = 0;

	//上方向
	StepX[3] = 1;
	StepY[3] = 0;
	for (int i = 0; i < Height + 2; i++)
		for (int j = 0; j < Width + 2; j++)
			mask[i][j] = 0;

	for (int i = 0; i < (Height + 2)*(Width + 2) + 10; i++)
	{
		RecordX[i] = 0;
		RecordY[i] = 0;
		RecordFX[i] = 0;
	}

	RecordX[0] = x;
	RecordY[0] = y;
	RecordFX[0] = 0;
	mask[x][y] = 1;
	c = 0;
	while (failflag == 0)
	{
		gotoxy(2 * y - 2, x - 1);
		printf("●"); //画出玩家当前位置
		if (map[x][y] == End) //判断是否到达出口
		{
			for (int i = 1; i < curr_step; i++)
			{
				x = RecordX[i];
				y = RecordY[i];
				gotoxy(2 * y - 2, x - 1);
				printf("* ");
			}
			gotoxy(30, 24);
			printf("到达终点,按任意键结束");
			_getch();
			break;
		}
		if (c != Auto)
			c = get_key();
		else Sleep(100);

		if (c == Esc)
		{
			gotoxy(0, 24);
			break;
		}
		switch (c)
		{
		case Up: //向上走
			if (map[x - 1][y] != Wall)
			{
				paint(x, y);
				x--;
				curr_step++;
				RecordX[curr_step] = x;
				RecordY[curr_step] = y;
				RecordFX[curr_step] = 0;
			}
			break;
		case Down: //向下走
			if (map[x + 1][y] != Wall)
			{
				paint(x, y);
				x++;
				curr_step++;
				RecordX[curr_step] = x;
				RecordY[curr_step] = y;
				RecordFX[curr_step] = 0;
			}
			break;
		case Left: //向左走
			if (map[x][y - 1] != Wall)
			{
				paint(x, y);
				y--;
				curr_step++;
				RecordX[curr_step] = x;
				RecordY[curr_step] = y;
				RecordFX[curr_step] = 0;
			}
			break;
		case Right: //向右走
			if (map[x][y + 1] != Wall)
			{
				paint(x, y);
				y++;
				curr_step++;
				RecordX[curr_step] = x;
				RecordY[curr_step] = y;
				RecordFX[curr_step] = 0;
			}
			break;
		case Auto:
			//自动走
			if (1)
			{
				int mflag = 0;
				for (int m = RecordFX[curr_step]; m < 4; m++)
				{
					int x1, y1;
					x1 = x + StepX[m];
					y1 = y + StepY[m];
					if (map[x1][y1] != Wall && mask[x1][y1] == 0)
					{
						paint(x, y);

						x = x1;
						y = y1;
						RecordFX[curr_step] = m;
						curr_step++;
						RecordX[curr_step] = x;
						RecordY[curr_step] = y;
						mask[x][y] = 1;
						RecordFX[curr_step] = 0;
						mflag = 1;
						break;
					}
					else RecordFX[curr_step] = m;
				}
				if (mflag == 0)
				{

					while (curr_step >= 0 && RecordFX[curr_step] == 3)
					{
						paint(x, y);
						mask[x][y] = 0;
						curr_step = curr_step - 1;
						x = RecordX[curr_step];
						y = RecordY[curr_step];
					}
					if (curr_step >= 0)
					{
						paint(x, y);
						mask[x][y] = 0;
						curr_step = curr_step - 1;
						x = RecordX[curr_step];
						y = RecordY[curr_step];

						RecordFX[curr_step] = RecordFX[curr_step] + 1;
					}


				}
			}
			break;
		}
		if (curr_step == 0 && RecordFX[curr_step] == 4)
		{
			gotoxy(30, 24);
			printf("无法到达终点,按任意键结束");
			_getch();
			break;
		}

	}
}
int main()
{
	system("maze demo ");
	int i, j;
	srand((unsigned)time(NULL)); //初始化随即种子
	hidden(); //隐藏光标
	for (i = 0; i <= Height + 1; i++)
		for (j = 0; j <= Width + 1; j++)
			if (i == 0 || i == Height + 1 || j == 0 || j == Width + 1) //初始化迷宫
				map[i][j] = Road;
			else map[i][j] = Wall;

	create(2 * (rand() % (Height / 2) + 1), 2 * (rand() % (Width / 2) + 1)); //从随机一个点开始生成迷宫,该点行列都为偶数
	for (i = 0; i <= Height + 1; i++) //边界处理 
	{
		map[i][0] = Wall;
		map[i][Width + 1] = Wall;
	}

	for (j = 0; j <= Width + 1; j++) //边界处理
	{
		map[0][j] = Wall;
		map[Height + 1][j] = Wall;
	}
	map[2][1] = Start; //给定入口
	map[Height - 1][Width] = End; //给定出口
	for (i = 1; i <= Height; i++)
		for (j = 1; j <= Width; j++) //画出迷宫
			paint(i, j);
	game(); //开始游戏
	_getch();
	return 0;
}


// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

在这里插入图片描述
在这里插入图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值