bool FillStatesNewPerBox(int i) { ushort xy = state[i]; int x, y, pos; map.XY2Pos(xy, out x, out y, out pos); byte leftCell = explorer.GetCell(x - 1, y); byte rightCell = explorer.GetCell(x + 1, y); byte upCell = explorer.GetCell(x, y - 1); byte downCell = explorer.GetCell(x, y + 1); bool IsHorizontalFree = ((leftCell | rightCell) & O_OCCUPIED_MASK) == 0; bool IsVerticalFree = ((upCell | downCell) & O_OCCUPIED_MASK) == 0; if (IsHorizontalFree) { AddNewState(i, x, y, -1, 0); AddNewState(i, x, y, 1, 0); } if (IsVerticalFree) { AddNewState(i, x, y, 0, -1); AddNewState(i, x, y, 0, 1); } if (IsHorizontalFree || IsVerticalFree) { return(true); } if ((explorer.cells[pos] & SokobanSolverMap.O_TARGET) != 0) { return(true); } // immovable box: stones on 2 aligned sides if ((((leftCell & upCell) | (upCell & rightCell) | (rightCell & downCell) | (downCell & leftCell)) & SokobanSolverMap.O_STONE) != 0) { return(false); } // immovable box: part of 2x2 occupied square int ox = x + ((leftCell & O_OCCUPIED_MASK) != 0 ? -1 : 1); int oy = y + ((upCell & O_OCCUPIED_MASK) != 0 ? -1 : 1); if ((explorer.GetCell(ox, oy) & O_OCCUPIED_MASK) != 0) { return(false); } return(true); }
void EraseState() { if (state == null) { return; } for (int i = 0; i < map.boxesCount; ++i) { cells[map.XY2Pos(state[i])] &= ~SokobanSolverMap.O_BOX & 0xff; } cells[map.XY2Pos(state[map.boxesCount])] &= ~SokobanSolverMap.O_PLAYER & 0xff; }
void WriteLRUD() { StringBuilder sb = new StringBuilder(); int playerFromX, playerFromY; int playerToX, playerToY; map.XY2Pos(solutionPath[0][0], out playerFromX, out playerFromY); for (int i = 0; i < solutionPath.Length; ++i) { for (int j = 0; j < solutionPath[i].Length; ++j) { if (i == 0 && j == 0) { continue; } map.XY2Pos(solutionPath[i][j], out playerToX, out playerToY); if (playerToX - playerFromX == -1) { sb.Append('L'); } else if (playerToX - playerFromX == 1) { sb.Append('R'); } else if (playerToY - playerFromY == -1) { sb.Append('U'); } else if (playerToY - playerFromY == 1) { sb.Append('D'); } else { throw new Exception("invalid path"); } playerFromX = playerToX; playerFromY = playerToY; } } string lrudPath = map.path + ".lrud"; File.WriteAllText(lrudPath, sb.ToString()); }