Esempio n. 1
0
        private void MoveStep(int fromPole, int toPole)
        {
            MoveRecord record = null;
            int        source = fromPole, dest = toPole;

            int[][] towersArr = towers.ToArray();

            // Interchange fromPole & toPole, if required
            // If frompole is empty
            if (towersArr[fromPole - 1].Length == 0)
            {
                source = toPole;
                dest   = fromPole;
            }
            // When top disk of fromPole > top disk of toPole
            else if (towersArr[toPole - 1].Length > 0 && (towersArr[fromPole - 1][0] > towersArr[toPole - 1][0]))
            {
                source = toPole;
                dest   = fromPole;
            }

            record = towers.Move(source, dest);
            if (record != null)
            {
                moveRecords.Enqueue(record);
                TowerUtilities.DisplayTowers(GetTowers());
                WriteLine($"\nMove {towers.NumberOfMoves} complete. Successfully moved disc from tower {source} to tower {dest}");
            }
            else
            {
                WriteLine("ERROR: Fail to move - record is null");
            }
        }
Esempio n. 2
0
        private void MoveAuto(int discNumber, int fromPole, int auxPole, int toPole)
        {
            if (discNumber == 1)
            {
                Console.Clear();
                MoveRecord record = towers.Move(fromPole, toPole);
                moveRecords.Enqueue(record);
                TowerUtilities.DisplayTowers(GetTowers());
                WriteLine($"\nMove {towers.NumberOfMoves} complete. Successfully moved disc from tower {fromPole} to tower {toPole}");
                if (towers.IsComplete)
                {
                    WriteLine($"Number of Moves: {towers.NumberOfMoves}");
                }
                Thread.Sleep(500);

                return;
            }
            else
            {
                MoveAuto(discNumber - 1, fromPole, toPole, auxPole);

                Console.Clear();
                MoveRecord record = towers.Move(fromPole, toPole);
                moveRecords.Enqueue(record);
                TowerUtilities.DisplayTowers(GetTowers());
                WriteLine($"\nMove {towers.NumberOfMoves} complete. Successfully moved disc from tower {fromPole} to tower {toPole}");
                Thread.Sleep(500);

                MoveAuto(discNumber - 1, auxPole, fromPole, toPole);
            }
        }
Esempio n. 3
0
        private void NormalMove(int fromPole, int toPole)
        {
            try
            {
                MoveRecord record = towers.Move(fromPole, toPole);
                moveRecords.Enqueue(record);
                undoMoves.Push(record);
                redoMoves.Clear();

                Console.Clear();
                TowerUtilities.DisplayTowers(GetTowers());
                WriteLine($"\nMove {towers.NumberOfMoves} complete. Successfully moved disc from tower {fromPole} to tower {toPole}");

                // Game is complete
                if (towers.IsComplete)
                {
                    string msg = towers.NumberOfMoves == towers.MinimumPossibleMoves ?
                                 $"It took you {towers.NumberOfMoves} moves. Congrats! That's the minimum!" :
                                 $"It took you {towers.NumberOfMoves} moves. Not bad, but it can be done in {towers.MinimumPossibleMoves} moves. Try again.";

                    WriteLine(msg);
                }
            }
            catch (Exception ex)
            {
                WriteLine($"\n{ex.GetType().Name}: {ex.Message}");
            }

            return;
        }
Esempio n. 4
0
        private void RedoMove()
        {
            try
            {
                if (redoMoves.Count == 0 || redoMoves.Peek() == null)
                {
                    throw new InvalidOperationException("No moves to Redo.");
                }

                // Get record from redo stack
                MoveRecord recordToUndo = redoMoves.Pop();
                // Make the move
                MoveRecord record = towers.Move(recordToUndo.FromPole, recordToUndo.ToPole);
                // Add the move to queue
                moveRecords.Enqueue(record);
                // Push it to undo stack
                undoMoves.Push(recordToUndo);

                Console.Clear();
                TowerUtilities.DisplayTowers(GetTowers());
                WriteLine($"\nMove {towers.NumberOfMoves} complete by redo of move {recordToUndo.MoveNumber}. Disc {recordToUndo.DiscNumber} returned to tower {recordToUndo.ToPole} from tower {recordToUndo.FromPole}");
            }
            catch (Exception ex)
            {
                WriteLine($"\n{ex.GetType().Name}: {ex.Message}");
            }

            return;
        }
Esempio n. 5
0
        public void AutoSolveStepByStep()
        {
            Console.Clear();
            TowerUtilities.DisplayTowers(GetTowers());

            Write("\nPress a key to see the first move.\n");
            ReadKey();

            MoveStepByStep();

            return;
        }
Esempio n. 6
0
        public void AutoSolve()
        {
            Console.Clear();
            TowerUtilities.DisplayTowers(GetTowers());

            Write("\nPress a key and watch closely!\n");
            ReadKey();

            // Start
            MoveAuto(NumberOfDiscs, 1, 2, 3);

            return;
        }
Esempio n. 7
0
        public SolvingMethod InputSolvingMethod()
        {
            bool          valid = false;
            string        inputStr;
            SolvingMethod solvingMethod = SolvingMethod.None;

            Console.Clear();
            TowerUtilities.DisplayTowers(GetTowers());

            WriteLine("\n\nOptions: ");
            WriteLine("- M - Solve the puzzle manually");
            WriteLine("- A - Auto-solve");
            WriteLine("- S - Auto-solve Step by Step");

            do
            {
                inputStr = string.Empty;
                Write($"\nChoose an approach: ");
                inputStr = ReadKey().KeyChar.ToString().Trim().ToUpper();
                valid    = inputStr == "M" || inputStr == "A" || inputStr == "S" ? true : false;
                if (!valid)
                {
                    WriteLine("\nInvalid Input: Press \"M\" or \"A\" or \"S\" to choose an approach.");
                    valid = false;
                }
            } while (!valid);

            switch (inputStr)
            {
            case "M":
                solvingMethod = SolvingMethod.Manual;
                break;

            case "A":
                solvingMethod = SolvingMethod.Auto;
                break;

            case "S":
                solvingMethod = SolvingMethod.AutoSolveStepByStep;
                break;
            }

            return(solvingMethod);
        }
Esempio n. 8
0
        // Manual Play
        public int InputMoveAction()
        {
            string inputStr;
            int    fromPole = 0, toPole = 0, moveNum;
            bool   valid = false;
            bool   moveCancelled = false;
            bool   undoOper = false, redoOper = false;

            Console.Clear();
            TowerUtilities.DisplayTowers(GetTowers());

            do
            {
                fromPole      = 0; toPole = 0;
                moveCancelled = false;

                moveNum = towers.NumberOfMoves + 1;
                WriteLine($"\nMove {moveNum}:");

                // From tower Input
                do
                {
                    Write($"\nEnter 'from' tower number (1 – 3), {GetUndoRedoMessagePart()} or ‘x’ to quit : ");
                    inputStr = ReadKey().KeyChar.ToString().Trim().ToUpper();
                    undoOper = inputStr == "\u001a" ? true : false;     // Undo operation
                    redoOper = inputStr == "\u0019" ? true : false;     // Redo operation
                    if (inputStr == "X")
                    {
                        WriteLine($"\nWell, you hand in there fo {towers.NumberOfMoves} moves. Nice try.");
                        return(-1);
                    }

                    if (undoOper || redoOper)
                    {
                        valid = true;
                    }
                    else
                    {
                        // From Pole
                        valid = IsPoleInputValid(inputStr, out fromPole);
                        if (!valid)
                        {
                            WriteLine("\nInvalid value. Tower value should be (1 – 3) or press 'Ctrl+z' or 'Ctrl+y' or 'x'");
                        }
                    }
                } while (!valid);

                // To tower Input
                if (!undoOper && !redoOper)
                {
                    do
                    {
                        Write("\nEnter 'to' tower number (1 – 3), or enter to cancel : ");
                        ConsoleKeyInfo consoleKeyInfo = ReadKey();
                        if (consoleKeyInfo.Key == ConsoleKey.Enter)
                        {
                            moveCancelled = true;
                            WriteLine("\nMove cancelled.");
                            break;
                        }
                        else
                        {
                            inputStr = consoleKeyInfo.KeyChar.ToString().Trim().ToUpper();
                            valid    = IsPoleInputValid(inputStr, out toPole);
                            if (!valid)
                            {
                                WriteLine("\nInvalid value. Tower value should be (1 – 3) or press 'enter'");
                            }
                        }
                    } while (!valid);
                }

                if (moveCancelled)
                {
                    continue;
                }

                // Move operation - Undo
                if (undoOper)
                {
                    UndoMove();
                }
                // Move operation - ReDo
                else if (redoOper)
                {
                    RedoMove();
                }
                // Move operation - normally
                else
                {
                    NormalMove(fromPole, toPole);
                }
            } while (!towers.IsComplete);

            return(0);
        }