/
evsyukov.s
/
DiceGame
Обзор
Документация
Войти
/
evsyukov.s
/
DiceGame
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
src/DicePoker.Core/Game/GameState.cs
149 строк
7 KB
ligay.a
Исправление для .editorconfig
12 дек 2025, 18:02
12 дек 2025, 18:02
324ead1
Код
Авторство
О чём код?
using System.Text.Json.Serialization; using DicePoker.Core.Models; namespace DicePoker.Core.Game { /// <summary> /// Класс, управляющий состоянием текущей игры. /// Отслеживает обоих игроков, текущую руку костей, количество перебросов и историю действий. /// Реализует основные правила игры: смену ходов, лимит перебросов, подсчет очков. /// </summary> public sealed class GameState { /// <summary>Первый игрок в игре</summary> public Player Player1 { get; } /// <summary>Второй игрок в игре</summary> public Player Player2 { get; } /// <summary>Индекс текущего игрока (0 = Player1, 1 = Player2)</summary> public int CurrentPlayerIndex { get; private set; } /// <summary>Текущая рука костей (общая для обоих игроков в их ход)</summary> public DiceHand Hand { get; } /// <summary>Количество оставшихся перебросов в текущем ходу (максимум 2)</summary> public int RerollsLeft { get; private set; } /// <summary>Номер текущего хода в игре (считается с 1)</summary> public int TurnNumber { get; private set; } /// <summary>Ограничение времени на один ход в секундах (0 = без ограничения)</summary> public int SecondsPerMove { get; private set; } /// <summary>История всех действий в игре (только для чтения)</summary> public IReadOnlyList<string> History => _history; /// <summary>Внутреннее хранилище истории игры</summary> [JsonInclude] private readonly List<string> _history = []; /// <summary> /// Конструктор для десериализации из JSON (используется при загрузке сохранения). /// Помечен атрибутом JsonConstructor для правильной работы System.Text.Json. /// </summary> [JsonConstructor] public GameState(Player player1, Player player2, int currentPlayerIndex, DiceHand hand, int rerollsLeft, int turnNumber, int secondsPerMove, List<string>? history = null) { Player1 = player1; Player2 = player2; CurrentPlayerIndex = currentPlayerIndex; Hand = hand; RerollsLeft = rerollsLeft; TurnNumber = turnNumber; SecondsPerMove = secondsPerMove <= 0 ? 0 : secondsPerMove; // Если передана история, копируем её if (history != null) { _history = [.. history]; } } /// <summary> /// Конструктор для создания новой игры с двумя игроками. /// Инициализирует начальное состояние: первый ход, первого игрока, руку костей и т.д. /// </summary> public GameState(string p1, string p2, int secondsPerMove = 0) { Player1 = new Player(p1); Player2 = new Player(p2); CurrentPlayerIndex = 0; // Начинает первый игрок Hand = new DiceHand(); RerollsLeft = 2; // В начале хода доступно 2 переброса TurnNumber = 1; SecondsPerMove = secondsPerMove <= 0 ? 0 : secondsPerMove; } /// <summary>Получает текущего игрока, чей сейчас ход</summary> public Player CurrentPlayer => CurrentPlayerIndex == 0 ? Player1 : Player2; /// <summary>Получает другого игрока (не текущего)</summary> public Player OtherPlayer => CurrentPlayerIndex == 0 ? Player2 : Player1; /// <summary> /// Начинает новый ход текущего игрока. /// Сбрасывает счетчик перебросов, бросает все кости и добавляет запись в историю. /// </summary> public void StartTurn() { RerollsLeft = 2; // Resetting rerolls for the new turn Hand.RollAll(); // Бросаем все кости AddHistory($"Turn {TurnNumber}: {CurrentPlayer.Name} rolled [{string.Join(",", Hand.Values())}]"); } /// <summary> /// Проверяет, остались ли переброски для текущего хода. /// </summary> public bool CanReroll => RerollsLeft > 0; /// <summary> /// Функция, выполняет переброску кость указанных индексов. /// Уменьшает счетчик перебросок и добавляет запись в историю. /// </summary> public void Reroll(params int[] indices) { // Проверяем, остались ли переброски if (RerollsLeft <= 0) { throw new InvalidOperationException("No rerolls left"); } // Перебрасываем выбранные кости Hand.RerollIndices(indices); RerollsLeft--; AddHistory($"{CurrentPlayer.Name} rerolled indices [{string.Join(",", indices)}] -> [{string.Join(",", Hand.Values())}]"); } /// <summary> /// Функция, завершает ход текущего игрока, подсчитывает очки на основе его комбинации и переходит к следующему игроку. /// </summary> public HandRank EndTurnAndScore() { // Получаем текущие значения костей int[] values = Hand.Values(); // Оцениваем покерную комбинацию HandRank rank = Logic.HandEvaluator.Evaluate(values); // Добавляем полученные очки к счету текущего игрока CurrentPlayer.AddScore(rank.ScoreValue); // Добавляем запись в историю AddHistory($"{CurrentPlayer.Name} finished with {rank.Category} ({string.Join(",", values)}) => +{rank.ScoreValue}"); // Переходим к следующему игроку CurrentPlayerIndex = 1 - CurrentPlayerIndex; TurnNumber++; return rank; } /// <summary> /// Функция, добавляет запись в историю игры с временной меткой. /// </summary> private void AddHistory(string entry) { _history.Add($"{DateTime.Now:HH:mm:ss} {entry}"); } } }