int ** generatemaze(int ** maze, int x, int y)
{ int direction;
maze[x][y] =0; // 標示此格已設定
// Form1->Memo2->Lines->Add("(x,y,dir)="+IntToStr(x)+","+IntToStr(y)+","+IntToStr(direction));
while (maze[x][y+2]==1 || maze[x+2][y]==1 || maze[x][y-2]==1 || maze[x-2][y]==1) // 如果不是外牆
{ direction = rand()%4+1; // 決定下一個位置
if (direction==1 && maze[x][y+2]==1) // 向右走
{ maze[x][y+1] =0; // 拆掉右牆
maze = generatemaze(maze, x,y+2);
}
else if (direction==2 && maze[x-2][y]==1) // 向上走
{ maze[x-1][y] =0; // 拆掉上牆
maze = generatemaze(maze, x-2,y);
}
else if (direction==3 && maze[x][y-2]==1) // 向左走
{ maze[x][y-1] =0; // 拆掉右牆
maze = generatemaze(maze, x,y-2);
}
else if (direction==4 && maze[x+2][y]==1) // 向下走
{ maze[x+1][y] =0; // 拆掉上牆
maze = generatemaze(maze, x+2,y);
}
}
return maze;
}
//--------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{ int i, j;
if (maze) // delete the previous maze
{ for (int i=0; i<m; i++) delete(maze[i]);
delete(maze);
}
m = Edit1->Text.ToInt();
n = Edit2->Text.ToInt();
maze = new int * [m];
for (int i=0; i<m; i++)
{ maze[i] = new int [n];
}
int Start_i=1, Start_j=1, End_i=m-2, End_j=n-2;
int x, y;
// srand(time(NULL));
for (x=0; x<m; x++)
{ for (y=0; y<n; y++)
{ if (x==0 || y==0 || x==m-1 || y==n-1 ) maze[x][y] = 2; // 設定外牆
else maze[x][y] = 1; // 初始迷宮內部
}
}
maze = generatemaze(maze, End_i, End_j); // 產生迷宮
maze[Start_i][Start_j-1] =0; // 拆掉入口左牆
maze[End_i][End_j+1] =0; // 拆掉出口右牆
StringGrid1->RowCount = m;
StringGrid1->ColCount = n;
for (i=0; i<m; i++)
for (j=0; j<n; j++)
StringGrid1->Cells[j][i] = maze[i][j];
}
----------------- 以上用 BCB 完成,以下用 VS 2010 完成 (兩語言對陣列的 boundary checking 不盡相同) -------------------------------
private: System::Void button1_Click_1(System::Object^ sender, System::EventArgs^ e)
{ int i, j;
int Start_i = 1, Start_j = 1, End_i = m-1, End_j = p-1;
if (maze) // delete the previous maze
{ for (i = 0; i < m; i++)
delete [] maze[i];
delete [] maze;
}
m = int::Parse(textBox1 -> Text);
p = int::Parse(textBox2 -> Text);
mazeX = new int * [m+2]; // mazeX 專為產生迷宮而生,大小為 (m+2)*(p+2); 外層乃刻意保留的擋板
for (i = 0; i <= m+1; i++)
mazeX[i] = new int [p+2];
for (i = 0; i <= m+1; i++)
{ for (int j = 0; j <= p+1; j++)
{ if ((i == 0) || (j == 0) || (i == m+1) || (j == p+1))
mazeX[i][j] = 4; // 設定外層刻意保留的擋板
else
mazeX[i][j] = 1; // 初始迷宮 (m*p) 內部
}
}
mazeX = generatemaze(mazeX, End_i, End_j); // 產生迷宮 出口[m-1,p-1]、入口:[2,2]
for (i = 1; i <= m; i++)
{ for (j = 1; j <= p; j++)
{ if ((i == 1) || (j == 1) || (i == m) || (j == p))
mazeX[i][j] = 2; // 設定外牆;之前保留的擋板稍後拆掉
}
}
mazeX[Start_i+1][Start_j] = 0; // 拆掉入口 mazeX[2,2] 的左牆 即 [2,1] (=[Start_i+1, Start_j])
mazeX[End_i][End_j+1] = 0; // 拆掉出口 mazeX[m-1, p-1] 右牆 即 [m-1,p](=[End_i, End_j+1])
maze = new int * [m];
for (i = 0; i < m; i++)
maze[i] = new int [p];
for (i = 0; i < m; i++)
for (j = 0; j < p; j++)
maze[i][j] = mazeX[i+1][j+1]; // 調整入口成為 maze[1,1]、出口 maze[m-2, p-2]
// ... 可將 maze 顯示於 dataGridView 或 richTextBox/listBox 中
for (i = 0; i <= m+1; i++)
delete [] mazeX[i];
delete [] mazeX;
}
# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# include <iostream>
using namespace std;
int ** maze;
int m, n;
int ** generatemaze(int ** maze, int x, int y)
{ int direction;
maze[x][y] = 0; // 標示此格已設定
while ((y+2 < n && maze[x][y+2]==1) || (x+2 < m && maze[x+2][y]==1) || (y-2 > 0 && maze[x][y-2]==1) || (x-2 > 0 && maze[x-2][y]==1)) // 如果不是外牆
{ direction = rand()%4+1; // 決定下一個位置
if (direction==1 && (y+2 < n && maze[x][y+2]==1))// 向右走
{ maze[x][y+1] = 0; // 拆掉右牆
maze = generatemaze(maze, x, y+2);
}
else if (direction==2 && (x-2 > 0 && maze[x-2][y]==1)) // 向上走
{ maze[x-1][y] = 0; // 拆掉上牆
maze = generatemaze(maze, x-2, y);
}
else if (direction==3 && (y-2 > 0 && maze[x][y-2]==1)) // 向左走
{ maze[x][y-1] =0; // 拆掉右牆
maze = generatemaze(maze, x, y-2);
}
else if (direction==4 && (x+2 < m && maze[x+2][y]==1)) // 向下走
{ maze[x+1][y] =0; // 拆掉上牆
maze = generatemaze(maze, x+2,y);
}
}
return maze;
}
int main()
{ int i, j, x, y;
cin >> m >> n;
cout << "m=" << m << ", n=" << n << endl;
maze = new int * [m];
for (i=0; i<m; i++)
{ maze[i] = new int [n];
}
int Start_i=1, Start_j=1, End_i=m-2, End_j=n-2;
srand(time(NULL));
for (x=0; x<m; x++)
{ for (y=0; y<n; y++)
{ if (x==0 || y==0 || x==m-1 || y==n-1 ) maze[x][y] = 2; // 設定外牆
else maze[x][y] = 1; // 初始迷宮內部
}
}
maze = generatemaze(maze, End_i, End_j); // 產生迷宮
maze[Start_i][Start_j-1] =0; // 拆掉入口左牆
maze[End_i][End_j+1] =0; // 拆掉出口右牆
string out, mark;
for (i=0; i<m; i++)
{ for (out = "", j=0; j<n; j++)
{ if (maze[i][j]==2 || maze[i][j]==1) mark = "#";
else mark = ".";
out += mark;
}
cout << out << endl;
}
getchar();
return 0;
}
========================= Visual Studio 2022 ============================
private:
void generate_maze(int x, int y)
{
int direction;
maze[x][y] = 0; // 標示出口
while ((y + 2 < width && maze[x][y + 2] == 1) || (x + 2 < height && maze[x + 2][y] == 1) || (y - 2 > 0 && maze[x][y - 2] == 1) || (x - 2 > 0 && maze[x - 2][y] == 1)) // 如果不是外牆
{
direction = rand() % 4 + 1; // 決定下一個位置
if (direction == 1 && (y + 2 < width && maze[x][y + 2] == 1)) // 向右走
{
maze[x][y + 1] = 0; // 向右走
generate_maze(x, y + 2);
}
else if (direction == 2 && (x - 2 > 0 && maze[x - 2][y] == 1)) // 向上走
{
maze[x - 1][y] = 0;
generate_maze(x - 2, y);
}
else if (direction == 3 && (y - 2 > 0 && maze[x][y - 2] == 1)) // 向左走
{
maze[x][y - 1] = 0;
generate_maze(x, y - 2);
}
else if (direction == 4 && (x + 2 < height && maze[x + 2][y] == 1)) // 向下走
{
maze[x + 1][y] = 0;
generate_maze(x + 2, y);
}
}
}
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) // Generate Maze button
{
String^ width_text = textBox1->Text;
String^ height_text = textBox2->Text;
width = System::Int32::Parse(width_text);
height = System::Int32::Parse(height_text);
int start_x = 1;
int start_y = 1;
int end_x = height - 2;
int end_y = width - 2;
maze = new int* [height];
for (int i = 0; i < height; i++)
{
maze[i] = new int[width];
}
srand(time(NULL));
for (int x = 0; x < height; x++)
{
for (int y = 0; y < width; y++)
{
if (x == 0 || y == 0 || x == height - 1 || y == width - 1)
{
maze[x][y] = 2; // 設定外牆
}
else
{
maze[x][y] = 1; // 設定內部
}
}
}
generate_maze(end_x, end_y);
maze[start_x][start_y - 1] = 0; //拆掉入口左牆
maze[end_x][end_y + 1] = 0; // 拆掉出口右牆
dataGridView1->RowCount = height + 1; // 要多加 1,不然他會IndexOutOfRange,可能是dataGridView本身的設定問題
dataGridView1->ColumnCount = width;
dataGridView1->ColumnHeadersVisible = false; // 隱藏columns
dataGridView1->RowHeadersVisible = false; // 隱藏index
dataGridView1->AllowUserToAddRows = false; // 去掉最後一行空白行
//dataGridView1->AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; // 調整欄位寬度,但不知為何這邊沒辦法用這行程式,所以手動去更改屬性的地方
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
dataGridView1->Rows[i]->Cells[j]->Value = maze[i][j];
}
}
draw_dataGridView();
}