/// <summary> /// Znajduje przejcie labiryntu midzy zadanymi punktami /// </summary> /// <returns>Lista kolejnych cCellPosition, ktre stanowi rozwizanie</returns> public ArrayList Solve(int xSource, int ySource, int xDest, int yDest, int maxSteps) { int[,] tMazePath = new int[MSIZEX, MSIZEY]; bool destReached = false; cCellPosition cellPos = new cCellPosition( xSource, ySource ); ArrayList calcState = new ArrayList(); // przygotowanie do rozpoczcia calcState.Add ( cellPos ); int step = 0; for (int i=0; i<MSIZEX; i++) for (int j=0; j<MSIZEY; j++) tMazePath[i,j] = -1; tMazePath[xSource, ySource] = step; // zabezpieczenia if ( maze_data == null ) return null; if ( xSource == xDest && ySource == yDest ) return calcState; while ( destReached == false && calcState.Count > 0 ) { step++; ArrayList calcNextState = new ArrayList(); for (int i=0; i<calcState.Count; i++) { cCellPosition calcCPos = (cCellPosition)calcState[i]; // sprawd cztery ssiadujce kierunki // N if ( calcCPos.y > 0 ) // tylko jesli w zakresie if ( tMazePath[calcCPos.x, calcCPos.y-1] == -1 ) // i jeszcze tam nie bylismy if ( (maze_data[calcCPos.x, calcCPos.y] & (byte)Direction.N) != 0 ) // a mozna tam isc { tMazePath[calcCPos.x, calcCPos.y-1] = step; cCellPosition calcNextCPos = new cCellPosition( calcCPos.x, calcCPos.y-1 ); calcNextState.Add ( calcNextCPos ); if ( calcNextCPos.x == xDest && calcNextCPos.y == yDest ) destReached = true; } // W if ( calcCPos.x > 0 ) // tylko jesli w zakresie if ( tMazePath[calcCPos.x-1, calcCPos.y] == -1 ) // i jeszcze tam nie bylismy if ( (maze_data[calcCPos.x, calcCPos.y] & (byte)Direction.W) != 0 ) // a mozna tam isc { tMazePath[calcCPos.x-1, calcCPos.y] = step; cCellPosition calcNextCPos = new cCellPosition( calcCPos.x-1, calcCPos.y ); calcNextState.Add ( calcNextCPos ); if ( calcNextCPos.x == xDest && calcNextCPos.y == yDest ) destReached = true; } // S if ( calcCPos.y < MSIZEY-1 ) // tylko jesli w zakresie if ( tMazePath[calcCPos.x, calcCPos.y+1] == -1 ) // i jeszcze tam nie bylismy if ( (maze_data[calcCPos.x, calcCPos.y+1] & (byte)Direction.N) != 0 ) // a mozna tam isc { tMazePath[calcCPos.x, calcCPos.y+1] = step; cCellPosition calcNextCPos = new cCellPosition( calcCPos.x, calcCPos.y+1 ); calcNextState.Add ( calcNextCPos ); if ( calcNextCPos.x == xDest && calcNextCPos.y == yDest ) destReached = true; } // E if ( calcCPos.x < MSIZEX-1 ) // tylko jesli w zakresie if ( tMazePath[calcCPos.x+1, calcCPos.y] == -1 ) // i jeszcze tam nie bylismy if ( (maze_data[calcCPos.x+1, calcCPos.y] & (byte)Direction.W) != 0 ) // a mozna tam isc { tMazePath[calcCPos.x+1, calcCPos.y] = step; cCellPosition calcNextCPos = new cCellPosition( calcCPos.x+1, calcCPos.y ); calcNextState.Add ( calcNextCPos ); if ( calcNextCPos.x == xDest && calcNextCPos.y == yDest ) destReached = true; } } calcState = calcNextState; } // moliwe s dwa warianty: if ( destReached == false ) return null; else { tMazePath[xDest, yDest] = step; // buduj drog przez tMazePath ArrayList pPath = new ArrayList(); int tx = xDest; int ty = yDest; pPath.Add ( new cCellPosition ( tx, ty ) ); bool stepExists; while ( tx != xSource || ty != ySource ) { step = tMazePath[tx, ty]; stepExists = false; // szukaj kroku // N if ( ty > 0 && stepExists == false ) if ( tMazePath[tx, ty-1] == step-1 && (maze_data[tx, ty] & (byte)Direction.N) != 0 ) { ty -= 1; stepExists = true; pPath.Add ( new cCellPosition ( tx, ty ) ); } // W if ( tx > 0 && stepExists == false ) if ( tMazePath[tx-1, ty] == step-1 && (maze_data[tx, ty] & (byte)Direction.W) != 0 ) { tx -= 1; stepExists = true; pPath.Add ( new cCellPosition ( tx, ty ) ); } // S if ( ty < MSIZEY -1 && stepExists == false ) if ( tMazePath[tx, ty+1] == step-1 && (maze_data[tx, ty+1] & (byte)Direction.N) != 0 ) { ty += 1; stepExists = true; pPath.Add ( new cCellPosition ( tx, ty ) ); } // E if ( tx < MSIZEX - 1 && stepExists == false ) if ( tMazePath[tx+1, ty] == step-1 && (maze_data[tx+1, ty] & (byte)Direction.W) != 0 ) { tx += 1; stepExists = true; pPath.Add ( new cCellPosition ( tx, ty ) ); } if ( stepExists == false ) return null; if (pPath.Count > maxSteps) break; } return pPath; } }
/// <summary> /// Znajduje przejcie labiryntu midzy zadanymi punktami /// </summary> /// <returns>Lista kolejnych cCellPosition, ktre stanowi rozwizanie</returns> public ArrayList Solve(int xSource, int ySource, int xDest, int yDest, int maxSteps) { int[,] tMazePath = new int[MSIZEX, MSIZEY]; bool destReached = false; cCellPosition cellPos = new cCellPosition(xSource, ySource); ArrayList calcState = new ArrayList(); // przygotowanie do rozpoczcia calcState.Add(cellPos); int step = 0; for (int i = 0; i < MSIZEX; i++) { for (int j = 0; j < MSIZEY; j++) { tMazePath[i, j] = -1; } } tMazePath[xSource, ySource] = step; // zabezpieczenia if (maze_data == null) { return(null); } if (xSource == xDest && ySource == yDest) { return(calcState); } while (destReached == false && calcState.Count > 0) { step++; ArrayList calcNextState = new ArrayList(); for (int i = 0; i < calcState.Count; i++) { cCellPosition calcCPos = (cCellPosition)calcState[i]; // sprawd cztery ssiadujce kierunki // N if (calcCPos.y > 0) // tylko jesli w zakresie { if (tMazePath[calcCPos.x, calcCPos.y - 1] == -1) // i jeszcze tam nie bylismy { if ((maze_data[calcCPos.x, calcCPos.y] & (byte)Direction.N) != 0) // a mozna tam isc { tMazePath[calcCPos.x, calcCPos.y - 1] = step; cCellPosition calcNextCPos = new cCellPosition(calcCPos.x, calcCPos.y - 1); calcNextState.Add(calcNextCPos); if (calcNextCPos.x == xDest && calcNextCPos.y == yDest) { destReached = true; } } } } // W if (calcCPos.x > 0) // tylko jesli w zakresie { if (tMazePath[calcCPos.x - 1, calcCPos.y] == -1) // i jeszcze tam nie bylismy { if ((maze_data[calcCPos.x, calcCPos.y] & (byte)Direction.W) != 0) // a mozna tam isc { tMazePath[calcCPos.x - 1, calcCPos.y] = step; cCellPosition calcNextCPos = new cCellPosition(calcCPos.x - 1, calcCPos.y); calcNextState.Add(calcNextCPos); if (calcNextCPos.x == xDest && calcNextCPos.y == yDest) { destReached = true; } } } } // S if (calcCPos.y < MSIZEY - 1) // tylko jesli w zakresie { if (tMazePath[calcCPos.x, calcCPos.y + 1] == -1) // i jeszcze tam nie bylismy { if ((maze_data[calcCPos.x, calcCPos.y + 1] & (byte)Direction.N) != 0) // a mozna tam isc { tMazePath[calcCPos.x, calcCPos.y + 1] = step; cCellPosition calcNextCPos = new cCellPosition(calcCPos.x, calcCPos.y + 1); calcNextState.Add(calcNextCPos); if (calcNextCPos.x == xDest && calcNextCPos.y == yDest) { destReached = true; } } } } // E if (calcCPos.x < MSIZEX - 1) // tylko jesli w zakresie { if (tMazePath[calcCPos.x + 1, calcCPos.y] == -1) // i jeszcze tam nie bylismy { if ((maze_data[calcCPos.x + 1, calcCPos.y] & (byte)Direction.W) != 0) // a mozna tam isc { tMazePath[calcCPos.x + 1, calcCPos.y] = step; cCellPosition calcNextCPos = new cCellPosition(calcCPos.x + 1, calcCPos.y); calcNextState.Add(calcNextCPos); if (calcNextCPos.x == xDest && calcNextCPos.y == yDest) { destReached = true; } } } } } calcState = calcNextState; } // moliwe s dwa warianty: if (destReached == false) { return(null); } else { tMazePath[xDest, yDest] = step; // buduj drog przez tMazePath ArrayList pPath = new ArrayList(); int tx = xDest; int ty = yDest; pPath.Add(new cCellPosition(tx, ty)); bool stepExists; while (tx != xSource || ty != ySource) { step = tMazePath[tx, ty]; stepExists = false; // szukaj kroku // N if (ty > 0 && stepExists == false) { if (tMazePath[tx, ty - 1] == step - 1 && (maze_data[tx, ty] & (byte)Direction.N) != 0 ) { ty -= 1; stepExists = true; pPath.Add(new cCellPosition(tx, ty)); } } // W if (tx > 0 && stepExists == false) { if (tMazePath[tx - 1, ty] == step - 1 && (maze_data[tx, ty] & (byte)Direction.W) != 0 ) { tx -= 1; stepExists = true; pPath.Add(new cCellPosition(tx, ty)); } } // S if (ty < MSIZEY - 1 && stepExists == false) { if (tMazePath[tx, ty + 1] == step - 1 && (maze_data[tx, ty + 1] & (byte)Direction.N) != 0 ) { ty += 1; stepExists = true; pPath.Add(new cCellPosition(tx, ty)); } } // E if (tx < MSIZEX - 1 && stepExists == false) { if (tMazePath[tx + 1, ty] == step - 1 && (maze_data[tx + 1, ty] & (byte)Direction.W) != 0 ) { tx += 1; stepExists = true; pPath.Add(new cCellPosition(tx, ty)); } } if (stepExists == false) { return(null); } if (pPath.Count > maxSteps) { break; } } return(pPath); } }