Добавленно TUI

This commit is contained in:
2026-03-05 23:00:24 +04:00
parent 3d57b2a574
commit 479014a03b
4 changed files with 233 additions and 13 deletions

View File

@@ -1,3 +1,6 @@
using System;
using su.divan2000.UtilsTUI;
namespace su.divan2000.PLandDS_HanoiTowers
{
class HanoiTowers
@@ -48,7 +51,7 @@ namespace su.divan2000.PLandDS_HanoiTowers
throw new InvalidOperationException("Source tower is empty");
if (targetTopIndex >= size)
throw new InvalidOperationException("Target tower is full");
if (targetTopIndex > 0 && sourceTower[sourceTopIndex] > targetTower[targetTopIndex])
if (targetTopIndex >= 0 && sourceTower[sourceTopIndex] > targetTower[targetTopIndex])
throw new InvalidOperationException("Cannot place larger disk on smaller one");
targetTower[targetTopIndex + 1] = sourceTower[sourceTopIndex];
@@ -66,6 +69,21 @@ namespace su.divan2000.PLandDS_HanoiTowers
}
return -1; // Tower is empty
}
public bool isSolved()
{
return towers[0].All(disk => disk == 0) && towers[1].All(disk => disk == 0) && towers[2].All(disk => disk != 0);
}
public void reset()
{
for (int i = 0; i < size; i++)
{
towers[0][i] = size - i;
towers[1][i] = 0;
towers[2][i] = 0;
}
}
}
static class HanoiUtils
@@ -98,16 +116,68 @@ namespace su.divan2000.PLandDS_HanoiTowers
return moves;
}
public static void ExecuteMoves(HanoiTowers towers, List<Move> moves)
public static void ExecuteMove(HanoiTowers towers, Move move)
{
foreach (Move move in moves)
towers.move(move.From, move.To);
}
public static int RunTUI()
{
bool running;
int n = InputHelper.AskInt("Введите количество дисков в ханойской башне: ");
HanoiTowers towers = new HanoiTowers(n);
HanoiTowers.TowerName selectedTower = HanoiTowers.TowerName.A;
Menu manualInput = new Menu("Выберите башню:\n"+towers);
manualInput.AddOption("Башня A", () => selectedTower = HanoiTowers.TowerName.A);
manualInput.AddOption("Башня B", () => selectedTower = HanoiTowers.TowerName.B);
manualInput.AddOption("Башня C", () => selectedTower = HanoiTowers.TowerName.C);
Menu menu = new Menu("Выберите действие:\n"+towers);
menu.AddOption("Сделать ход вручную", () =>
{
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);
manualInput.SetTitle("Выберите башню, с которой хотите переместить диск:\n" + towers);
manualInput.RunMenu();
HanoiTowers.TowerName from = selectedTower;
manualInput.SetTitle("Перемещение с башни " + from + "\nВыберите башню, на которую хотите переместить диск:\n" + towers);
manualInput.RunMenu();
HanoiTowers.TowerName to = selectedTower;
try
{
towers.move(from, to);
} catch (InvalidOperationException ex)
{
Console.WriteLine("Невозможно переместить диск: " + ex.Message);
}
});
menu.AddOption("Сбросить башню", () =>
{
towers.reset();
});
menu.AddOption("Решить башню автоматически", () =>
{
List<Move> moves = MoveN(towers, towers.Size, HanoiTowers.TowerName.A, HanoiTowers.TowerName.C, HanoiTowers.TowerName.B);
towers.reset();
foreach (Move move in moves) {
ExecuteMove(towers, move);
Console.Clear();
Console.WriteLine("Решение башни:\n" + towers);
System.Threading.Thread.Sleep(500); // Пауза для визуализации
}
});
menu.AddOption("Выход", () =>
{
running = false;
});
for (running = true; running;)
{
menu.SetTitle("Выберите действие:\n" + towers);
menu.RunMenu();
running = !towers.isSolved();
}
return 0;
}
}
}