A few days ago, helping a friend made a job, is a demo for the labyrinth solving
The maze solve is a very classic problem, I think the problem is not discussed.
I want everyone to see my ideas, mention comments.
Below is the program
//head File
#ifndef Labyrinth_structure # Define Labyrinth_structure
#include
Const int event_paint = 0; const Int event_backdate = 1; const Int evenet_ok = 3;
const Int State_ERROR = -1; const state_pass = 0; // You can pass const state_parassed = 1; // Mark has passed const state_cannotpass = 2; // Can't pass const state_entry = 3; // Entrance point const Int State_end = 4; // Export Point
Class Spoint {public:
__fastcall ~ spoint () {
} __Fastcall spoint () {prioritydirection = 1; count = -1;} __fastcall spot (tpint tpoint) {priorityDirection = 1; count = -1; x = tpoint.x; y = tpoint.y;} __fastcall spot (int TX) , int TY) {priorityDirection = 1; count = -1; x = Tx; y = type;} int operator == (const spot & source) {return (source.x == x&& source.y == y);} int Operator! = (const spoint & source) {return (source.x! = x || source.y! = y);
INT X; int y; int count; int prioritydirection; // A priority direction additional four directions};
Template
}
Class Clabyrinth {Tcanvas * Labyrinthcanvas; Int ImageWidth;
Int Labyrinthheight; int labyrinthwidth;
Int Labyrinthcol; int labyrinthrow;
Int unity; int unitwidth;
INT LEFTSPACE; INT TOPSPACE;
Tstringlist * alreadpasslist; int * labyrinthdata;
Graphics :: TBitmap * Bitmap_STATE_PASS; Graphics :: TBitmap * Bitmap_STATE_PASSED; Graphics :: TBitmap * Bitmap_STATE_CANNOTPASS; Graphics :: TBitmap * Bitmap_STATE_ENTRY; Graphics :: TBitmap * Bitmap_STATE_END; void SetMemory (); void SetRowCol (int tRow, int tCol); bool GetNewPoint (int Direction, int & tRow, int & tCol, int & tState); void SetState (int tRow, int tCol, int tState); public: __fastcall CLabyrinth (AnsiString FileName); __fastcall CLabyrinth (int tWidth, int tHeight, TCanvas * tCanvas = NULL); __fastcall ~ CLabyrinth (); void __fastcall Assin (const CLabyrinth & Source) {LabyrinthCol = Source.LabyrinthCol; LabyrinthRow = Source.LabyrinthRow; LabyrinthData = new int [LabyrinthRow * LabyrinthCol]; for (int k = 0; k < LabyrinthRow * LabyrinthCol; k ) LabyrinthData [k] = Source.LabyrinthData [k];} public: void ChangRowCol (int tRow, int tCol); void GetRowCol (int & tRow, int & tCol); void Updata ();
void SetSize (int tWidth, int tHeight); void GetSize (int & tWidth, int & tHeight); void GetSpace (int & tLeftSpace, int & tTopSpace); void SetCanvas (TCanvas * tCanvas); void Refresh (); // entire drawing board to refresh void Refresh (TRECT RECT, INT TSTATE = -1); Void Refresh (TPOINT POINT, INT TSTATE = -1); Void Refresh (int Trow, Int Tcol, Int TState = -1); void savetofile (ANSISTRING TFILENAME = ") ; bool LoadFromFile (AnsiString tFileName = ""); int ConvertRC (int tRow, int tCol); int GetState (int tRow, int tCol); int GetState (TPoint tPoint); void ChangeState (int oldState, int NewState, int Times = -1); Void FindResult (tpoint * startpoint = null); public: Bool PowerExit; Bool Ischange; Ansistring FileName; TMYEVENT FMYEVENT
}
#ENDIF
// below is a part
#include
__fastcall CLabyrinth :: CLabyrinth (AnsiString FileName) {LoadFromFile (FileName);} void CLabyrinth :: Updata () {UnitHeight = ImageHeight / LabyrinthRow; UnitWidth = ImageWidth / LabyrinthCol;
Labyrinthheight = unitHeight * Labyrinthrow; LabyrinthWidth = UnitWidth * Labyrinthcol;
Leftspace = (ImageWidth-LabyrinthWidth) / 2; TOPSPACE = (ImageHeight-LabyrinthHeight) / 2;
}
__fastcall CLabyrinth :: CLabyrinth (int tWidth, int tHeight, TCanvas * tCanvas) {LabyrinthData = NULL; PowerExit = false; AlreadPassList = new TStringList (); Bitmap_STATE_PASS = new Graphics :: TBitmap (); Bitmap_STATE_PASSED = new Graphics :: TBitmap ( ); Bitmap_STATE_CANNOTPASS = new Graphics :: TBitmap (); Bitmap_STATE_ENTRY = new Graphics :: TBitmap (); Bitmap_STATE_END = new Graphics :: TBitmap (); Bitmap_STATE_PASS-> LoadFromResourceName ((int) hInstance, "PASSNUNLL"); Bitmap_STATE_PASSED-> LoadFromResourceName ((int) hInstance, "PASS"); Bitmap_STATE_CANNOTPASS-> LoadFromResourceName ((int) hInstance, "CANNOTPASS"); Bitmap_STATE_ENTRY-> LoadFromResourceName ((int) hInstance, "sTATE_ENTRY"); Bitmap_STATE_END-> LoadFromResourceName ((int) hInstance, "STATE_END"); IsChange = false; LabyrinthData = NULL; LabyrinthCol = 40; LabyrinthRow = 40; LabyrinthCanvas = tCanvas; ImageHeight = tHeight; ImageWidth = tWidth; SetRowCol (LabyrinthRow, LabyrinthCol);} __ fastcall CLabyrinth :: ~ CLabyrinth ( ) {Delete bitmap_state_pass; delete bitmap_state_parassed; delete bi TMAP_STATE_CANNOTPASS; DELETE BITMAP_STATE_ENTRY; DELETE BITMAP_STATE_END; if (Labyrinthdata) {Delete [] Labyrinthdata; LabyrinthData = null;}}
Void Clabyrinth :: setMemory () {if (labyrinthdata) {delete [] Labyrinthdata; Labyrinthdata = null;
LabyrinthData = new int [LabyrinthRow * LabyrinthCol]; for (int k = 1; k
} Void Clabyrinth :: Refresh (TPOINT POINT, INT TSTATE) {INT TCOL = (Point.x-Leftspace) / UnitWidth; Int Trow = (Point.y-Topspace) / UnityT; Tcol = Point.x% UnitWidth> 0? 1: 0; TROW = Point.Y% UnitHeight> 0? 1: 0; Refresh (TROW, TCOL, TSTATE);
} Void Clabyrinth :: Refresh (int Trow, Int Tcol, Int TState {if (Labyrinthcanvas == NULL) RETURN; if (TROW <0 || Tcol <0 || TROW> Labyrinthrow || Tcol> Labyrinthcol) Return; int oldState = LabyrinthData [ConvertRC (tRow, tCol)]; if (tState = - 1!) {if (oldState == sTATE_ENTRY || oldState == STATE_END) return; LabyrinthData [ConvertRC (tRow, tCol)] = tState; IsChange = true;} else tState = oldState; switch (tState) {case STATE_PASS: LabyrinthCanvas-> StretchDraw (Rect (unitWidth * (tCol-1) LeftSpace, UnitHeight * (tRow-1) TopSpace, unitWidth * tCol LeftSpace, UnitHeight * tRow TopSpace), Bitmap_STATE_PASS); break; case STATE_PASSED: LabyrinthCanvas-> StretchDraw (Rect (unitWidth * (tCol-1) LeftSpace, UnitHeight * (tRow-1) TopSpace, unitWidth * tCol LeftSpace, UnitHeight * tRow TopSpace), Bitmap_STATE_PASSED); break; case STATE_CANNOTPASS: LabyrinthCanvas-> StretchDraw (Rect (unitWidth * (tCol-1) LeftSpace, UnitHeight * (tRow-1) TopSpace, unitWidth * tCol LeftSpace, UnitHeight * tRow TopSpace ), Bitmap_state_cannotpass; break; case state_entry: Labyrinthcan vas-> StretchDraw (Rect (UnitWidth * (tCol-1) LeftSpace, UnitHeight * (tRow-1) TopSpace, UnitWidth * tCol LeftSpace, UnitHeight * tRow TopSpace), Bitmap_STATE_ENTRY); break; case STATE_END: LabyrinthCanvas- > StretchDraw (Rect (unitWidth * (tCol-1) LeftSpace, UnitHeight * (tRow-1) TopSpace, unitWidth * tCol LeftSpace, UnitHeight * tRow TopSpace), Bitmap_STATE_END); break; default: break;}
} int Clabyrinth :: ConvertRC (int Trow, int Tcol) {return ((TROW-1) * Labyrinthcol TCOL-1);
}
void CLabyrinth :: SetSize (int tWidth, int tHeight) {LabyrinthHeight = tHeight; LabyrinthWidth = tWidth; UnitHeight = LabyrinthHeight / LabyrinthRow; UnitWidth = LabyrinthWidth / LabyrinthCol; LabyrinthHeight = UnitHeight * LabyrinthRow; LabyrinthWidth = UnitWidth * LabyrinthCol; Refresh ();} Void Clabyrinth :: GetSpace (int & Tleftspace) {tletspace = ippace; ttopspace = TOPSPACE
}
Void Clabyrinth :: getSize (int & twidth, int & theight) {theight = LabyrinthHeight; twidth = labyrinthwidth;
} Int CLabyrinth :: GetState (int tRow, int tCol) {if (tRow> 0 && tCol> 00 && tRow <= LabyrinthRow && tCol <= LabyrinthCol) return (LabyrinthData [ConvertRC (tRow, tCol)]); return STATE_ERROR;}
INT CLABYRINTH :: GetState (TPOINT TPOINT) {Int Tcol = Tpoint.x / UnitWidth; Int Trow = Tpoint.Y / UnityT; Tcol = TPOINT.X% UnitWidth> 0? 1: 0; TROW = TPOINT.Y% UnityT> 0? 1: 0; if (Trow> 0 && Tcol> 0 && TROW <= Labyrinthrow && Tcol <= Labyrinthcol) Return (LabyrinThdata [ConvertRC (TROW, TCOL)]); RETURN State_ERROR;
} Void CLabyrinth :: SaveToFile (AnsiString tFileName) {if (tFileName.IsEmpty ()) tFileName = FileName; if (tFileName.IsEmpty ()) return; FILE * in; try {try {if ((in = fopen (tFileName. c_str (), "w ")) == null) {showMessage ("Cannot open file !!!"); throw (0);} char smark [5] = "LabyR"; int adjustition = 100; fprintf (in , "% s", smark; fprintf (in, "% d", tetition; fprintf (in, "% D% D", Labyrinthrow, Labyrinthcol; for (int K = 0; k
void CLabyrinth :: ChangeState (int OldState, int NewState, int Times) {int tCount = 0; for (int k = 0; k Bool Clabyrinth :: LoadFromFile (Ansistring TFileName) {file * in; Try {try {ix (tfilename.c_str (), "r")) == null) {showMessage ("Can't open the file !!! "); Throw (0);} rebind (in); char mark [5]; Ansistring smark =" labyr "; fscanf (in,"% s ", mark); Ansistring Tempstr = Mark; tempstr = tempstr.substring 1, 5); if (Tempstr! = Smark) {showMessage ("This file is not a labyrinth data file"); throw (0);} int TROW, TCOL; INT TEDITION; FSCANF (in, "% d", & tetition) FSCANF (In, "% D% D", & TROW, & TCOL); Labyrinthcol = Tcol; Labyrinthrow = TROW; SetMemory (); int TState; for (int K = 0; K } __Finally} catch (...)}} catch (...) {returnaf false;}} bool CLabyrinth :: GetNewPoint (int Direction, int & tRow, int & tCol, int & tState) {int OldCol = tCol; int OldRow = tRow; switch (Direction) {case 1: tCol = tCol; tRow = tRow-1; break; case 2: Tcol = Tcol 1; TROW = TROW; Break; Case 3: Tcol = Tcol; TROW = TROW 1; Break; Case 4: Tcol = Tcol-1; TROW = TREAK; DEFAULT: RETURN FALSE;} TSTATE = GETSTATE (TROW 1, TCOL 1); if ((TState == State_Pass || TState == State_end) && alreadpasslist-> indexof ("x:% DY:% D", arrayofconst ((Oldcol 1 , Oldrow 1))))))) <0) // Discover new node return true; return false;} void clabyrinth :: FindResult (TPoint * tstartpoint) {spoint * startspoint; spoint * currentspoint; spoint * stopspoint; / / = new spot (); tpoint startpoint; tpoint stoppoint; int tcount = 0; alleadpasslist-> clear (); for (int L = 0; l if (tStartPoint = NULL!) CurrentSPoint = new SPoint (* tStartPoint); else CurrentSPoint = new SPoint (StartPoint); StopSPoint = new SPoint (StopPoint); StartSPoint = CurrentSPoint; if (CurrentSPoint-> X> StopSPoint-> X) CurrentSPoint -> prioritydirection = 4; else currentspoint-> prioritydirection = 2; Cshed INT nowState; Int CX, Cy; While (1) {if (PowerExit) Break; do {if (PowerExit) Break; currentspoint-> count ; bool tneedpush; cx = currentspoint-> x; cy = currentspoint-> y; switchpoint-> y; switch (CurrentSPoint-> Count) {case 0: tNeedPush = GetNewPoint (CurrentSPoint-> PriorityDirection, CY, CX, NowState); break; case 1: case 2: case 3: case 4: tNeedPush = GetNewPoint (CurrentSPoint-> Count, CY , Cx, downstate; break; default: tneedpush = false; setState (currentspoint-> y 1, currentspoint-> x 1, state_pass); Refresh (currentspoint-> y 1, currentspoint-> x 1); AlreadPassList-> Add ("x:% dy:% d", arrayofconst (currentspoint-> x 1, currentspoint-> y 1)))))))))))))) FMyEvent (Event_BackDate); Break;} if (tneedpush) {Int OldPriorityDirection = currentspoint-> priorityd IRECTION; int Oldcount; setState (currentspoint-> y 1, currentspoint-> x 1, state_parassed); refresh (currentspoint-> y 1, currentspoint-> x 1); tshed.push ( CurrentSPoint); if (FMyEvent) FMyEvent (EVENT_PAINT); CurrentSPoint = new SPoint (CX, CY); if (OldCount == 0) CurrentSPoint-> PriorityDirection = OldPriorityDirection; else CurrentSPoint-> PriorityDirection = OldCount; if (NowState == STATE_END ) {MessageDlg ("Congratulations!!!", Mtinformation, TMSGDLGButtons () << Mbok, 0); ChangeState (state_passed, state_pass); refresh (); if (fMyevent) fmyevent (event_ok); return;} Break;}} while (currentspoint); if (curRentSpoint == null) // No solution {Messagedlg ("There is no passage of this labyrinth." MtWarning, TMSGDLGButtons () << mbok, 0); if (fMyevent) fmyevent (Event_ok); return;}} PowerExit = false; // The following is the member function of the stack Template T * Temp = (Spoint *) list-> items [list-> count-1]; list-> delete (list-> count-1); return temp; } Template } ///