Ejemplo n.º 1
0
        static void Main(string[] args)
        {
            // Get the input values from the user.
            GetInputParameters();

            // Setup the matrix of squares, indicating the start, finish and obstacle cells.
            matrix = new CellIs[matrixWidth, matrixHeight];
            matrix[startPoint.X, startPoint.Y] = CellIs.StartPoint;
            matrix[finishPoint.X, finishPoint.Y] = CellIs.FinishPoint;
            foreach (Point o in obstacles)
            {
                matrix[o.X, o.Y] = CellIs.Obstacle;
            }

            // Keep track of how many paths we find.
            solutionsFound = 0;

            // Open a log file so we can write out the paths we find.
            string logFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "WPC25-PathsFound.txt");
            sw = new StreamWriter(logFile);
            WriteLogFileHeader();

            DrawMatrix();
            Console.WriteLine("Press any key to proceed...");
            Console.ReadLine();

            // We use an object to keep track of values as we recurse back and forth along test paths.
            // This is the initial object containing the starting point A.
            Cell startingCell = new Cell();
            startingCell.CurrentCell = startPoint;
            startingCell.PreviousCell = new Point(-1, -1);
            startingCell.MoveCount = 0;

            message = "Valid paths are shown below";
            Console.WriteLine(message);
            sw.WriteLine(message);

            // Start recursing...
            CheckCell(startingCell);

            // Write messages to user an log.
            message = string.Format("Success!!  Number of paths found = {0}", solutionsFound);
            Console.WriteLine(message);
            sw.WriteLine();
            sw.WriteLine(message);
            sw.Close();

            // Wait for user to close the console.
            Console.ReadLine();
        }
Ejemplo n.º 2
0
        private static StreamWriter sw; // To write paths found to a log file

        #endregion Fields

        #region Methods

        /// <summary>
        /// The interesting bit that checks whether a cell is suitable for a candidate path.
        /// </summary>
        /// <param name="tracker">An object that keeps track of key variables for a cell 
        /// along a candidate path.  It allows us to use recursion to go forwards and 
        /// backwards along the path.</param>
        /// <returns>True if we reached the target (finish) cell; false otherwise.</returns>
        private static bool CheckCell(Cell tracker)
        {
            Cell clone;

            #if SHOWPATHSCHECKED
            DrawMatrix();
            #endif

            // Check if we've reached the finish point
            if (tracker.CurrentCell == finishPoint)
            {
                // We've reached the finish cell so check whether the path consists of the required
                // number of cells.
                if (tracker.MoveCount == pathLength)
                {
                    // It's a real McCoy.
                    solutionsFound++;
                    DrawMatrix();
                }
                return true;
            }

            if (tracker.MoveCount >= pathLength)
            {
                // Reset the current cell to an empty one
                matrix[tracker.CurrentCell.X, tracker.CurrentCell.Y] = CellIs.Empty;
            #if SHOWPATHSCHECKED
                DrawMatrix();
            #endif
                return false;
            }

            // Get the state of the cells adjoining the current one
            CellIs cellAboveState = GetAdjoiningCellState(Direction.UP, tracker);
            CellIs cellRightState = GetAdjoiningCellState(Direction.RIGHT, tracker);
            CellIs cellBelowState = GetAdjoiningCellState(Direction.DOWN, tracker);
            CellIs cellLeftState = GetAdjoiningCellState(Direction.LEFT, tracker);

            // If it's ok to move up, do so
            if (cellAboveState == CellIs.Empty || cellAboveState == CellIs.FinishPoint)
            {
                // Mark the cell as on the path
                if (cellAboveState == CellIs.Empty)
                    matrix[tracker.CurrentCell.X, tracker.CurrentCell.Y + 1] = CellIs.PathCell;

                clone = new Cell(tracker);
                // Bump the counter that keeps track of how many cells are along the path.
                if (++clone.MoveCount > pathLength) return false;

                // As we're moving, set the previous cell to the current one.
                clone.PreviousCell.X = clone.CurrentCell.X;
                clone.PreviousCell.Y = clone.CurrentCell.Y;

                // And then move to the cell above
                clone.CurrentCell.Y++;

                // And check that.
                if (CheckCell(clone))
                {
                    // Reset the current cell
                    matrix[tracker.CurrentCell.X, tracker.CurrentCell.Y] = CellIs.Empty;
            #if SHOWPATHSCHECKED
                    // Draw the matrix for checking purposes if we're in debug mode
                    DrawMatrix();
            #endif
                    return false;
                }
            }

            // If it's OK to move right, do so
            if (cellRightState == CellIs.Empty || cellRightState == CellIs.FinishPoint)
            {
                // Mark the cell as on the path
                if (cellRightState == CellIs.Empty)
                    matrix[tracker.CurrentCell.X + 1, tracker.CurrentCell.Y] = CellIs.PathCell;

                clone = new Cell(tracker);
                // Bump the counter that keeps track of how many cells are along the path.
                if (++clone.MoveCount > pathLength) return false;

                // As we're moving, set the previous cell to the current one.
                clone.PreviousCell.X = clone.CurrentCell.X;
                clone.PreviousCell.Y = clone.CurrentCell.Y;

                // And then move to the cell to the right
                clone.CurrentCell.X++;

                // And check that.
                if (CheckCell(clone))
                {
                    // Reset the current cell
                    matrix[tracker.CurrentCell.X, tracker.CurrentCell.Y] = CellIs.Empty;
            #if SHOWPATHSCHECKED
                    // Draw the matrix for checking purposes if we're in debug mode
                    DrawMatrix();
            #endif
                    return false;
                }
            }

            // If it's ok to move down, do so
            if (cellBelowState == CellIs.Empty || cellBelowState == CellIs.FinishPoint)
            {
                // Mark the cell as on the path
                if (cellBelowState == CellIs.Empty)
                    matrix[tracker.CurrentCell.X, tracker.CurrentCell.Y - 1] = CellIs.PathCell;

                clone = new Cell(tracker);
                // Bump the counter that keeps track of how many cells are along the path.
                if (++clone.MoveCount > pathLength) return false;

                // As we're moving, set the previous cell to the current one.
                clone.PreviousCell.X = clone.CurrentCell.X;
                clone.PreviousCell.Y = clone.CurrentCell.Y;

                // And then move to the cell below
                clone.CurrentCell.Y--;

                // And check that.
                if (CheckCell(clone))
                {
                    // Reset the current cell
                    matrix[tracker.CurrentCell.X, tracker.CurrentCell.Y] = CellIs.Empty;
            #if SHOWPATHSCHECKED
                    // Draw the matrix for checking purposes if we're in debug mode
                    DrawMatrix();
            #endif
                    return false;
                }
            }

            // If it's OK to move left, do so
            if (cellLeftState == CellIs.Empty || cellLeftState == CellIs.FinishPoint)
            {
                // Mark the cell as on the path
                if (cellLeftState == CellIs.Empty)
                    matrix[tracker.CurrentCell.X - 1, tracker.CurrentCell.Y] = CellIs.PathCell;

                clone = new Cell(tracker);
                // Bump the counter that keeps track of how many cells are along the path.
                if (++clone.MoveCount > pathLength) return false;

                // As we're moving, set the previous cell to the current one.
                clone.PreviousCell.X = clone.CurrentCell.X;
                clone.PreviousCell.Y = clone.CurrentCell.Y;

                // And then move to the cell to the left
                clone.CurrentCell.X--;

                // And check that.
                if (CheckCell(clone))
                {
                    // Reset the current cell
                    matrix[tracker.CurrentCell.X, tracker.CurrentCell.Y] = CellIs.Empty;
            #if SHOWPATHSCHECKED
                    // Draw the matrix for checking purposes if we're in debug mode
                    DrawMatrix();
            #endif
                    return false;
                }
            }

            // Reset the current cell to an empty one
            if (matrix[tracker.CurrentCell.X, tracker.CurrentCell.Y] != CellIs.StartPoint)
                matrix[tracker.CurrentCell.X, tracker.CurrentCell.Y] = CellIs.Empty;
            #if SHOWPATHSCHECKED
            // Draw the matrix for checking purposes if we're in debug mode
            DrawMatrix();
            #endif
            return false;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets the state of a cell adjacent to the specified one.
        /// </summary>
        /// <param name="direction">The direction to look in (left, right, up or down)</param>
        /// <param name="cell">The reference cell.</param>
        /// <returns>Whether the cell is empty, the start or finish point, an obstacle or 
        /// one that's on the current path</returns>
        private static CellIs GetAdjoiningCellState(Direction direction, Cell cell)
        {
            int xOffset = 0;
            int yOffset = 0;

            if (direction == Direction.UP && cell.CurrentCell.Y + 1 < matrix.GetLength(1))
                yOffset = 1;

            else if (direction == Direction.DOWN && cell.CurrentCell.Y - 1 >= 0)
                yOffset = -1;
            else if (direction == Direction.RIGHT && cell.CurrentCell.X + 1 < matrix.GetLength(0))
                xOffset = 1;
            else if (direction == Direction.LEFT && cell.CurrentCell.X - 1 >= 0)
                xOffset = -1;
            else
                return CellIs.InvalidCell;

            return matrix[cell.CurrentCell.X + xOffset, cell.CurrentCell.Y + yOffset];
        }