新建一个地图文件,格式如下
maze.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include"maze.h"
#include<fstream>
#include<string>
#include<assert.h>
//新建一个txt文件,里面存一串1,0的数字作为地图。
// 格式如下(必须按照此格式)
//h:14
//l:15
//map:
//01110100001001
//00000001010000
//00101010101001
//11000101000000
//00000010101111
//01111010000000
//00000000010011
//01111100111000
//10000000000001
//01110010001101
//10000011110100
//01011100000000
//11100000010101
//00000110100000
//00111000011010
//读取文件内的内容作为地图
void getmap(maze *lty)
{
FILE* f = fopen("C:\\Users\\luotianyi\\Desktop\\map.txt","rb+");
if (f)
{
cout << "打开文件成功" << endl;
}
else
{
cout << "打开文件失败" << endl;
perror("open file fail");
return;
}
int hang = 0;
int lie = 0;
while (fgetc(f) != 'h') //读取到 h
{
}
fseek(f, 1, SEEK_CUR); //向后偏移1(跳过:)
int k = 0; //用来接收字符串转int的值
string han; //读取的行存在这里面
while ((k = fgetc(f)) >= 48 && k <= 57) //往后读取到的数字字符都追加进han里
{
han += k;
}
hang=std::stoi(han); //string转int
lty->h = hang;
while (fgetc(f) != 'l')//读取到 l
{
}
fseek(f, 1, SEEK_CUR); //向后偏移1(跳过:)
k = 0;
string li; //读取到的列存到这里面
while ((k = fgetc(f)) >= 48 && k <= 57) //往后读取到的数字字符追加进li里
{
li += k;
}
lie = std::stoi(li); //string转int之后存进lie里
lty->l = lie;
int** t = new int* [hang];
for (int k = 0; k < hang; k++) //创建二维数组当做地图
{
t[k] = new int[lie];
}
while (fgetc(f) != 'p')//读取到 p
{
}
k = 0;
while (k< 48 || k > 57) //map:找完找下一排.
{
k = fgetc(f);
}
fseek(f, -1, SEEK_CUR); //向前偏移1 ,指针走到数字字符前面
for (int x = 0; x < hang; x++)
{
printf("第%d排\n", x); //查看地图每一排
for (int y = 0; y < lie; y++)
{
auto k = fgetc(f)-48;
t[x][y] = k;
printf("%d ", k); //查看每次获取的地图块儿
}
cout << endl;
k = 0;
while ((k < 48 || k > 57)&&k!=EOF) //map:找完找下一排.EOF文件结束标志
{
k = fgetc(f);
}
fseek(f, -1, SEEK_CUR); //向前偏移1 ,指针走到数字字符前面
}
lty->lty = t;
fclose(f);
f = nullptr;
}
void test()
{
int a = 15; //地图的长宽
int b = 14;
stack yyy; //栈
stinit(&yyy);
stack minyyy; //最小路径栈
stinit(&minyyy);
maze lty(0,0);
getmap(<y); //获取地图
lty.look(); //查看地图
cout << endl << endl;
pos cur(0, 0); //当前位置类
getpath(lty.lty, lty.h, lty.l, cur, &yyy, &minyyy); //走迷宫,获取路径
if (minyyy.top == 0) //如果最小路径栈里没有数据
{
cout << "没有通路" << endl;
}
else
{
cout << "最少多少步可以走到:" << minyyy.top << endl << endl;;
for (int k = 0; k <= minyyy.top - 1; k++)
{
cout << '[' << minyyy.lty[k].l + 1 << "," << minyyy.lty[k].h + 1 << ']' << " -> ";
}
}
delete[] yyy.lty;
yyy.lty = nullptr;
yyy.top = yyy.capacity = 0;
delete[] minyyy.lty;
minyyy.lty = nullptr;
minyyy.top = minyyy.capacity = 0;
}
int main()
{
test();
return 0;
}
maze.h
#pragma once
#include<iostream>
using namespace std;
#include<assert.h>
class maze
{
public:
maze(int a,int b);
~maze();
void look(); //查看地图
int h; //行
int l; //列
int** lty; //地图数组
};
maze::maze(int a=0,int b=0) //构造地图
:h(a),l(b),lty(nullptr)
{
}
maze::~maze() //析构地图
{
for (int k = 0; k < h; k++)
{
delete[]lty[k];
lty[k] = nullptr;
}
delete[] lty;
lty = nullptr;
h = l = 0;
}
void maze::look() //看看地图
{
cout << endl;
for (int m = 0; m < h; m++)
{
for (int n = 0; n < l; n++)
{
printf("%-2d ", lty[m][n]);
}
cout << endl;
}
cout << endl;
}
class pos //位置类(当前位置/下一个位置)
{
public:
pos(int a=0, int b=0)
:h(a), l(b)
{
}
int h; //行
int l; //列
};
typedef struct stack //栈,用来储存走过的路径
{
pos* lty; //一个储存位置的数组指针,每个元素是pos(一个坐标)
int top; //栈顶的下一个位置
int capacity; //栈空间大小
}stack;
void stinit(stack*a,int b=20) //初始化栈,默认初始化20个空间
{
a->lty = new pos[b];
a->capacity = b;
a->top = 0;
}
void stacket(stack *a) //栈扩容
{
if (a->capacity == a->top)
{
pos* temp= (pos*)realloc(a->lty, a->capacity * 1.5 * sizeof(pos));
if (temp == nullptr)
{
assert(temp);
}
a->lty = temp;
a->capacity = 1.5 * a->capacity;
}
}
void push(stack *a,pos b) //入栈
{
stacket(a);
a->lty[a->top] = b;
a->top++;
}
void pop(stack* a) //出栈
{
a->top--;
}
bool ispass(int** lty, int n, int m, pos next) //下一个坐标next能否走通
{
if (next.h >= 0 && next.h <= n - 1
&& next.h >= 0 && next.l <= m - 1
&& lty[next.h][next.l] == 0
)
{
return true;
}
else
{
return false;
}
}
void getpath(int** lty, int n, int m, pos cur, stack* a,stack*min) //走迷宫,获取路径
{
push(a, cur); //起点坐标入栈,每次递归进来,相当于以新的当前坐标为起点
if (cur.h == n - 1 && cur.l == m - 1) //如果到了终点
{
if (min->top == 0||min->top>a->top) //如果最小路径栈==0或者最小步数大于当前步数
{
min->top = 0; //将最小路径栈置0
for (int k = 0; k < a->top; k++) //把当前路径栈拷贝到最小路径栈上
{
pos temp;
temp.h = a->lty[k].h;
temp.l = a->lty[k].l;
push(min, temp);
}
}
}
pos next(0, 0);
lty[cur.h][cur.l] = 2;
//上
next = cur;
next.h -= 1;
if (ispass(lty, n, m, next))
{
getpath(lty, n, m, next, a, min);
//cout << next.h << " " << next.l << endl;
}
//下
next = cur;
next.h += 1;
if (ispass(lty, n, m, next))
{
getpath(lty, n, m, next, a, min);
//cout << next.h << " " << next.l << endl;
}
//左
next = cur;
next.l -= 1;
if (ispass(lty, n, m, next))
{
getpath(lty, n, m, next, a, min);
//cout << next.h << " " << next.l << endl;
}
//右
next = cur;
next.l += 1;
if (ispass(lty, n, m, next))
{
getpath(lty, n, m, next, a, min);
//cout << next.h << " " << next.l << endl;
}
lty[cur.h][cur.l] = 0; //走过的路径置0
pop(a); //递归结束出栈
}