由于种子寻路的方向是固定的,所以生成的迷宫比较规律。若希望生成更合理的迷宫地图,应该使种子随机向四周进行探索。
下附代码可以实现M*N个格子的迷宫生成。
#include<GL\freeglut.h>
#include<iostream>
#include<ctime>
using namespace std;
void myinit()
{
// attributes
glClearColor(1.0, 1.0, 1.0, 1.0);//设置背景颜色
glColor3f(1.0, 0.0, 0.0);//设置绘画颜色
// set up viewing
glMatrixMode(GL_PROJECTION); //当前操作的矩阵为“模型视图矩阵”,GL_PROJECTION表示设置为投影矩阵
glLoadIdentity(); //把当前矩阵设置为单位矩阵
gluOrtho2D(0, 1000, 0 , 1000); //设置窗口坐标范围(0.0, 50.0, 0.0, 50.0)-->(0.0, 500, 0.0, 500)
glMatrixMode(GL_MODELVIEW);
glPointSize(1);
}
void lineDDA() {
glBegin(GL_POINTS); //开始绘画,并把每一个点当做顶点来处理
int randNum = 1;
clock_t star_time, end_time;
star_time = clock();
for (int i = 0; i < randNum; ++i) {
//int x0 = rand() % 500;
//int x1 = rand() % 500;
//int y0 = rand() % 500;
//int y1 = rand() % 500;
int x0 = 0, y0 = 0;
int x1 = 500, y1 = 500;
int dx = x1 - x0, dy = y1 - y0, step, k;
float x_inc, y_inc, x = x0, y = y0;
if (abs(dx) > abs(dy)) step = abs(dx); //此处要加绝对值,否则dx或dy小于0时可能不画
else step = abs(dy);
x_inc = float(dx) / step, y_inc = float(dy) / step;
for (k = 0; k <= step; ++k) {
glVertex2i(floor(x + 0.5), floor(y + 0.5));
x += x_inc, y += y_inc;
}
}
glEnd();
glFlush();//清空缓存
end_time = clock();
std::cout << "total time:" << end_time - star_time << std::endl;
}
void lineDDA(int x0, int y0, int x1, int y1) {
glBegin(GL_POINTS); //开始绘画,并把每一个点当做顶点来处理
int dx = x1 - x0, dy = y1 - y0, step, k;
float x_inc, y_inc, x = x0, y = y0;
if (abs(dx) > abs(dy)) step = abs(dx); //此处要加绝对值,否则dx或dy小于0时可能不画
else step = abs(dy);
x_inc = float(dx) / step, y_inc = float(dy) / step;
for (k = 0; k <= step; ++k) {
glVertex2i(floor(x + 0.5), floor(y + 0.5));
x += x_inc, y += y_inc;
}
glEnd();
glFlush();//清空缓存
}
void swap(int& a, int& b) {
int temp = a;
a = b; b = temp;
}
int M, N;
int edgelen;
int** reachMatrix;
bool Reach(int x, int y) {//判断是否到达过
if (x >= M || x < 0 || y >= N || y < 0) return true;
return reachMatrix[x][y];
};
void Flood_Fill_4(int i, int j) //(x,y)是种子
{
reachMatrix[i][j] = 1;
if (!Reach(i - 1, j)) {//下面能走
lineDDA(j * edgelen, i * edgelen, (j+1) * edgelen, i * edgelen);
Flood_Fill_4(i - 1, j);
}
if (!Reach(i, j - 1)) {//左边能走
lineDDA(j * edgelen, i * edgelen, j * edgelen, (i+1) * edgelen);
Flood_Fill_4(i, j - 1);
}
if (!Reach(i + 1, j)) {//上面能走
lineDDA(j * edgelen, (i + 1) * edgelen, (j + 1) * edgelen, (i + 1) * edgelen);
Flood_Fill_4(i + 1, j);
}
if (!Reach(i, j + 1)) {//右边能走
lineDDA((j+1) * edgelen, i * edgelen, (j+1) * edgelen, (i + 1) * edgelen);
Flood_Fill_4(i, j + 1);
}
}
void maze() {
edgelen = 40;//设置小方格边长
M = 20, N = 15;//设置迷宫规格
reachMatrix = new int* [M];
for (int i = 0; i < M; ++i) {//0是墙
reachMatrix[i] = new int[N];
}
for (int i = 0; i < M; ++i) {
for (int j = 0; j < N; ++j) {
reachMatrix[i][j] = 0;
}
}
glColor3f(1.0, 0.0, 0.0);//设置绘画颜色
for (int i = 0; i <= M; ++i) {//画横线
lineDDA(0, i * edgelen, N * edgelen, i * edgelen);
}
for (int i = 0; i <= N; ++i) {//画竖线
lineDDA(i * edgelen, 0, i * edgelen, M*edgelen);
}
glColor3f(0.0, 0.0, 0.0);//设置绘画颜色
Flood_Fill_4(8, 8);
lineDDA(0, M * edgelen, 1*edgelen, M * edgelen);
lineDDA(N*edgelen, 0, N * edgelen, 1 * edgelen);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv); //初始化GLUT库
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //选择缓冲区模式和颜色模式
//glutInitAWindowSize(500, 500) <--是打错了吗?
glutInitWindowSize(500, 500); //设置窗口大小,(int width, int height),单位是像素
glutInitWindowPosition(50, 50); //(0,0)是左上角
glutCreateWindow("Sierpinski Gasket"); //产生一个顶层的窗口.title 作为窗口的名字,也就是窗口标题栏显示的内容
glutDisplayFunc(lineDDA); //程序会自动调用display函数重绘窗口
//glutDisplayFunc(lineBresenham);
glutDisplayFunc(maze);
myinit();
glutMainLoop(); //循环执行主函数,并保持窗口不消失;实际操作起来变成每点击一下窗口运行一次glutDisplayFunc
}