microbeWay.h
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:16k
- // Copyright: 胡小民,丁展 2002.5
- #include "stdio.h"
- #include "stdlib.h"
- #include "iostream.h"
- #include "maze.h"
- #include "mazeMake.h"
- /*
- const int MAX_MStack_SIZE=1000;
- const int SIZEX_MAZE=15;
- const int SIZEY_MAZE=15;
- const int EXIT_ROW=SIZEX_MAZE-2;
- const int EXIT_COL=SIZEY_MAZE-2;
- const int MAX_ANT_NUM=4;
- int maze[SIZEX_MAZE][SIZEY_MAZE];
- bool mark[SIZEX_MAZE][SIZEY_MAZE]; // record that some path is not accessable
- int pos[SIZEX_MAZE][SIZEY_MAZE]; // record all objects position at the same time
- // tell others that this path cannot be accessed in fact it describe the new maze
- bool found=false;
- int step=0;
- */
- //class element;
- class MStack;
- //class offsets;
- //int Max(int x,int y ,int z,int w);
- //void GenerateMaze();
- long MSearchPath(MStack& _MStack);
- void MInitMark();
- //void ShowMaze();
- //void SimpleMaze();
- void MAllocate(MStack _MStackarray[],int n);
- void MInitAll();
- int MMin(int x,int y ,int z,int w);
- /*
- bool Square1(int i,int j)
- {
- if(maze[i-1][j]&&maze[i][j-1]&&maze[i-1][j-1])
- return true;
- return false;
- }
- bool Square0(int i,int j)
- {
- if(!maze[i-1][j]&&!maze[i][j-1]&&!maze[i-1][j-1])
- return true;
- return false;
- }
- //----------------------------//
- class element
- {
- public:
- int row;
- int col;
- int dir;
- };*/
- /*
- bool EqualElement(const element a,const element b)
- {
- if(a.col==b.col&&a.row==b.row)
- return true;
- else
- return false;
- }*/
- /*
- class offsets
- {
- public:
- int vert;
- int horiz;
- public:
- void GetValue(int vert=0,int horiz=0)
- {
- this->vert=vert;
- this->horiz=horiz;
- }
- };*/
- //---------------------------//
- //offsets move[4];
- class MStack
- {
- private:
- int top;
- element error;
- int count;
- public:
- element stack[MAX_STACK_SIZE];
- public:
- bool classmark[CONST_MAZEX][CONST_MAZEY];
- int method; // method是对走法的处理,顺时针,逆时针等等
- public:
- MStack():top(-1)
- {
- MMinitMark();
- }
- void NewAntsCame()
- {
- MMinitMark();
- classmark[1][1]=true;
- AddMStack(1,1,1);
- row=1;
- col=1;
- dir=1;
- next_row=0;
- next_col=0;
- dir=0;
- count=0;
- pos[1][1]++;
- //------------------
- count++;
- position=DeleteMStack();
- row=position.row;
- col=position.col;
- dir=position.dir;
- }
- void SetDir(int dir)
- {
- this->dir=dir;
- }
- void MStackEmpty()
- {
- top=-1;
- }
- element DeleteMStack()
- {
- if(top==-1)
- return error;
- else
- return stack[top--];
- }
- bool AddMStack(const element & pa)
- {
- if(top==MAX_STACK_SIZE-1)
- return false;
- else
- {
- stack[++top]=pa;
- return true;
- }
- }
- bool AddMStack(int row,int col,int dir)
- {
- if(top==MAX_STACK_SIZE-1)
- return false;
- else
- {
- top++;
- stack[top].row=row;
- stack[top].col=col;
- stack[top].dir=dir;
- return true;
- }
- }
- bool Empty()
- {
- if(top==-1)
- return true;
- else
- return false;
- }
- void MMinitMark();
- //
- private:
- int row,col,next_row,next_col,dir;
- element position;
- public:
- int MSearchPathStepByStep();
- bool TestDir(int dir);
- bool TestDirection(int dir);
- int GetLength()
- {
- return top;
- }
- element GetCurrentPosition()
- {
- element temp;
- temp.row=row;
- temp.col=col;
- temp.dir=0 ; // temp.dir=dir;
- return temp;
- }
- element GetLastPosition()
- {
- element temp;
- temp.row=next_row;
- temp.col=next_col;
- temp.dir=0;
- return temp;
- }
- ~MStack()
- {}
- };
- //--------------independent-------------------//
- void MStack::MMinitMark()
- {
- int i,j;
- for(i=0;i<SIZEX_MAZE;i++)
- for(j=0;j<SIZEY_MAZE;j++)
- {
- if(maze[i][j]==1)
- classmark[i][j]=true;
- else
- classmark[i][j]=false;
- }
- }
- bool MStack::TestDir(int dir)
- {
- this->dir=dir;
- if(this->dir<0||this->dir>3)
- return false;
- next_row=row+move[dir].vert;
- next_col=col+move[dir].horiz;
- if(next_row==EXIT_ROW&&next_col==EXIT_COL)
- {
- found=true;
- ::pos[next_row][next_col]++;
- ::pos[row][col]--;
- position.row=row;
- position.col=col;
- position.dir=--dir;
- AddMStack(position);
- row=next_row;
- col=next_col;
- dir=3;
- AddMStack(row,col,dir);
- count++;
- return true;
- }
- else
- // 墙 在栈里
- if(!maze[next_row][next_col]&&!classmark[next_row][next_col])
- {
- classmark[next_row][next_col]=true;
- ::pos[row][col]--;
- ::pos[next_row][next_col]++;
- position.row=row;
- position.col=col;
- position.dir=++this->dir;
- AddMStack(position);
- row=next_row;
- col=next_col;
- this->dir=0;
- count++;
- return true;
- }
- return false;
- }
- bool MStack::TestDirection(int dir)
- {
- this->dir=dir;
- if(this->dir<0||this->dir>3)
- return false;
- int num=0;
- while(num<4)
- {
- this->dir=this->dir%4;
- next_row=row+move[this->dir].vert;
- next_col=col+move[this->dir].horiz;
- if(next_row==EXIT_ROW&&next_col==EXIT_COL)
- {
- found=true;
- classmark[next_row][next_col]=true;
- ::pos[next_row][next_col]++;
- ::pos[row][col]--;
- position.row=row;
- position.col=col;
- position.dir=--dir;
- AddMStack(position);
- row=next_row;
- col=next_col;
- dir=3;
- AddMStack(row,col,dir);
- count++;
- return true;
- }
- else
- if(!maze[next_row][next_col]&&!classmark[next_row][next_col])
- {
- classmark[next_row][next_col]=true;
- ::pos[row][col]--;
- ::pos[next_row][next_col]++;
- position.row=row;
- position.col=col;
- position.dir=++this->dir;
- AddMStack(position);
- row=next_row;
- col=next_col;
- this->dir=0;
- count++;
- return true;
- }
- else
- {
- ++this->dir;
- num++;
- if(num==4)
- {
- count++;
- ::pos[row][col]--;
- position=DeleteMStack();
- row=position.row;
- col=position.col;
- this->dir=position.dir;
- ::pos[row][col]++;
- return false;
- }
- }
- }
- return false;
- }
- int MStack::MSearchPathStepByStep()
- {
-
- while(dir<4&&!found)
- {
- next_row=row+move[dir].vert;
- next_col=col+move[dir].horiz;
- if(next_row==EXIT_ROW&&next_col==EXIT_COL)
- {
- found=true;
- classmark[next_row][next_col]=true;
- ::pos[next_row][next_col]++;
- ::pos[row][col]--;
- position.row=row;
- position.col=col;
- position.dir=--dir;
- AddMStack(position);
- row=next_row;
- col=next_col;
- dir=0;
- AddMStack(row,col,dir);
- count++;
-
- }
- else
- {
- if(!maze[next_row][next_col]&&!classmark[next_row][next_col]&&!mark[next_row][next_col])
- {
- classmark[next_row][next_col]=true;
- ::pos[row][col]--;
- ::pos[next_row][next_col]++;
-
- position.row=row;
- position.col=col;
- position.dir=++dir;
- AddMStack(position);
- row=next_row;
- col=next_col;
- dir=0;
- count++;
- return 0;
- }
- else
- {
- ++dir;
- if(dir==4)
- {
- if(!Empty()&&!found)
- {
- count++;
- ::pos[row][col]--;
- position=DeleteMStack();
- row=position.row;
- col=position.col;
- dir=position.dir;
- ::pos[row][col]++;
- return 0;
- }
- else
- return -1;
- }
- }
- }
- }
- if(found)
- {
- return count;
- }
- else
- {
- return 0;
- }
- }
- /*
- void SimpleMaze()
- {
- int i=1,j=1;
- maze[i][j]=0;
- int k;
- while(i!=EXIT_ROW||j!=EXIT_COL)
- {
- if(i==EXIT_ROW)
- {
- while(j!=EXIT_COL)
- maze[i][++j]=0;
- break;
- }
- if(j==EXIT_COL)
- {
- while(i!=EXIT_ROW)
- maze[++i][j]=0;
- break;
- }
- k=rand()%2;
- if(k==0)
- {
- i++;
- maze[i][j]=0;
- continue;
- }
- if(k==1)
- {
- j++;
- maze[i][j]=0;
- continue;
- }
- }
- }
- void GenerateMaze()
- {
- int i,j;
- int i1,j1;
- for(i=0;i<SIZEX_MAZE;i++)
- for(j=0;j<SIZEY_MAZE;j++)
- maze[i][j]=1;
- SimpleMaze();
- for(i=2;i<SIZEX_MAZE-2;i++)
- for(j=2;j<SIZEY_MAZE-2;j++)
- {
- if(Square1(i,j))
- {
- i1=i-rand()%2;
- j1=j-rand()%2;
- maze[i1][j1]=0;
- }
- }
- MStack _MStack;
- if(MSearchPath(_MStack)==0)
- {
- SimpleMaze();
- }
- }
- void ShowMaze()
- {
- int i=0,j=0;
- for(i=1;i<SIZEX_MAZE-1;i++)
- {
- for(j=1;j<SIZEY_MAZE-1;j++)
- cout<<maze[i][j]<<" ";
- cout<<endl;
- }
- }*/
- void MInitMark()
- {
- int i,j;
- for(i=0;i<SIZEX_MAZE;i++)
- for(j=0;j<SIZEY_MAZE;j++)
- {
- mark[i][j]=false;
- pos[i][j]=0;
- }
- move[0].GetValue(-1,0);
- move[1].GetValue(0,1);
- move[2].GetValue(1,0);
- move[3].GetValue(0,-1);
- }
- long MSearchPath(MStack & _MStack)
- {
- int row,col,next_row,next_col,dir;
- long count=0;
- bool found=false;
- element position;
- MInitMark();
- mark[1][1]=true;
- _MStack.AddMStack(1,1,1);
- while(!_MStack.Empty()&&!found)
- {
- position=_MStack.DeleteMStack();
- row=position.row;
- col=position.col;
- dir=position.dir;
- while(dir<4&&!found)
- {
- next_row=row+move[dir].vert;
- next_col=col+move[dir].horiz;
- if(next_row==EXIT_ROW&&next_col==EXIT_COL)
- found=true;
- else
- if(!maze[next_row][next_col]&&!mark[next_row][next_col])
- {
- mark[next_row][next_col]=1;
- position.row=row;
- position.col=col;
- position.dir=++dir;
- _MStack.AddMStack(position);
- row=next_row;
- col=next_col;
- dir=0;
- count++;
- }
- else
- ++dir;
- }
- }
- if(found)
- {
- return count;
- }
- else
- return 0;
- }
- void MInitAll()
- {
- GenerateMaze();
- MInitMark();
- }
- int MMin(int x,int y ,int z,int w)
- {
- int m=x*y*z*w;
- int count;
- if(m==0)
- {
- count=0;
- if(x==0)
- count+=1;
- if(y==0)
- count+=2;
- if(z==0)
- count+=4;
- if(w==0)
- count+=8;
- return count;
- }
- return 0;
- }
- void MAllocate(MStack _MStackarray[],int n)
- {
- int x,y;
- int count=0;
- int i=0;
- int dir=0;
- element position;
- int turn=0;
- // int length=0;
- int countnum=0;
- bool once=true;
- int pos[CONST_MAZEX][CONST_MAZEY]; // record all objects position at the same time
- MStack newMStack[CONST_ANT_NUM];
- ::step++;
- for(i=0;i<n;i++)
- newMStack[i]=_MStackarray[i];
- for(i=0;i<SIZEX_MAZE;i++)
- for(int j=0;j<SIZEY_MAZE;j++)
- {
- pos[i][j]=::pos[i][j];
- }
- for(x=1;x<SIZEX_MAZE-1;x++)
- for(y=1;y<SIZEY_MAZE-1;y++)
- {
- if(pos[x][y]<=0)
- continue;
- else
- {
- position.row=x;
- position.col=y;
- position.dir=1;
-
- count=MMin(maze[x-1][y],maze[x+1][y],maze[x][y-1],maze[x][y+1]);
-
- switch(count)
- {
- case 0: cout<<"false "<<endl;break;
- case 1:
- case 2:
- case 4:
- case 8:
- {
- for(i=0;i<n;i++)
- {
- if(EqualElement(_MStackarray[i].GetCurrentPosition(),position))
- {
- if(count==1)
- dir=0; //all go to (x-1,y)
- else if(count==2)
- dir=2; // all go to(x+1,y)
- else if(count==4)
- dir=3; // all to to (x,y-1)
- else if(count==8)
- dir=1; // all go to (x,y+1)
- // newMStack[i].SetDir(dir);
- newMStack[i].TestDirection(dir);
- // //if((++countnum)==n) return;
- }
- }
- break;
- }
- case 3:
- case 5:
- case 6:
- {
- turn=0;
- for(i=0;i<n;i++)
- {
- if(EqualElement(_MStackarray[i].GetCurrentPosition(),position))
- {
- if(turn==0)
- {
- if(count== 3 || count ==5)
- dir=0;
- else if(count==6) // all go to (x+1,y) and (x,y-1)
- dir=2;
- newMStack[i].TestDirection(dir);
- turn=1;
- }
- else
- {
- if(count==3)
- dir=2; // all to (x-1,y) and (x+1,y)
- else if(count==5 || count==6)
- dir=3; // all go to (x-1,y) and (x,y-1)
- newMStack[i].TestDirection(dir);
- turn=0;
- }
- }
- }
- break;
- }
- case 7:
- case 11:
- case 13:
- case 14:
- {
- // 7: all go to (x-1,y) and (x+1,y) and (x,y-1)
- // 11: all go to (x-1,y) and (x+1,y) and (x,y+1)
- // 13: all go to (x-1,y) and (x,y-1) and (x,y+1)
- // 14: all go to (x+1,y) and (x,y-1) and (x,y+1)
- turn=0;
- for(i=0;i<n;i++)
- {
- if(EqualElement(_MStackarray[i].GetCurrentPosition(),position))
- {
- switch(turn)
- {
- case 0:
- if(count==7 || count ==11 || count==13)
- dir=0;
- else
- dir=2;
- newMStack[i].TestDirection(dir);
- turn=1;
- break;
- case 1:
- if(count==7 || count==11)
- dir=2;
- else
- dir=3;
- newMStack[i].TestDirection(dir);
- turn=2;
- break;
- case 2:
- if(count==7)
- dir=3;
- else
- dir=1;
- newMStack[i].TestDirection(dir);
- turn=0;
- break;
- }
- }
- }
- break;
- }
-
- case 9: // all go to (x-1,y) and (x,y+1)
- case 10: // all go to (x+1,y) and (x,y+1)
- case 12: // all go to (x,y-1) and (x,y+1)
- {
- turn=0;
- for(i=0;i<n;i++)
- {
- if(EqualElement(_MStackarray[i].GetCurrentPosition(),position))
- {
- switch(turn)
- {
- case 0:
- if(count==9)
- dir=0;
- else if(count==10)
- dir=2;
- else if(count==12)
- dir=3;
- newMStack[i].TestDirection(dir);
- turn=1;
- break;
- case 1:
- dir=1;
- newMStack[i].TestDirection(dir);
- turn=0;
- break;
- }
- }
- }
- break;
- }
- case 15:
- {
- turn=0;
- for(i=0;i<n;i++)
- {
- if(EqualElement(_MStackarray[i].GetCurrentPosition(),position))
- {
- switch(turn)
- {
- case 0:
- dir=0;
- newMStack[i].TestDirection(dir);
- turn=1;
- break;
- case 1:
- dir=1;
- newMStack[i].TestDirection(dir);
- turn=2;
- break;
- case 2:
- dir=2;
- newMStack[i].TestDirection(dir);
- turn=3;
- break;
- case 3:
- dir=3;
- newMStack[i].TestDirection(dir);
- turn=3;
- break;
- }
- }
- }
- break;
- }
- default:
- break;
-
- }
- }
- }
- for(i=0;i<n;i++)
- _MStackarray[i]=newMStack[i];
- }
- /*
- void main()
- {
- MMinitAll();
- ShowMaze();
- int i;
- cout<<endl<<" this is the final result "<<endl;
- //-----------------final test--------------------------------------//
- MMinitMark();
- MStack _MStackarray[MAX_ANT_NUM];
-
- for(i=0;i<MAX_ANT_NUM;i++)
- _MStackarray[i].NewAntsCame ();
- found=false;
- int tag=0;
- element position;
- bool x;
- element temp;
- int j;
- while(1)
- {
- MAllocate(_MStackarray,MAX_ANT_NUM);
- for(i=0;i<MAX_ANT_NUM;i++)
- {
- for(j=0;j<_MStackarray[i].GetLength();j++)
- {
- temp=_MStackarray[i].MStack[j];
- }
- }
- cout<<endl;
- for(i=1;i<SIZEX_MAZE-1;i++)
- {
- for(j=1;j<SIZEY_MAZE-1;j++)
- cout<<pos[i][j]<<" ";
- cout<<" ";
- for(j=1;j<SIZEY_MAZE-1;j++)
- cout<<maze[i][j]<<" ";
- cout<<endl;
- }
-
- for(i=0;i<MAX_ANT_NUM;i++)
- {
- position=_MStackarray[i].GetCurrentPosition();
- if(position.row==EXIT_ROW&&position.col==EXIT_COL)
- {
- tag=i;
- break;
- }
- x=found;
- }
- if(tag)
- break;
- if(found==true)
- break;
- }
- cout<<endl;
- cout<<"------------------final test------------------"<<endl;
- for(i=0;i<_MStackarray[tag].GetLength()+1;i++)
- {
- cout<<_MStackarray[tag].MStack[i].row<<"--"<<_MStackarray[tag].MStack[i].col<<";";
- }
- }
- */