|
제가 해 봤음... (그렇다고 할일없는 넘은 아닙니다 ^^)
알고리즘까지는 모르겠고 최단거리는 구할수 있읍니다.
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
int map[10][10] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 0, 0, 0, 1, 0, 0, 1, 0,
0, 1, 0, 0, 0, 1, 0, 0, 1, 0,
0, 1, 0, 0, 0, 1, 1, 1, 1, 0,
0, 1, 1, 1, 0, 0, 1, 0, 1, 0,
0, 1, 0, 0, 0, 0, 1, 0, 1, 0,
0, 1, 1, 1, 1, 1, 1, 0, 1, 0,
0, 1, 0, 0, 0, 0, 0, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
int tmap[10][10];
void copymap()
{
for(int j=0;j<10;j++){
for(int i=0;i<10;i++){
tmap[j][i]=map[j][i];
}
}
}
void draw(int map[10][10])
{
Form1->Memo1->Font->Name="굴림체";
Form1->Memo1->Font->Size=9;
Form1->Memo1->Text="";
for(int j=0;j<10;j++){
AnsiString s="";
for(int i=0;i<10;i++){
switch(map[j][i]){
case 4:
s+="x";
break;
case 5:
s+="*";
break;
case 0:
s+="\n";
break;
case 1:
s+=" ";
break;
case 7:
s+="s";
break;
case 8:
s+="e";
break;
}
}
Form1->Memo1->Lines->Add(s);
}
}
class oneline{
public:
oneline*parent;
TList*l;
oneline(oneline*);
~oneline();
void add(TPoint*);
};
oneline::oneline(oneline*p)
{
l=new TList();
parent=p;
}
oneline::~oneline()
{
delete l;
}
void oneline::add(TPoint*p)
{
l->Add(p);
}
class ppitem{
public:
oneline*parent;
int x,y;
ppitem(oneline*,int,int);
~ppitem(){};
};
ppitem::ppitem(oneline*pa,int xx,int yy)
{
parent=pa;
x=xx;y=yy;
};
class pp{
public:
TList*l;
pp();
~pp();
void push(ppitem*);
ppitem*pop();
};
pp::pp()
{
l=new TList();
}
pp::~pp()
{
delete l;
}
void pp::push(ppitem*pi)
{
l->Add(pi);
}
ppitem*pp::pop()
{
if(!l->Count) return 0;
ppitem*p=(ppitem*)l->Items[l->Count-1];
l->Delete(l->Count-1);
return p;
}
class allline{
public:
TList*l;
allline();
~allline();
void add(oneline*);
bool is_exist_sub(oneline*,int,int);
bool is_exist(oneline*,int,int);
};
allline::allline(){
l=new TList();
}
allline::~allline()
{
delete l;
}
void allline::add(oneline*o)
{
l->Add(o);
};
bool allline::is_exist_sub(oneline*o,int x,int y)
{
TList*l=(TList*)o->l;
for(int i=0;i<l->Count;i++){
TPoint*p=(TPoint*)l->Items[i];
if(p->x==x&&p->y==y){return true;}
}
return false;
}
bool allline::is_exist(oneline*o,int x,int y)
{
oneline*oo=o;
while(oo){
if(is_exist_sub(oo,x,y)) return true;
oo=oo->parent;
}
return false;
}
void run()
{
allline*all=new allline();
pp*pushpop=new pp();
oneline*parent,*cur=new oneline(0);
cur->add(new TPoint(1,8));//1,8 시작위치
all->add(cur);
pushpop->push(new ppitem(cur,1,8));//1,8 시작위치
int x,y;
ppitem*pi;
while(true){
pi=pushpop->pop();
if(!pi){
// ShowMessage("no pushed pos");
break;
}
x=pi->x;y=pi->y;parent=pi->parent;
cur=new oneline(parent);
all->add(cur);
bool loop_flag=true;
while(loop_flag){
// if(x==8&&y==8){ //골 is 8,8
// ShowMessage("find goal");
// }
int t=map[y][x];//for display
map[y][x]=4;
draw(map);
Sleep(100);
map[y][x]=t;
cur->add(new TPoint(x,y));
bool b1=(map[y][x+1]==1)&!all->is_exist(cur,x+1,y);
bool b2=(map[y][x-1]==1)&!all->is_exist(cur,x-1,y);
bool b3=(map[y+1][x]==1)&!all->is_exist(cur,x,y+1);
bool b4=(map[y-1][x]==1)&!all->is_exist(cur,x,y-1);
int cnt=0;
if(b1){cnt++;};
if(b2){cnt++;};
if(b3){cnt++;};
if(b4){cnt++;};
switch(cnt){
case 0:
loop_flag=false;
// ShowMessage("no more 길");
break;
case 1:
if(b1){x++;};
if(b2){x--;};
if(b3){y++;};
if(b4){y--;};
break;
default:
if(b1){pushpop->push(new ppitem(cur,x+1,y));};
if(b2){pushpop->push(new ppitem(cur,x-1,y));};
if(b3){pushpop->push(new ppitem(cur,x,y+1));};
if(b4){pushpop->push(new ppitem(cur,x,y-1));};
loop_flag=false;
break;
}
}
}
//골 찾은 부분 찾기
TList*t1=new TList();
for(int i=0;i<all->l->Count;i++){
oneline*a=(oneline*)all->l->Items[i];
for(int j=0;j<a->l->Count;j++){
TPoint*p=(TPoint*)a->l->Items[j];
if(p->x==8&&p->y==8){//골 is 8,8
t1->Add(a);
}
}
}
//골 찾은 부분 draw
ShowMessage("draw");
for(int i=0;i<t1->Count;i++){
copymap();
draw(tmap);
oneline*a=(oneline*)t1->Items[i];
int cnt=0;
while(a){
for(int j=a->l->Count-1;j>=0;j--){
TPoint*p=(TPoint*)a->l->Items[j];
tmap[p->y][p->x]=4;
cnt++;
draw(tmap);
Sleep(100);
}
a=a->parent;
}
ShowMessage("거리="+AnsiString(cnt-1));
}
ShowMessage("done");
//please free all
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
run();
}
.끝.
우람이 님이 쓰신 글 :
: 안녕하세요
: obstacle사이로 point(source)와 point(target)를 잊는 최단경로를 구해야 하는데요...
: Lee's Algorithm(maze running)이나 Line-Searching Algorithm에 대해 아시는 분 있으면
: 도움 부탁드립니다. 위의 Algorithm외에 다른 방법이 있다면 가르쳐 주시구요..
: 자세한 자료가 나와있는 사이트나 자료있으면 올려주시구요,,,source도 있으면 부탁드립니다.
: 그럼 다들 수고하시고요 많은 도움 부탁드립니다.
|