|
@@ -39,7 +39,7 @@ namespace MafiaTelegramBot.Game.GameRooms
|
|
var player = _turnOrder.Dequeue();
|
|
var player = _turnOrder.Dequeue();
|
|
if(!player.IsPlaying) continue;
|
|
if(!player.IsPlaying) continue;
|
|
await PlayersCh.Send($"{strings.now_turn} \\({player.TurnOrder}\\) {player.NickName}");
|
|
await PlayersCh.Send($"{strings.now_turn} \\({player.TurnOrder}\\) {player.NickName}");
|
|
- await Bot.SendWithMarkdown2(player.ChatId, strings.you_turn_say);
|
|
|
|
|
|
+ if (TimerEnabled) await Bot.SendWithMarkdown2(player.ChatId, strings.you_turn_say);
|
|
await player.CurrentRole.SpeakAction();
|
|
await player.CurrentRole.SpeakAction();
|
|
if (firstPlayer != null && player.IsPlaying) _turnOrder.Enqueue(player);
|
|
if (firstPlayer != null && player.IsPlaying) _turnOrder.Enqueue(player);
|
|
else firstPlayer = player;
|
|
else firstPlayer = player;
|
|
@@ -116,7 +116,7 @@ namespace MafiaTelegramBot.Game.GameRooms
|
|
if(!player.IsPlaying || !player.IsAlive) continue;
|
|
if(!player.IsPlaying || !player.IsAlive) continue;
|
|
if (firstPlayer == null) player.IsFirst = true;
|
|
if (firstPlayer == null) player.IsFirst = true;
|
|
await PlayersCh.Send($"{strings.now_turn} \\({player.TurnOrder}\\) {player.NickName}");
|
|
await PlayersCh.Send($"{strings.now_turn} \\({player.TurnOrder}\\) {player.NickName}");
|
|
- await Bot.SendWithMarkdown2(player.ChatId, strings.you_turn_say);
|
|
|
|
|
|
+ if (TimerEnabled) await Bot.SendWithMarkdown2(player.ChatId, strings.you_turn_say);
|
|
await player.CurrentRole.SpeakAction();
|
|
await player.CurrentRole.SpeakAction();
|
|
await player.CurrentRole.VotingAction();
|
|
await player.CurrentRole.VotingAction();
|
|
if (player.IsFirst) firstPlayer = player;
|
|
if (player.IsFirst) firstPlayer = player;
|
|
@@ -155,24 +155,21 @@ namespace MafiaTelegramBot.Game.GameRooms
|
|
{
|
|
{
|
|
if (role is Roles.Mafia)
|
|
if (role is Roles.Mafia)
|
|
{
|
|
{
|
|
- var votes = players.Where(p=> p.IsAlive)
|
|
|
|
- .GroupBy(p => p.CurrentRole.GetNightTarget())
|
|
|
|
|
|
+ var votes = players.Where(p=> p.IsAlive && p.CurrentRole.NightTargetId != -1)
|
|
|
|
+ .GroupBy(p => p.CurrentRole.NightTargetId)
|
|
.Select(item => new {id = item.Key, count = item.Count()})
|
|
.Select(item => new {id = item.Key, count = item.Count()})
|
|
.ToList();
|
|
.ToList();
|
|
if (votes.Count > 0)
|
|
if (votes.Count > 0)
|
|
{
|
|
{
|
|
var max = votes.Max(item => item.count);
|
|
var max = votes.Max(item => item.count);
|
|
var maxCount = votes.Count(item => item.count == max);
|
|
var maxCount = votes.Count(item => item.count == max);
|
|
- if (maxCount != 1)
|
|
|
|
- {
|
|
|
|
- mafiaNotAgree = $"\n{strings.mafia_not_agree}";
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- var selected = votes.First(item => item.count == max);
|
|
|
|
- if (selected.id == -1) continue;
|
|
|
|
- await Players[selected.id].CurrentRole.Kill();
|
|
|
|
|
|
+ if (maxCount > 1) continue;
|
|
|
|
+ var selected = votes.First(item => item.count == max).id;
|
|
|
|
+ if (selected == -1) continue;
|
|
|
|
+ await Players[selected].CurrentRole.Kill();
|
|
}
|
|
}
|
|
|
|
+ else
|
|
|
|
+ mafiaNotAgree = strings.mafia_not_kill_message;
|
|
foreach (var mafia in players) await mafia.CurrentRole.ApplyNightActionResult();
|
|
foreach (var mafia in players) await mafia.CurrentRole.ApplyNightActionResult();
|
|
}
|
|
}
|
|
else if (players.Count == 1)
|
|
else if (players.Count == 1)
|
|
@@ -186,41 +183,38 @@ namespace MafiaTelegramBot.Game.GameRooms
|
|
var message = strings.city_wakes_up;
|
|
var message = strings.city_wakes_up;
|
|
if(afterKill.IsEquals(beforeKill)) message += strings.everyone_survived;
|
|
if(afterKill.IsEquals(beforeKill)) message += strings.everyone_survived;
|
|
else foreach (var (id, alive) in afterKill)
|
|
else foreach (var (id, alive) in afterKill)
|
|
- if(beforeKill[id] != alive) message += alive
|
|
|
|
- ? $"{Players[id].NickName} {strings.will_be_ressurected}"
|
|
|
|
- : $"{Players[id].NickName} {strings.will_be_killed}";
|
|
|
|
|
|
+ if(beforeKill[id] != alive) {
|
|
|
|
+ message += alive
|
|
|
|
+ ? $"{Players[id].NickName} {strings.will_be_ressurected}"
|
|
|
|
+ : $"{Players[id].NickName} {strings.will_be_killed}";
|
|
|
|
+ await PlayersCh.SendTo(id, alive ? strings.you_will_be_ressurected : strings.you_will_be_killed);
|
|
|
|
+ }
|
|
message += mafiaNotAgree;
|
|
message += mafiaNotAgree;
|
|
await PlayersCh.SendSticker(Stickers.Sticker["Day"]);
|
|
await PlayersCh.SendSticker(Stickers.Sticker["Day"]);
|
|
await PlayersCh.Send(message);
|
|
await PlayersCh.Send(message);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
- private async Task<List<Player>> DefencePhase()
|
|
|
|
|
|
+ private async Task DefencePhase(List<Player> contenders)
|
|
{
|
|
{
|
|
- return await Task.Run( async () =>
|
|
|
|
|
|
+ await Task.Run( async () =>
|
|
{
|
|
{
|
|
- var contendersForDispatch = _voteUpList.Where(p => p.VotedCount == _largeVote).ToList();
|
|
|
|
- foreach (var defender in _voteUpList) defender.VotedCount = 0;
|
|
|
|
- _voteUpList.Clear();
|
|
|
|
- _largeVote = 0;
|
|
|
|
- if (contendersForDispatch.Count == 1) return contendersForDispatch;
|
|
|
|
- foreach (var defender in contendersForDispatch) await defender.CurrentRole.DefenceAction();
|
|
|
|
- var votersPlayers = Players.Values
|
|
|
|
- .Where(p => p.IsAlive)
|
|
|
|
- .Except(contendersForDispatch)
|
|
|
|
- .ToList();
|
|
|
|
|
|
+ VoteUpList.Clear();
|
|
|
|
+ VoteKillList.Clear();
|
|
|
|
+ foreach (var contender in contenders) await contender.CurrentRole.DefenceAction();
|
|
|
|
+ var votersPlayers = Players.Values.Where(p => p.IsAlive).ToArray();
|
|
Timer votingTimer = new() {Interval = 10 * 1000, AutoReset = false};
|
|
Timer votingTimer = new() {Interval = 10 * 1000, AutoReset = false};
|
|
var resetEvent = new ManualResetEvent(false);
|
|
var resetEvent = new ManualResetEvent(false);
|
|
votingTimer.Elapsed += (_, _) => resetEvent.Set();
|
|
votingTimer.Elapsed += (_, _) => resetEvent.Set();
|
|
List<Message> messagesToDelete = new();
|
|
List<Message> messagesToDelete = new();
|
|
foreach (var player in votersPlayers)
|
|
foreach (var player in votersPlayers)
|
|
- messagesToDelete.Add(await player.CurrentRole.SendVotingList(contendersForDispatch));
|
|
|
|
|
|
+ messagesToDelete.Add(await PlayersCh.SendTo(player.ChatId, strings.you_have_ten_seconds,
|
|
|
|
+ Keyboard.VoteKeyboard(contenders, player.Id, vote: Callback.VoteToKill)));
|
|
votingTimer.Start();
|
|
votingTimer.Start();
|
|
resetEvent.WaitOne();
|
|
resetEvent.WaitOne();
|
|
votingTimer.Stop();
|
|
votingTimer.Stop();
|
|
foreach (var message in messagesToDelete)
|
|
foreach (var message in messagesToDelete)
|
|
- await Bot.EditMessageAsync(message.Chat.Id, message.MessageId, strings.time_out);
|
|
|
|
- return _voteUpList.Where(p => p.VotedCount == _largeVote).ToList();
|
|
|
|
|
|
+ await PlayersCh.EditTo(message.Chat.Id, message.MessageId, strings.time_out);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -228,28 +222,74 @@ namespace MafiaTelegramBot.Game.GameRooms
|
|
{
|
|
{
|
|
await Task.Run(async () =>
|
|
await Task.Run(async () =>
|
|
{
|
|
{
|
|
- var contenders = await DefencePhase();
|
|
|
|
- if (contenders.Count > 1) contenders = await DefencePhase();
|
|
|
|
- if (contenders.Count is > 1 or 0 ) await PlayersCh.Send(strings.villagers_could_not_decide);
|
|
|
|
- else await contenders[0].CurrentRole.Dispatch();
|
|
|
|
|
|
+ if (VoteUpList.Count == 1) await VoteUpList[0].CurrentRole.Dispatch();
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ await DefencePhase(VoteUpList);
|
|
|
|
+ var contenders = await CalculateCandidates();
|
|
|
|
+ switch (contenders.Count)
|
|
|
|
+ {
|
|
|
|
+ case 1:
|
|
|
|
+ await VoteUpList[0].CurrentRole.Dispatch();
|
|
|
|
+ break;
|
|
|
|
+ case > 1:
|
|
|
|
+ await DefencePhase(contenders);
|
|
|
|
+ contenders = await CalculateCandidates();
|
|
|
|
+ if (contenders.Count == 1) await VoteUpList[0].CurrentRole.Dispatch();
|
|
|
|
+ else await PlayersCh.Send(strings.villagers_could_not_decide);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ await PlayersCh.Send(strings.villagers_could_not_decide);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
- private async Task<Message> PutUpVote(long playerId, long targetId)
|
|
|
|
|
|
+ private async Task<List<Player>> CalculateCandidates()
|
|
|
|
+ {
|
|
|
|
+ var message = strings.results_of_voting;
|
|
|
|
+ foreach (var (playerId, targetId) in VoteKillList)
|
|
|
|
+ message += $"\n{Players[playerId]} {strings.vote_to} {Players[targetId]}";
|
|
|
|
+ if (message == strings.results_of_voting) message = strings.no_one_voted;
|
|
|
|
+ await PlayersCh.Send(message);
|
|
|
|
+
|
|
|
|
+ var votes = VoteUpList.Where(p=> p.IsAlive && p.IsPlaying)
|
|
|
|
+ .GroupBy(p => p.Id)
|
|
|
|
+ .Select(item => new {id = item.Key, count = item.Count()})
|
|
|
|
+ .ToList();
|
|
|
|
+ List<Player> result = new();
|
|
|
|
+ if (votes.Count <= 0) return result;
|
|
|
|
+ var max = votes.Max(item => item.count);
|
|
|
|
+ var maxObjects = votes.Where(item => item.count == max);
|
|
|
|
+ result.AddRange(maxObjects.Select(obj => Players[obj.id]));
|
|
|
|
+ return result.ToList();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private async Task PutUpVote(long playerId, long targetId, int messageId, bool toKill = false)
|
|
{
|
|
{
|
|
var player = Players[playerId];
|
|
var player = Players[playerId];
|
|
- var target = Players[targetId];
|
|
|
|
- _voteUpList.AddUnique(target);
|
|
|
|
- target.VotedCount++;
|
|
|
|
- if (target.VotedCount > _largeVote) _largeVote = target.VotedCount;
|
|
|
|
- if (playerId != targetId)
|
|
|
|
|
|
+ if (targetId == 0)
|
|
{
|
|
{
|
|
-
|
|
|
|
- await PlayersCh.SendExcept(player.ChatId, $"{player.NickName} {strings.vote_to} {target.NickName}");
|
|
|
|
- return await Bot.SendWithMarkdown2(player.ChatId, $"{strings.you_vote_player} {target.NickName}");
|
|
|
|
|
|
+ if (!toKill) await PlayersCh.SendExcept(player.ChatId, $"{player.NickName} {strings.skip_vote}");
|
|
|
|
+ await PlayersCh.EditTo(player.ChatId, messageId, strings.you_skip_vote);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ var target = Players[targetId];
|
|
|
|
+ VoteUpList.Add(target);
|
|
|
|
+ if (toKill) VoteKillList.Add(playerId, targetId);
|
|
|
|
+ if (playerId != targetId)
|
|
|
|
+ {
|
|
|
|
+ if (!toKill) await PlayersCh.SendExcept(player.ChatId, $"{player.NickName} {strings.put_up_vote_to} {target.NickName}");
|
|
|
|
+ await PlayersCh.EditTo(player.ChatId, messageId, $"{strings.you_vote_player} {target.NickName}");
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if (!toKill) await PlayersCh.SendExcept(player.ChatId, $"{player.NickName} {strings.vote_to_self}");
|
|
|
|
+ await PlayersCh.EditTo(player.ChatId, messageId, strings.you_vote_to_self);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- await PlayersCh.SendExcept(player.ChatId, $"{player.NickName} {strings.vote_to_self}");
|
|
|
|
- return await Bot.SendWithMarkdown2(player.ChatId, strings.you_vote_to_self);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
private async Task EndOfGame()
|
|
private async Task EndOfGame()
|