diff --git a/HanoiTowers.cs b/HanoiTowers.cs index 14cd9f7..2ac723d 100644 --- a/HanoiTowers.cs +++ b/HanoiTowers.cs @@ -1,82 +1,113 @@ -namespace su.divan2000.PLandDS_hanoi +namespace su.divan2000.PLandDS_HanoiTowers { class HanoiTowers { - private int[] tower_A; - private int[] tower_B; - private int[] tower_C; - + private int[][] towers; private int size; + public enum TowerName { A, B, C } + public int Size { get { return size; } } + public HanoiTowers(int size) { this.size = size; - tower_A = new int[size]; - tower_B = new int[size]; - tower_C = new int[size]; + towers = new int[3][]; + towers[0] = new int[size]; + towers[1] = new int[size]; + towers[2] = new int[size]; for (int i = 0; i < size; i++) { - tower_A[i] = size - i; + towers[0][i] = size - i; } } - public string toString() + public override string ToString() { int charsPerTower = size.ToString().Length; string result = ""; for (int i = size - 1; i >= 0; i--) { - result += tower_A[i].ToString().PadLeft(charsPerTower).Replace("0", "|") + " "; - result += tower_B[i].ToString().PadLeft(charsPerTower).Replace("0", "|") + " "; - result += tower_C[i].ToString().PadLeft(charsPerTower).Replace("0", "|") + "\n"; + result += towers[0][i].ToString().PadLeft(charsPerTower).Replace("0", "|") + " "; + result += towers[1][i].ToString().PadLeft(charsPerTower).Replace("0", "|") + " "; + result += towers[2][i].ToString().PadLeft(charsPerTower).Replace("0", "|") + "\n"; } return result; } - public void move(int from, int to) + public void move(TowerName from, TowerName to) { - int[] sourceTower = getTower(from); - int[] targetTower = getTower(to); + if (from == to) return; + int[] sourceTower = towers[(int)from]; + int[] targetTower = towers[(int)to]; int sourceTopIndex = getTopIndex(sourceTower); int targetTopIndex = getTopIndex(targetTower); - if (sourceTopIndex == -1) - { - throw new InvalidOperationException("No disk to move"); - } - - if (targetTopIndex != -1 && sourceTower[sourceTopIndex] > targetTower[targetTopIndex]) - { + if (sourceTopIndex < 0) + throw new InvalidOperationException("Source tower is empty"); + if (targetTopIndex >= size) + throw new InvalidOperationException("Target tower is full"); + if (targetTopIndex > 0 && sourceTower[sourceTopIndex] > targetTower[targetTopIndex]) throw new InvalidOperationException("Cannot place larger disk on smaller one"); - } - + targetTower[targetTopIndex + 1] = sourceTower[sourceTopIndex]; sourceTower[sourceTopIndex] = 0; } - private int[] getTower(int index) + public int getTopIndex(int[] tower) { - switch (index) - { - case 0: return tower_A; - case 1: return tower_B; - case 2: return tower_C; - default: throw new ArgumentException("Invalid tower index"); - } - } - - private int getTopIndex(int[] tower) - { - for (int i = size - 1; i >= 0; i--) + for (int i = size-1; i >= 0; i--) { if (tower[i] != 0) { return i; } } - return -1; // Tower is full + return -1; // Tower is empty + } + } + + static class HanoiUtils + { + public struct Move + { + public HanoiTowers.TowerName From; + public HanoiTowers.TowerName To; + + public Move(HanoiTowers.TowerName from, HanoiTowers.TowerName to) + { + From = from; + To = to; + } + } + + public static List MoveN(HanoiTowers towers, int n, HanoiTowers.TowerName from, HanoiTowers.TowerName to, HanoiTowers.TowerName aux) + { + List moves = new List(); + if (n == 1) + { + moves.Add(new Move(from, to)); + } + else + { + moves.AddRange(MoveN(towers, n - 1, from, aux, to)); + moves.Add(new Move(from, to)); + moves.AddRange(MoveN(towers, n - 1, aux, to, from)); + } + return moves; + } + + public static void ExecuteMoves(HanoiTowers towers, List moves) + { + foreach (Move move in moves) + { + towers.move(move.From, move.To); + Console.Clear(); + Console.WriteLine($"Move from {move.From} to {move.To}"); + Console.WriteLine(towers); + System.Threading.Thread.Sleep(1000); + } } } } \ No newline at end of file diff --git a/Program.cs b/Program.cs index b047ae6..6cd851d 100644 --- a/Program.cs +++ b/Program.cs @@ -1,36 +1,18 @@ using System; -namespace su.divan2000.PLandDS_hanoi +namespace su.divan2000.PLandDS_HanoiTowers { class Program { static void Main() { - HanoiTowers towers = new HanoiTowers(4); - Console.WriteLine(towers.toString()); + HanoiTowers towers = new HanoiTowers(8); + Console.WriteLine(towers); - try - { - towers.move(0, 1); - Console.WriteLine(towers.toString()); - towers.move(0, 2); - Console.WriteLine(towers.toString()); - towers.move(1, 2); - Console.WriteLine(towers.toString()); - towers.move(0, 1); - Console.WriteLine(towers.toString()); - towers.move(2, 0); - Console.WriteLine(towers.toString()); - towers.move(2, 1); - Console.WriteLine(towers.toString()); - towers.move(0, 1); - } - catch (InvalidOperationException ex) - { - Console.WriteLine("Error: " + ex.Message); - } - - Console.WriteLine(towers.toString()); + List moves = HanoiUtils.MoveN(towers, towers.Size, HanoiTowers.TowerName.A, HanoiTowers.TowerName.C, HanoiTowers.TowerName.B); + HanoiUtils.ExecuteMoves(towers, moves); + + Environment.Exit(0); } } } \ No newline at end of file