C++实践 走出迷宫

c和c++学了快一个学期了,感觉也编不出什么像样的程序,不是解决数学问题就是打印图形,感觉没什么劲。今天找了一个有趣的题目来做做,这是imooc上老师布置的一个案例。先不管算法好坏,来实现一个人走出迷宫的程序,要求能在屏幕上显示出人在走迷宫,并显示出走了几步。

第一次写这种面向对象的程序,很多地方写得都比较臃肿orz,枚举类型也不太会用,实践中遇到了各种各样的困难,暴露了我好多知识的漏洞,但最终还是一一克服了,这种感觉真的是挺好的,我以后还是要多做一些这样的实践才行,其实编这样的程序真的挺有趣的hh


先给个实现后的效果图吧

此处应有图片

设计思路:

定义两个类,分别来表示人和迷宫。迷宫用数组来表示,迷宫的墙用1来表示,路用0来表示。

小人通过右手法则走迷宫,每次先判断右手边的是不是墙,如果不是就往右走,否则就往左转,再继续判断右手边是否为墙,一直循环,直到走出迷宫为止。

代码:

头文件maze.h 用来定义枚举类型方向和速度,常量路、墙,还有坐标的结构体

#pragma once

enum direction { up, right, down, left }; //方向
enum speed { FAST = 100, NORMAL = 300, SLOW = 500 }; //速度
const int ROAD = 0; //路
const int WALL = 1; //墙
struct POX { //坐标
	int x;
	int y;
};


头文件MyMazer.h 用来声明人类

#pragma once
#include "maze.h"
#include "MyMazeMap.h"


class MyMazeMap;
class MyMazer
{
public:
	
	MyMazer(int x = 0, int y = 0, speed s = NORMAL, direction d = direction::right, char Person_Char = 'T');
	//构造函数,初始化数据成员
	void setPersonPosition(int x, int y);	//设置人物位置
	void setPersonDirection(direction d);	//设置人物朝向
	void setPersonSpeed(speed s);		//设置人物速度
	void setPersonChar(char c);		//设置人物符号
	void setMap(MyMazeMap *m);		//设置地图对象
	void start();				//开始游戏
	void turn(int d = 0);			//转向 d=0顺时针 d=1逆时针
	void gotoxy(int x, int y);		//移动光标到(x,y)
	void move();				//向前移动人物移动
	void display();			        //更新人物在屏幕上的位置
	direction getManRightSide();		//返回人物的右侧方向
private:
	char m_cPerson;			//人物字符
	direction m_dDirection;		//人物朝向
	speed m_sSpeed;			//人物速度
	POX m_sPosition;		//人物当前位置
	POX m_sLastPosition;		//人物上次的位置,为了制作动画效果
	MyMazeMap *m_pcMap;		//地图对象
	int m_iSteps;			//步数
};


头文件MyMazeMap.h 用来声明迷宫类

#pragma once
#include "maze.h"
#include  "MyMazer.h"


class MyMazeMap
{
public:
	MyMazeMap();					//构造函数,初始化数据成员
	void setMazeMap(int* map, int r, int c);	//设置地图,高,宽
	void setMazeWall(char wall);			//设置墙的符号
	void drawMap();					//绘制地图
	bool isMazeBound(int x, int y, direction d);	//判断(x,y)的d方向上是否是墙
	bool isBound(int x, int y);			//判断(x,y)是否是墙
	bool isOut(int x, int y);			//判断是否走出迷宫
	int getR();					//返回地图高
	int getC();					//返回的图宽
private:
	char m_cWall;	//墙的符号
	char m_cRoad;	//路的符号
	int m_r;	//高
	int m_c;	//宽
	int* m_piMap;	//地图
};



源文件MyMazer.cpp 用来实现MyMazer类的成员函数

#include "MyMazer.h"
#include <Windows.h>
#include <iostream>

MyMazer::MyMazer(int x, int y, speed s, direction d, char Person_Char) :m_sPosition{ x,y }, m_sSpeed(s), m_dDirection(d), m_cPerson(Person_Char)
{ //初始化
	m_sLastPosition = m_sPosition;
	m_pcMap = NULL;
	m_iSteps = 0;
}

void MyMazer::setPersonPosition(int x, int y)
{ //设置人物的位置
	m_sPosition.x = x;
	m_sPosition.y = y;
}

void MyMazer::setPersonDirection(direction d)
{ //设置人物的朝向
	m_dDirection = d;
}

void MyMazer::setPersonSpeed(speed s)
{ //设置人物的速度
	m_sSpeed = s;
}

void MyMazer::setPersonChar(char c)
{ //设置人物字符
	m_cPerson = c;
}

void MyMazer::setMap(MyMazeMap * m)
{ //设置地图对象
	m_pcMap = m;
}

void MyMazer::start()
{ //游戏开始,使用右手规则走迷宫
	if (!m_pcMap) {
		std::cout << "You haven't set map, please use setMap() to continue" << std::endl;
		return;
	}
	gotoxy(m_sPosition.x, m_sPosition.y);
	std::cout << m_cPerson;
	while (1) {
		while(m_pcMap->isMazeBound(m_sPosition.x, m_sPosition.y, getManRightSide())) {
			turn(1);
		}
		turn();
		move();
		if (m_pcMap->isOut(m_sPosition.x, m_sPosition.y)) break;
		display();
	}
	gotoxy(0, m_pcMap->getR());
	std::cout << "闯关成功!!!" << std::endl << "总共走了" << m_iSteps << "步" << std::endl;
}

void MyMazer::turn(int d)
{
	if (d == 0) { //顺时针转向
		if (m_dDirection == direction::up) m_dDirection = direction::right;
		else if (m_dDirection == direction::right) m_dDirection = direction::down;
		else if (m_dDirection == direction::down) m_dDirection = direction::left;
		else m_dDirection = direction::up;
	}
	else { //逆时针转向
		if (m_dDirection == direction::up) m_dDirection = direction::left;
		else if (m_dDirection == direction::left) m_dDirection = direction::down;
		else if (m_dDirection == direction::down) m_dDirection = direction::right;
		else m_dDirection = direction::up;
	}
}

void MyMazer::gotoxy(int x, int y)
{ //将光标移动至(x,y)
	if (x < 0 || y < 0) return;
	COORD cd;
	cd.X = x;
	cd.Y = y;
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(handle, cd);
}

void MyMazer::move()
{ //向前移动一步
	m_sLastPosition = m_sPosition;
	switch (m_dDirection) {
	case direction::up: m_sPosition.y--; break;
	case direction::right: m_sPosition.x++; break;
	case direction::down: m_sPosition.y++; break;
	case direction::left: m_sPosition.x--; break;
	}
	m_iSteps++;
}

void MyMazer::display()
{ //显示函数
	Sleep(m_sSpeed);
	gotoxy(m_sLastPosition.x, m_sLastPosition.y);
	std::cout << " ";
	gotoxy(m_sPosition.x, m_sPosition.y);
	std::cout << m_cPerson;
	gotoxy(0, m_pcMap->getR());
	std::cout << "已经走了" << m_iSteps << "步了" << std::endl;
}

direction MyMazer::getManRightSide()
{ //读取人物朝向右侧的方向
	direction ret;
	switch (m_dDirection) {
	case direction::up:ret = direction::right; break;
	case direction::right:ret = direction::down; break;
	case direction::down:ret = direction::left; break;
	case direction::left:ret = direction::up; break;
	}
	return ret;
}




源文件MyMazeMap.cpp 用来实现MyMazeMap类的成员函数

#include "MyMazeMap.h"
#include <iostream>
#include <cstdlib>

MyMazeMap::MyMazeMap()
{ //初始化数据成员
	m_c = 0;
	m_r = 0;
	m_cRoad = ' ';
	m_cWall = '*';
}

void MyMazeMap::setMazeMap(int * map, int r, int c)
{ //设置迷宫
	m_piMap = map;
	m_r = r;
	m_c = c;
}

void MyMazeMap::setMazeWall(char wall)
{ //设置表示墙的符号
	m_cWall = wall;
}

void MyMazeMap::drawMap()
{ //绘制地图
	system("cls");
	for (int i = 0; i < m_r; i++) {
		for (int j = 0; j < m_c; j++) {
			if (*(m_piMap + m_c*i + j) == WALL) std::cout << m_cWall;
			else std::cout << m_cRoad;
		}
		std::cout << std::endl;
	}
}

bool MyMazeMap::isMazeBound(int x, int y, direction d)
{ //判断面前的是不是墙
	bool Bound = false;
	switch (d) {
	case direction::up:
		if (isBound(x, y - 1)) Bound = true;
		break;
	case direction::right:
		if (isBound(x + 1, y)) Bound = true;
		break;
	case direction::down:
		if (isBound(x, y + 1)) Bound = true;
		break;
	case direction::left:
		if (isBound(x - 1, y)) Bound = true;
		break;
	}
	return Bound;
}

bool MyMazeMap::isBound(int x, int y)
{ //判断(x,y)是不是墙
	if (isOut(x,y)) return false;
	if (*(m_piMap + m_c*y + x) == WALL) return true;
	return false;
}

bool MyMazeMap::isOut(int x, int y)
{ //判断是否走出迷宫
	if (x > m_c - 1 || x<0 || y> m_r - 1 || y < 0) return true;
	return false;
}

int MyMazeMap::getR()
{ //返回迷宫的行数
	return m_r;
}

int MyMazeMap::getC()
{ //返回迷宫的列数
	return m_c;
}



最后就是源文件maze.cpp了 main函数在这里呢

#include <iostream>
#include <cstdlib>
#include "maze.h"
#include "MyMazeMap.h"
#include "MyMazer.h"

using namespace std;

const int SUCCESS = 0;
int main()
{
	int map[10][18] = {
					{ WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL, },
					{ WALL,ROAD,WALL,WALL,WALL,WALL,WALL,WALL,WALL,ROAD,ROAD,ROAD,ROAD,WALL,WALL,WALL,WALL,WALL, },
					{ WALL,ROAD,ROAD,WALL,WALL,WALL,WALL,WALL,WALL,ROAD,WALL,WALL,ROAD,WALL,WALL,WALL,ROAD,WALL, },
					{ WALL,WALL,ROAD,WALL,WALL,WALL,WALL,WALL,WALL,ROAD,WALL,WALL,ROAD,WALL,WALL,WALL,ROAD,WALL, },
					{ WALL,WALL,ROAD,ROAD,ROAD,ROAD,ROAD,ROAD,ROAD,ROAD,ROAD,WALL,ROAD,WALL,ROAD,ROAD,ROAD,WALL, },
					{ WALL,WALL,ROAD,WALL,ROAD,WALL,WALL,WALL,ROAD,WALL,ROAD,ROAD,ROAD,WALL,ROAD,WALL,WALL,WALL, },
					{ WALL,ROAD,ROAD,WALL,ROAD,WALL,WALL,WALL,ROAD,WALL,WALL,ROAD,WALL,WALL,ROAD,WALL,WALL,WALL, },
					{ WALL,ROAD,WALL,WALL,ROAD,WALL,WALL,WALL,ROAD,WALL,WALL,ROAD,WALL,WALL,ROAD,WALL,WALL,WALL, },
					{ WALL,ROAD,WALL,WALL,ROAD,WALL,WALL,WALL,ROAD,WALL,WALL,ROAD,ROAD,ROAD,ROAD,WALL,WALL,WALL, },
					{ WALL,ROAD,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL,WALL, },
	};
	MyMazeMap maze;
	maze.setMazeMap(&map[0][0], 10, 18); //设置地图
	maze.drawMap(); //绘制地图
	MyMazer mazer;
	mazer.setPersonPosition(16, 2); //设置开始时人物位置
	mazer.setPersonDirection(direction::up); //设置开始时人物朝向 up right down left
	mazer.setPersonSpeed(FAST); //设置速度 FAST NORMAL SLOW
	mazer.setPersonChar('#'); //设置表示人的字符
	mazer.setMap(&maze); //设置人物所在地图
	mazer.start(); //游戏开始
	system("pause");
	return SUCCESS;
}

以上,就是走出迷宫的所有代码了

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现自动生成并走出迷宫的功能,可以使用深度优先搜索(DFS)算法和迷宫生成算法。下面是一个简单的实现过程。 1. 迷宫生成算法 使用递归分割法生成迷宫。将整个迷宫划分为四个矩形,然后随机选择一堵墙将两个矩形连接起来,重复上述过程直到所有的矩形都被划分成为单元格。最后,将入口和出口随机放置在迷宫的边缘。 2. DFS算法 从入口开始进行深度优先搜索,标记已经访问过的单元格,直到找到出口为止。如果遇到无法通过的墙壁或已经访问过的单元格,则返回上一层继续搜索。 3. 实现代码 以下是一个简单的C++代码实现: ```cpp #include <iostream> #include <vector> #include <stack> #include <stdlib.h> #include <time.h> using namespace std; const int N = 10; // 迷宫大小 int maze[N][N]; // 迷宫矩阵 int start_x, start_y, end_x, end_y; // 入口和出口坐标 // 递归分割法生成迷宫 void generate_maze(int x1, int y1, int x2, int y2) { if (x2 <= x1 || y2 <= y1) return; int mx = (x1 + x2) / 2; int my = (y1 + y2) / 2; if (rand() % 2 == 0) // 随机选择一堵墙 { for (int i = y1; i < y2; i++) maze[mx][i] = 1; int hole = rand() % (y2 - y1) + y1; maze[mx][hole] = 0; generate_maze(x1, y1, mx, hole); generate_maze(x1, hole+1, mx, y2); } else { for (int i = x1; i < x2; i++) maze[i][my] = 1; int hole = rand() % (x2 - x1) + x1; maze[hole][my] = 0; generate_maze(x1, y1, hole, my); generate_maze(hole+1, y1, x2, my); } } // 深度优先搜索 bool dfs(int x, int y) { if (x == end_x && y == end_y) return true; if (maze[x][y] == 1) return false; maze[x][y] = 1; // 标记已经访问过的单元格 if (x > 0 && dfs(x-1, y)) return true; if (x < N-1 && dfs(x+1, y)) return true; if (y > 0 && dfs(x, y-1)) return true; if (y < N-1 && dfs(x, y+1)) return true; return false; } int main() { srand(time(NULL)); generate_maze(0, 0, N, N); start_x = rand() % N; start_y = (rand() % 2 == 0) ? 0 : N-1; end_x = rand() % N; end_y = (rand() % 2 == 0) ? 0 : N-1; maze[start_x][start_y] = 0; maze[end_x][end_y] = 0; cout << "迷宫矩阵:" << endl; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) cout << maze[i][j] << " "; cout << endl; } cout << "入口坐标:" << start_x << " " << start_y << endl; cout << "出口坐标:" << end_x << " " << end_y << endl; if (dfs(start_x, start_y)) cout << "可以走出迷宫!" << endl; else cout << "无法走出迷宫!" << endl; return 0; } ``` 运行程序后,可以看到生成的迷宫矩阵和入口、出口的坐标,以及是否可以走出迷宫

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值