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"); } }
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); } }
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; }
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; }
public void AutoSolveStepByStep() { Console.Clear(); TowerUtilities.DisplayTowers(GetTowers()); Write("\nPress a key to see the first move.\n"); ReadKey(); MoveStepByStep(); return; }
public void AutoSolve() { Console.Clear(); TowerUtilities.DisplayTowers(GetTowers()); Write("\nPress a key and watch closely!\n"); ReadKey(); // Start MoveAuto(NumberOfDiscs, 1, 2, 3); return; }
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); }
// 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); }