Fork me on GitHub

Cmaze

// ConsoleApplication12.cpp : 定义控制台应用程序的入口点。
//

#include “stdafx.h”

#include #include #include #include #include #include #define MAXSIZE 5000
using namespace std;

struct point {
int x;
int y;
point(int x0 = 0, int y0 = 0):x(x0),y(y0) {}
point(point& p) {
this->x = p.x;
this->y = p.y;
}
bool operator==(point& p){
return this->x == p.x&&this->y == p.y;
}
bool operator!=(point& p) {
return !(this == p);
}
};
int direction[8][2] = { { 1,1 },{ 1,-1 },{ -1,1 },{ -1,-1 } ,{1,0},{0,1},{-1,0},{0,-1}};
struct stkpoint {
point
p;
int dir;
stkpoint(point poi = NULL) :p(poi), dir(0) {};
bool operator==(stkpoint&q){
return
(this->p) == (q.p);
}
};
templateclass pointStack {
T
vendor;
int top;
public:
pointStack() {
vendor = new T[MAXSIZE];
top = -1;
}
void push(T p) {
vendor[++top] = p;
}
T pop() {
if (top == -1) { cout << “empty”; exit(0); }
return vendor[top–];
}
point operator[](int index) {
return T[index];
}
bool IsIn(T q) {
for (int i = 0; i <= top; i++) {
if (vendor[i] == q) {
return true;
}
}
return false;
}
int getTop() {
return top;
}
};
class puzzle {
int** puz;
//pointStack path;
int length;
protected:
void opendoor(int x1, int y1, int x2, int y2) {
if (puz[length - 1][length - 1] == 1)puz[length - 1][length - 1] = 0;
if (x1 == x2) {
int pos = y1 + rand() % ((y2 - y1) / 2 + 1)
2;
if (pos >= length)pos–;
puz[x1][pos] = 0;
}
else if (y1 == y2) {
int pos = x1 + rand() % ((x2 - x1) / 2 + 1) 2;
if (pos >= length)pos–;
puz[pos][y1] = 0;
}
else {
cout << “error!” << endl;
exit(0);
}
//cout << “opened” << endl;
}
void formpuzzle(int x, int y, int height, int width, bool ans) {
if (ans) {
print(2);
system(“cls”);
}
int xpos, ypos;
if (height <= 2 || width <= 2)
{
//cout << “finished one step” << endl;
return;
}
xpos = x + rand() % ((height) / 2)
2 + 1;
for (int i = y; i < y + width; i++) {
puz[xpos][i] = 1;
}
ypos = y + rand() % ((width) / 2) * 2 + 1;
for (int i = x; i < x + height; i++) {
puz[i][ypos] = true;
}
int isClosed = rand() % 4 + 1;
switch (isClosed)
{
case 1:
opendoor(xpos + 1, ypos, x + height - 1, ypos);// 2
opendoor(xpos, ypos + 1, xpos, y + width - 1);// 3
opendoor(x, ypos, xpos - 1, ypos);// 4
break;
case 2:
opendoor(xpos, ypos + 1, xpos, y + width - 1);// 3
opendoor(x, ypos, xpos - 1, ypos);// 4
opendoor(xpos, y, xpos, ypos - 1);// 1
break;
case 3:
opendoor(x, ypos, xpos - 1, ypos);// 4
opendoor(xpos, y, xpos, ypos - 1);// 1
opendoor(xpos + 1, ypos, x + height - 1, ypos);// 2
break;
case 4:
opendoor(xpos, y, xpos, ypos - 1);// 1
opendoor(xpos + 1, ypos, x + height - 1, ypos);// 2
opendoor(xpos, ypos + 1, xpos, y + width - 1);// 3
break;
default:
break;
}

    // 左上角
    formpuzzle(x, y, xpos - x, ypos - y, ans);
    // 右上角
    formpuzzle(x, ypos + 1, xpos - x, width - ypos + y - 1, ans);
    // 左下角
    formpuzzle(xpos + 1, y, height - xpos + x - 1, ypos - y, ans);
    // 右下角
    formpuzzle(xpos + 1, ypos + 1, height - xpos + x - 1, width - ypos + y - 1, ans);
}
bool go(int x, int y, bool ans) {//递归算法
    if (ans) { print(); system("cls"); };
    if (puz\[x\]\[y\] != 0)return false;
    point *p = new point(x, y);
    //if (!path.IsIn(\*p))path.push(\*p);
    puz\[x\]\[y\] = 2;

    if (x == length - 1 && y == length - 1) { return true; }
    if (x < length - 1)
        if (puz\[x+1\]\[y\]!=2 && go(x + 1, y, ans))
            return true;
    if (y < length - 1)
        if (puz\[x\]\[y+1\]!=2 && go(x, y + 1, ans))
            return true;
    if (x > 0)
        if (puz\[x-1\]\[y\]!=2 && go(x - 1, y, ans))
            return true;
    if (y > 0)
        if (puz\[x\]\[y-1\]!=2 && go(x, y - 1, ans))
            return true;



    //path.pop();
    puz\[x\]\[y\] = 3;
    return false;
}

public:
puzzle(int n):length(n) {
puz = new int*[n];
for (int i = 0; i < n; i++) {
puz[i] = new int[n] {0};
}
}
void print(int time=0) {
for (int i = 0; i < length + 2; i++) {

        for (int j = 0; j < length + 2; j++) {
            if (i == 0 || j == 0 || i == length + 1 || j == length + 1) {
                    setfillcolor(BROWN);
                    fillrectangle(10 * i, 10 * j, 10 * (i + 1), 10 * (j + 1));
            }
            else {
                if (puz\[i - 1\]\[j - 1\] == 1) {
                        setfillcolor(RED);
                        fillrectangle(10 * i, 10 * j, 10 * (i + 1), 10 * (j + 1));
                }
                else if (puz\[i - 1\]\[j - 1\] == 2) {
                    setfillcolor(YELLOW);
                    fillcircle(10 * i+5, 10 * j+5, 5);

                }
                else if (puz\[i - 1\]\[j - 1\] == 3) {
                    setfillcolor(BLUE);
                    fillrectangle(10 * i, 10 * j, 10 * (i + 1), 10 * (j + 1));
                }
                else {
                        setfillcolor(GREEN);
                        fillrectangle(10 * i, 10 * j, 10 * (i + 1), 10 * (j + 1));
                }
            }
        }
        cout << endl;

    }
}

void mk(bool ans=1) {
    formpuzzle(0, 0, length, length, ans);
}
void go_loop() {//非递归算法
    pointStack s;
    stkpoint w;
    w.p = new point(0, 0);
    point *q;
    while (true) {
        bool poped = false;
        if (puz\[w.p->x\]\[w.p->y\] ==0) {
            puz\[w.p->x\]\[w.p->y\] = 2;
            //print();
            s.push(w);
        }
        else {
            poped = true;
            w = s.pop();
            w.dir++;
        }
        if (w.p->x == length - 1 && w.p->y == length - 1)break;
        if (w.dir < 8) {
            if (poped)s.push(w);
            if (w.p->x + direction\[w.dir\]\[0\] < length&&w.p->x + direction\[w.dir\]\[0\] >= 0 && w.p->y + direction\[w.dir\]\[1\] < length&&w.p->y + direction\[w.dir\]\[1\] >= 0) {
                q = new point(w.p->x + direction\[w.dir\]\[0\], w.p->y + direction\[w.dir\]\[1\]);
                w.p = q;
                w.dir = 0;
            }
        }
        else {
            puz\[w.p->x\]\[w.p->y\] = 3;
            if (!poped)s.pop();
        }
    }
}
void search(bool ans=1) {
    go(0, 0, ans);

}

};
int main() {
int n,ans1,ans2;
cout << “请输入你需要的地图维度:”;
cin >> n;
cout << “是否需要输出创建过程?”;
cin >> ans1;
cout << “是否需要输出寻迹过程?”;
cin >> ans2;
srand(time(0));
int t = 2 n + 1;
initgraph(10
(t+2), 10 * (t+2));
puzzle puzz(t);
setfillcolor(YELLOW);
setbkcolor(BLUE);
puzz.print(1);
puzz.mk(ans1);
puzz.print(1);
if (!ans1)Sleep(1000);
//puzz.search(ans2);
puzz.go_loop();
puzz.print();
getchar();
getchar();
return 0;
}