123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading;
- using System.Threading.Tasks;
- using MafiaTelegramBot.Controllers;
- using MafiaTelegramBot.DataBase;
- using MafiaTelegramBot.Models;
- using MafiaTelegramBot.Resources;
- using MafiaTelegramBot.Extensions;
- using Telegram.Bot.Types.ReplyMarkups;
- namespace MafiaTelegramBot.Game
- {
- public class GameRoom
- {
- private bool _isRunning;
- public int MaxPlayers = 10;
- private int _minPlayers = Constants.PLAYER_LIMITS_MIN;
- public virtual bool IsPrivate { get; protected set; } = false;
- public bool IsExtended { get; init; }
- public bool TimerEnabled { get; set; } = true;
- public string RoomName { get; init; } = "NoNameRoom";
- public UserEntity Owner { get; init; } = new();
- private readonly Queue<UserEntity> _turnOrder = new();
- public readonly Dictionary<long, UserEntity> Players = new();
- public readonly Dictionary<Roles, int> Settings = new()
- {
- {Roles.Mafia, 0},
- {Roles.Cop, 0},
- {Roles.Villager, 0},
- {Roles.Doctor, 0},
- {Roles.Don, 0},
- {Roles.Hooker, 0},
- };
- public void Start()
- {
- new Task(async () =>
- {
- _isRunning = true;
- await FirstDay();
- await GameCycle();
- await EndOfGame();
- }).Start();
- }
- public async Task<ResultCode> Prepare()
- {
- var resultCode = CanStartGame();
- if (resultCode != ResultCode.CodeOk) return resultCode;
- await ReadSettings();
- await GenerateTurnOrder();
- await AssignRoles();
- return resultCode;
- }
- private async Task FirstDay()
- {
- await Task.Run(() => { });
- }
- private async Task GameCycle()
- {
- await Task.Run(() => { });
- }
- private async Task EndOfGame()
- {
- await Task.Run(async () =>
- {
- foreach (var (_, player) in Players)
- {
- player.SetRole(Roles.None);
- _isRunning = false;
- _turnOrder.Clear();
- Thread.Sleep(10000);//TODO just for tests
- if (!Players.ContainsKey(Owner.Id) || Players.Count == 0) new Task(async() =>
- await RoomController.DissolveRoom(IsPrivate ? RoomEncrypter.NameToCode(RoomName) : RoomName)).Start();
- else
- {
- await Bot.SendWithMarkdown2(Owner.ChatId, strings.thanks_for_game, Keyboards.OwnerGameMenu);
- await NotifyPlayersAbout(Owner.Id, strings.thanks_for_game, Keyboards.PlayerGameMenu);
- }
- }
- });
- }
- private async Task ReadSettings()
- {
- if (!IsExtended) await SetNormalRoles();
- }
- private ResultCode CanStartGame()
- {
- if (Players.Count < _minPlayers) return ResultCode.TooFewPlayers;
- if (Players.Count > MaxPlayers) return ResultCode.TooManyPlayers;
- return _isRunning ? ResultCode.GameAlreadyRunning : ResultCode.CodeOk;
- }
- private async Task SetNormalRoles()
- {
- await Task.Run(() =>
- {
- Settings[Roles.Villager] = Players.Count;
- Settings[Roles.Cop] = 1;
- if (Players.Count != 8) Settings[Roles.Doctor] = 1;
- else Settings[Roles.Doctor] = 0;
- if (Players.Count % 3 == 0)
- {
- Settings[Roles.Mafia] = Players.Count / 3;
- Settings[Roles.Don] = 0;
- }
- else
- {
- Settings[Roles.Mafia] = (Players.Count / 3) - 1;
- Settings[Roles.Don] = 1;
- }
- foreach (var (key, value) in Settings)
- if (key != Roles.Villager)
- Settings[Roles.Villager] -= value;
- foreach (var (key, value) in Settings)
- if (value < 1)
- Settings.Remove(key);
- });
- }
- public async Task<List<UserEntity>> GetPlayers()
- {
- return await Task.Run(() =>
- {
- var players = Players.Values.ToList();
- players.Remove(Owner);
- return players;
- });
- }
- private async Task AssignRoles()
- {
- await Task.Run(() =>
- {
- var random = new Random();
- for (var i = 0; i < _turnOrder.Count; ++i)
- {
- var user = _turnOrder.Dequeue();
- var roles = new List<Roles>();
- foreach (var (key, value) in Settings) roles.AddTimes(key, value);
- user.SetRole(roles.GetAndRemove(random.Next(roles.Count)));
- _turnOrder.Enqueue(user);
- }
- });
- }
- private async Task GenerateTurnOrder()
- {
- await Task.Run(() =>
- {
- var random = new Random();
- var playersCopy = Players.Values.ToList();
- while (playersCopy.Count != 0)
- {
- var player = playersCopy.GetAndRemove(random.Next(playersCopy.Count));
- _turnOrder.Enqueue(player);
- player.TurnOrder = _turnOrder.Count;
- }
- });
- }
- public bool IsFilled()
- {
- return Players.Count == MaxPlayers;
- }
- public async Task NotifyPlayersAbout(long ignoredUserId, string message, IReplyMarkup keyboard = null)
- {
- foreach (var player in Players.Values.Where(player => ignoredUserId != player.Id))
- {
- await Bot.SendWithMarkdown2(player.ChatId, message, keyboard);
- }
- }
- public async Task NotifyPlayersAboutGameStarted()
- {
- foreach (var player in Players.Values)
- {
- var message =
- $"{strings.your_role}: _*{player.GetRole()}*_\n" +
- $"{strings.your_turn_order}: _*{player.TurnOrder}*_\n"+
- $"{strings.bot_starting_game}";
- await Bot.SendWithMarkdown2(player.ChatId, message, Keyboards.InGamePlayerMenu);
- }
- }
- }
- }
|