# Untitled

unknown
c_cpp
2 years ago
9.4 kB
24
Indexable
Never
```//---------------------------------------------------------------------------

#include "stdio.h"
#include <vcl.h>
#pragma hdrstop

#include "MouseInMaze.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

TForm1 *Form1;

#define MAXSIZE 30
#define possible_direction 8

int ** maze;  //二微陣列存迷宮
int m, n, top;

struct offset  //用來存方位的移動值
{
int dx;
int dy;
};

enum direction{N, NE, E, SE, S, SW, W, NW}; //列舉8個方位

struct position  //用來存點的位置+移動的方位
{
int x;
int y;
int dir;
};

struct offset move[possible_direction];  //用move這個陣列去存可能的移動位置
struct position *stack;

void push(struct position data) //stack中push的概念
{
if(top == (m*n-1))
{
}
else
{
stack[++top] = data;
}
}

struct position pop()  //stack中pop的概念
{
if(top == -1)
{
}
else
{
return stack[top--];
}
}

void path(int m, int n)
{
int mark[300][300];
String str = "";
stack = new struct position[m*n];
struct position step;
boolean found = false;
int i, j, u, v;
int count = 0;

//用另一個mark陣列存maze的值，這個陣列是記錄哪邊走過用的
for(i = 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
mark[i][j] = maze[i][j];
}
}

//初始化
step.x = 1; step.y = 0; step.dir = E;
push(step);

//走迷宮的邏輯
//從方位0走到7，只要可以走就更新位置，如果不能走就退回前一步
//因為mark有去紀錄有沒有走過，所以就會退回前一步，再走沒走過的地方
//找到的話就把路徑顯示出來
while(top != -1)
{
step = pop();
while((step.dir <= NW) && (!found))
{
count++;
u = step.x + move[step.dir].dx;
v = step.y + move[step.dir].dy;
int x = step.dir;
Form1->Memo2->Lines->Add("● Step" + IntToStr(count) + "： (u, v, dir) = " + IntToStr(u) + ", " + IntToStr(v) + ", " + IntToStr(x));
if((u == m-1) && (v == n))
{
found = true;
str += "(" +IntToStr(step.x) + "," + IntToStr(step.y) + ")";
while (top != -1)
{
Form1->StringGrid1->Cells[step.y][step.x] = "●";
Form1->StringGrid2->Cells[step.y][step.x] = "●";
step = pop();
str = "(" + IntToStr(step.x) + "," + IntToStr(step.y) + ")-->" + str;
}
}
else if((maze[u][v]==0) && (mark[u][v]==0))
{
mark[u][v] = 1;
step.dir += 1;
push(step);
step.x = u; step.y = v; step.dir = 0;
Form1->StringGrid1->Cells[step.y][step.x] = "*";
Form1->StringGrid2->Cells[step.y][step.x] = "*";
}
else
{
step.dir += 1;
}
}
}
}

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
//初始化
move[N].dx = -1; move[N].dy = 0;
move[NE].dx = -1; move[NE].dy = 1;
move[E].dx = 0; move[E].dy = 1;
move[SE].dx = 1; move[SE].dy = 1;
move[S].dx = 1; move[S].dy = 0;
move[SW].dx = 1; move[SW].dy = -1;
move[W].dx = 0; move[W].dy = -1;
move[NW].dx = -1; move[NW].dy = -1;
}
//---------------------------------------------------------------------------

//讀檔用
void __fastcall TForm1::Button1Click(TObject *Sender)
{
FILE *fp;     // Define fp as a pointer pointing to some file (with data type FILE) in HD
String out;
int i, j;
AnsiString infile;   // Use builder's string (AnsiString) to ease the conversion (into const char *)

if (OpenDialog1->Execute())
{
infile = OpenDialog1->FileName;
fp = fopen(infile.c_str(), "r+");
//c_str函数的傳回值是 const char *, 即把AnsiString轉成const char *給fopen使用
fscanf(fp, "%d %d", &m, &n);    // Read in two integers m & n
Memo2->Lines->Add("(m, n) = (" + IntToStr(m) + ", " + IntToStr(n) + ")");
maze = new int * [m];
for(i = 0; i < m; i++)
{
maze[i] = new int [n];
}
// Read in m*n 0/1/2's into maze[][]
for(i = 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
fscanf(fp, "%d", &maze[i][j]);
}
}
fclose(fp);

for(i = 0; i < m; i++)
{
out = "";
for(j = 0; j < n; j++)
{
out += " " + IntToStr(maze[i][j]);
}
}
}

Memo1->Lines->Add("You Can Now Click On Button 'Show Maze In String Grid'!");
Button2->Enabled = True;
}
//---------------------------------------------------------------------------

//顯示迷宮用
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Memo1->Lines->Add("'Show Maze In String Grid' Clicked!");
Memo1->Lines->Add("Check It At Page 'Maze By Icon/Color'!");
Memo1->Lines->Add("You Can Now Click On Button 'Find A Tour In Maze'!");
int i, j;
int grid_size = StrToInt(Edit1->Text);
for(i = 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
StringGrid1->Cells[j][i] = maze[i][j];
StringGrid2->Cells[j][i] = maze[i][j];
}
}

StringGrid1->RowCount = m;  StringGrid1->ColCount = n;
StringGrid1->DefaultDrawing = true;  StringGrid1->FixedCols=0;  StringGrid1->FixedRows=0;
for (i=0; i<m; i++) StringGrid1->RowHeights[i] = grid_size;
for (i=0; i<n; i++) StringGrid1->ColWidths[i] = grid_size;

StringGrid2->RowCount = m;  StringGrid2->ColCount = n;
StringGrid2->DefaultDrawing = true;  StringGrid2->FixedCols=0;  StringGrid2->FixedRows=0;
for (i=0; i<m; i++) StringGrid2->RowHeights[i] = grid_size;
for (i=0; i<n; i++) StringGrid2->ColWidths[i] = grid_size;

StringGrid1->Refresh();
StringGrid2->Refresh();

Button3->Enabled = True;
}
//---------------------------------------------------------------------------

//迷宮判斷過程的顯示(美化)
void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol, int ARow, TRect &Rect,
TGridDrawState State)
{
AnsiString text = StringGrid1->Cells[ACol][ARow];
if(text == "0")
{
StringGrid1->Canvas->Brush->Color = TColor RGB(246,234,190);
StringGrid1->Canvas->FillRect(Rect);
}
else if(text == "●")
{
StringGrid1->Canvas->Brush->Color = TColor RGB(246,234,190);
StringGrid1->Canvas->FillRect(Rect);
StringGrid1->Canvas->TextRect(Rect, Rect.Left+10, Rect.Top+10, text);
}
else if(text == "*")
{
StringGrid1->Canvas->Brush->Color = TColor RGB(246,234,190);
StringGrid1->Canvas->FillRect(Rect);
StringGrid1->Canvas->TextRect(Rect, Rect.Left+10, Rect.Top+10, text);
}
else
{
StringGrid1->Canvas->Brush->Color = TColor RGB(94,69,75);
StringGrid1->Canvas->FillRect(Rect);
}

}
//---------------------------------------------------------------------------

//找路徑用
void __fastcall TForm1::Button3Click(TObject *Sender)
{
Memo1->Lines->Add("Find A Tour In Maze Clicked!");
Memo1->Lines->Add("Track The Steps At 'Track' Or Check The Graph At 'Maze By Icon/Color'!");
path(m,n);
}
//---------------------------------------------------------------------------

//可以顯示每個Grid的大小和值
void __fastcall TForm1::StringGrid1Click(TObject *Sender)
{
TRect Recto = StringGrid1->CellRect(StringGrid1->Col, StringGrid1->Row);

int width = Recto.Width();
int height = Recto.Height();

Label2->Caption = "Size: " + IntToStr(width) + " * " + IntToStr(height);
Label3->Caption = "Cell: [" + IntToStr(StringGrid1->Col) + ", " + IntToStr(StringGrid1->Row)+ "] = " + StringGrid1->Cells[StringGrid1->Col][StringGrid1->Row];
}
//---------------------------------------------------------------------------

//迷宮判斷過程的顯示(美化)
void __fastcall TForm1::StringGrid2DrawCell(TObject *Sender, int ACol, int ARow, TRect &Rect,
TGridDrawState State)
{
AnsiString text = StringGrid1->Cells[ACol][ARow];
if(text == "0")
{
StringGrid2->Canvas->Brush->Color = TColor RGB(255,255,255);
StringGrid2->Canvas->FillRect(Rect);
}
else if(text == "●")
{
StringGrid2->Canvas->Brush->Color = TColor RGB(210,180,140);
StringGrid2->Canvas->FillRect(Rect);
}
else if(text == "*")
{
StringGrid2->Canvas->Brush->Color = TColor RGB(255,239,213);
StringGrid2->Canvas->FillRect(Rect);
}
else
{
StringGrid2->Canvas->Brush->Color = TColor RGB(119,136,153);
StringGrid2->Canvas->FillRect(Rect);
}
}
//---------------------------------------------------------------------------

//可以顯示每個Grid的大小和值
void __fastcall TForm1::StringGrid2Click(TObject *Sender)
{
TRect Recto = StringGrid2->CellRect(StringGrid2->Col, StringGrid2->Row);

int width = Recto.Width();
int height = Recto.Height();

Label2->Caption = "Size: " + IntToStr(width) + " * " + IntToStr(height);
Label3->Caption = "Cell: [" + IntToStr(StringGrid2->Col) + ", " + IntToStr(StringGrid2->Row)+ "] = " + StringGrid2->Cells[StringGrid2->Col][StringGrid2->Row];
}
//---------------------------------------------------------------------------
```