/
evsyukov.s
/
test
Обзор
Документация
Войти
/
evsyukov.s
/
test
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/DicePoker.ConsoleApp/Program.cs
282 строки
8 KB
chernova.v
Улучшена визуализация костей
14 ноя 2025, 16:43
14 ноя 2025, 16:43
589325b
Код
Авторство
О чём код?
using System.Text; using DicePoker.Core.Data.Abstractions; using DicePoker.Core.Data.Repositories; using DicePoker.Core.Game; using DicePoker.Core.Logic; using DicePoker.Core.Models; using DicePoker.Core.Services; Console.OutputEncoding = Encoding.UTF8; // Настройка путей к данным var savesDir = Path.Combine(AppContext.BaseDirectory, "data"); var saveFilePath = Path.Combine(savesDir, "save.json"); var recordsFilePath = Path.Combine(savesDir, "records.json"); // Dependency Injection: создание репозиториев и сервисов IGameRepository gameRepository = new JsonFileGameRepository(savesDir); IRecordsRepository recordsRepository = new JsonFileRecordsRepository(recordsFilePath); var gamePersistenceService = new GamePersistenceService(gameRepository); var recordsService = new RecordsManagementService(recordsRepository, topCount: 10); // Главный цикл приложения while (true) { Console.Clear(); PrintHeader(); Console.WriteLine("1) Новая игра"); Console.WriteLine("2) Загрузить игру"); Console.WriteLine("3) Таблица рекордов"); Console.WriteLine("4) Выход"); Console.Write("\nВыбор: "); var choice = Console.ReadLine(); switch (choice) { case "1": StartNewGame(); break; case "2": await LoadAndResume(); break; case "3": await ShowRecords(); break; case "4": return; default: continue; } } void PrintHeader() { Console.WriteLine("=== Кости (Покерные комбинации) ==="); } void StartNewGame() { Console.Clear(); PrintHeader(); Console.Write("Имя игрока 1: "); var p1 = Console.ReadLine() ?? "Игрок 1"; Console.Write("Имя игрока 2: "); var p2 = Console.ReadLine() ?? "Игрок 2"; Console.Write("Ограничение времени на ход (сек, 0 = без ограничения): "); int.TryParse(Console.ReadLine(), out var secondsPerMove); var state = new GameState(p1, p2, secondsPerMove); RunGameLoop(state).GetAwaiter().GetResult(); } async Task LoadAndResume() { var hasSave = await gamePersistenceService.HasSavedGameAsync(); if (!hasSave) { Console.WriteLine("\nНет сохранения. Нажмите Enter."); Console.ReadLine(); return; } var state = await gamePersistenceService.LoadGameAsync(); if (state == null) { Console.WriteLine("\nОшибка загрузки сохранения. Нажмите Enter."); Console.ReadLine(); return; } RunGameLoop(state).GetAwaiter().GetResult(); } async Task ShowRecords() { Console.Clear(); PrintHeader(); var list = await recordsService.GetTopRecordsAsync(); if (list.Count == 0) { Console.WriteLine("Пока пусто."); } else { Console.WriteLine("\n=== Топ-10 рекордов ===\n"); int i = 1; foreach (var r in list) { Console.WriteLine($"{i,2}. {r.PlayerName,-16} {r.Score,8}"); i++; } // Дополнительно показываем статистику var stats = await recordsService.GetStatisticsAsync(); Console.WriteLine($"\nВсего записей: {stats.TotalRecords}"); Console.WriteLine($"Наивысший счет: {stats.HighestScore}"); Console.WriteLine($"Средний счет: {stats.AverageScore}"); if (stats.TopPlayer != null) Console.WriteLine($"Лидер: {stats.TopPlayer}"); } Console.WriteLine("\nEnter чтобы вернуться в меню."); Console.ReadLine(); } async Task RunGameLoop(GameState state) { var undoStack = new Stack<GameSnapshot>(); while (true) { Console.Clear(); PrintHeader(); PrintScores(state); Console.WriteLine($"\nХод: {state.CurrentPlayer.Name} (пере-бросов осталось: {state.RerollsLeft})"); state.StartTurn(); while (true) { Console.WriteLine($"\nКости: [{string.Join(",", state.Hand.Values())}]"); Console.WriteLine($"Подсказка (маска удержания): {HintGenerator.SuggestKeepMask(state.Hand.Values())}"); Console.WriteLine("\nВыберите действие:"); Console.WriteLine("1) Перебросить выбранные кости"); Console.WriteLine("2) Завершить ход"); Console.WriteLine("3) Сохранить игру"); Console.WriteLine("4) История"); Console.WriteLine("5) Отмена последнего действия (undo)"); Console.WriteLine("6) Выход в главное меню"); Console.Write("\nВаш выбор: "); string? answer; if (state.SecondsPerMove > 0) { answer = ReadLineWithTimeout(state.SecondsPerMove); if (answer is null) { Console.WriteLine("\nВремя истекло. Ход завершён автоматически."); FinalizeTurn(state); break; } } else { answer = Console.ReadLine(); } switch (answer) { case "1": if (!state.CanReroll) { Console.WriteLine("Лимит перебросов в ходу — 2. Больше перебрасывать нельзя."); break; } undoStack.Push(GameSnapshot.FromState(state)); Console.Write("Введите индексы костей для переброса (0-4, через пробел): "); var input = Console.ReadLine() ?? ""; var indices = ParseIndices(input); state.Reroll(indices); break; case "2": FinalizeTurn(state); break; case "3": await gamePersistenceService.SaveGameAsync(state); Console.WriteLine("Игра сохранена."); break; case "4": ShowHistory(state); break; case "5": if (undoStack.Count > 0) { var snap = undoStack.Pop(); state = snap.ToState(); Console.WriteLine("Откат выполнен."); } else { Console.WriteLine("Нечего отменять."); } break; case "6": return; default: Console.WriteLine("Неизвестная команда."); break; } if (answer == "2") { break; } } // Игра завершается после одного полного раунда (по одному ходу на игрока) — всего 2 хода if (state.TurnNumber > 2) { Console.Clear(); PrintHeader(); PrintScores(state); Console.WriteLine("\nИгра завершена!"); var winner = state.Player1.Score == state.Player2.Score ? "Ничья" : (state.Player1.Score > state.Player2.Score ? state.Player1.Name : state.Player2.Name); Console.WriteLine($"Победитель: {winner}"); // Добавляем рекорды обоих игроков через сервис await recordsService.AddRecordAsync(state.Player1.Name, state.Player1.Score); await recordsService.AddRecordAsync(state.Player2.Name, state.Player2.Score); Console.WriteLine("\nEnter чтобы вернуться в меню."); Console.ReadLine(); return; } } } void FinalizeTurn(GameState state) { var rank = state.EndTurnAndScore(); Console.WriteLine($"\nКомбинация: {rank.Category}, очки: {rank.ScoreValue}"); Console.WriteLine("Enter для продолжения..."); Console.ReadLine(); } void ShowHistory(GameState state) { Console.WriteLine("\nИстория:"); foreach (var h in state.History.TakeLast(20)) { Console.WriteLine(h); } } void PrintScores(GameState state) { Console.WriteLine($"{state.Player1.Name}: {state.Player1.Score} | {state.Player2.Name}: {state.Player2.Score}"); } string? ReadLineWithTimeout(int seconds) { var line = new StringBuilder(); var end = DateTime.UtcNow.AddSeconds(seconds); while (DateTime.UtcNow < end) { if (Console.KeyAvailable) { var key = Console.ReadKey(true); if (key.Key == ConsoleKey.Enter) return line.ToString(); if (key.Key == ConsoleKey.Backspace && line.Length > 0) { line.Length--; Console.Write("\b \b"); } else if (!char.IsControl(key.KeyChar)) { line.Append(key.KeyChar); Console.Write(key.KeyChar); } } Thread.Sleep(10); } return null; } int[] ParseIndices(string input) { return input.Split(' ', StringSplitOptions.RemoveEmptyEntries) .Select(s => int.TryParse(s, out var i) ? i : -1) .Where(i => i >= 0 && i < 5) .Distinct() .ToArray(); }