407 lines
16 KiB
C#
407 lines
16 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
|
|
namespace Wolf
|
|
{
|
|
internal class Game
|
|
{
|
|
|
|
List<Player> players = new List<Player>();
|
|
List<Player> playersToKill = new List<Player>();
|
|
private OSCClient logicClient;
|
|
private OSCClient ttsClient;
|
|
private Logger logger;
|
|
public bool isFinished = false;
|
|
public bool readHistory = true;
|
|
|
|
public Game(OSCClient client, OSCClient ttsClient, Logger logger)
|
|
{
|
|
this.logicClient = client;
|
|
this.ttsClient = ttsClient;
|
|
this.logger = logger;
|
|
}
|
|
|
|
public void AddPlayer(Player player)
|
|
{
|
|
players.Add(player);
|
|
logger.Log($"Player {player.Name} has joined the game.");
|
|
}
|
|
|
|
public Task StartGame()
|
|
{
|
|
int playercount = players.Count;
|
|
|
|
if (playercount <= 5)
|
|
{
|
|
logger.Log("Not enough players to start the game.");
|
|
ttsClient.Read(logger.getLastLine());
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
List<Player.Role> roles = Player.GetRoleAssignmentForPlayerCount(playercount);
|
|
|
|
players[0].PlayerRole = roles[2];
|
|
for (int i = 1; i < players.Count; i++)
|
|
{
|
|
players[i].PlayerRole = roles[i];
|
|
}
|
|
//Random random = new Random();
|
|
//for (int i = 0; i < players.Count; i++)
|
|
//{
|
|
// int randomIndex = random.Next(roles.Count);
|
|
// players[i].PlayerRole = roles[randomIndex];
|
|
// roles.RemoveAt(randomIndex);
|
|
//}
|
|
|
|
foreach (Player p in players)
|
|
{
|
|
logger.Log($"Player {p.Name} is assigned the role {p.PlayerRole}");
|
|
}
|
|
|
|
var res = logicClient.GetConfirmation(new List<Player> { players[0], players[1] });
|
|
res.Wait();
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public void ShowRole(Player player)
|
|
{
|
|
|
|
Console.Clear();
|
|
Console.CursorVisible = false;
|
|
|
|
int width = Console.WindowWidth;
|
|
int height = Console.WindowHeight;
|
|
|
|
string playerName = player.Name;
|
|
string roleName = player.PlayerRole.ToString();
|
|
string isAliveStatus = player.isAlive ? "ALIVE" : "DEAD";
|
|
string tags = player.tags.Count > 0 ? string.Join(", ", player.tags) : "NONE";
|
|
|
|
string[] lines = new string[]
|
|
{
|
|
$"PLAYER: {playerName}",
|
|
$"ROLE: {roleName}",
|
|
$"STATUS: {isAliveStatus}",
|
|
$"TAGS: {tags}"
|
|
};
|
|
|
|
// Top (0°) - Normal text
|
|
int topRow = height / 8;
|
|
Console.SetCursorPosition(0, topRow);
|
|
Console.ForegroundColor = ConsoleColor.Green;
|
|
foreach (string line in lines)
|
|
{
|
|
Console.SetCursorPosition((width - line.Length) / 2, topRow++);
|
|
Console.WriteLine(line);
|
|
}
|
|
|
|
Console.ForegroundColor = ConsoleColor.White;
|
|
}
|
|
|
|
public Task FirstRound()
|
|
{
|
|
logger.Log("Die erste Runde beginnt.");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
logger.Log("Alle Spieler schlafen ein");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
getConfirmationEveryoneAsleep();
|
|
|
|
foreach (Player p in players)
|
|
{
|
|
logger.Log($"Spieler {p.Name} wacht auf und sieht sich seine Rolle an.");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
ShowRole(p);
|
|
logger.Log($"Spieler {p.Name} hat seine Rolle gesehen und geht wieder schlafen.");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
getConfirmationEveryoneAsleep();
|
|
}
|
|
|
|
Console.Clear();
|
|
|
|
//Amor
|
|
Player player = players.FirstOrDefault(p => p.PlayerRole == Player.Role.amor);
|
|
if (player != null && player.isAlive)
|
|
{
|
|
logger.Log("Amor wacht auf");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
//maybe wait
|
|
logger.Log("Amor verschiesst seinen ersten Pfeil");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
int targetid1 = getPlayerId(players.Where(p=>p.isAlive == true && p.role != Player.Role.amor).ToList(),
|
|
new List<Player>() { player });
|
|
Player target = players.Find(p => p.id == targetid1);
|
|
|
|
logger.Log("Amor vershiesst seinen zweiten Pfeil");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
int targetid2 = getPlayerId(players.Where(p=>p.isAlive == true && p.role != Player.Role.amor && p.id != target.id).ToList(),
|
|
new List<Player>() { player });
|
|
Player target2 = players.Find(p => p.id == targetid2);
|
|
|
|
logger.Log("Amor schlaeft wieder ein.");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
getConfirmationEveryoneAsleep();
|
|
if (target != null && target2 != null && target.isAlive && target2.isAlive)
|
|
{
|
|
target.tags.Add(Player.Tag.lover);
|
|
target2.tags.Add(Player.Tag.lover);
|
|
logger.Log($"Spieler {target.id} und Spieler {target2.id} sind jetzt verliebt.");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
logger.Log($"Spieler {target.id} und Spieler {target2.id} wachen auf und sehen sich an.");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
getConfirmation(new List<Player>() { target, target2 });
|
|
logger.Log("Die Verliebten gehen wieder schlafen");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
}
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task NormalRound()
|
|
{
|
|
if (CheckWinConditions())
|
|
{
|
|
isFinished = true;
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
// Seer
|
|
Player player = players.FirstOrDefault(p => p.PlayerRole == Player.Role.seer);
|
|
Player target = null;
|
|
if (player != null && player.isAlive)
|
|
{
|
|
logger.Log("Das Sehende wacht auf.");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
logger.Log("Das Sehende wählt einen Spieler");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
int targetid = getPlayerId(players.Where(p=>p.isAlive == true && p.role != Player.Role.seer).ToList(),
|
|
new List<Player>() { player });
|
|
target = players.Find(p => p.id == targetid);
|
|
RevealRoleToSeer(target);
|
|
logger.Log("Das Sehende schlaeft wieder ein");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
getConfirmationEveryoneAsleep();
|
|
}
|
|
|
|
// Werewolves
|
|
logger.Log("Werwoelfe wachen auf");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
logger.Log("Werwoelfe waehlen einen Spieler");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
int targetId = getPlayerId(players.Where(p=>p.isAlive == true && p.role != Player.Role.werewolf).ToList(),
|
|
players.Where(p => p.PlayerRole == Player.Role.werewolf).ToList());
|
|
target = players.Find(p => p.id == targetId);
|
|
playersToKill.Add(target);
|
|
logger.Log("Werwoelfe schlafen ein");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
getConfirmationEveryoneAsleep();
|
|
|
|
|
|
//witch
|
|
player = players.FirstOrDefault(p => p.PlayerRole == Player.Role.witch);
|
|
if (player != null && player.isAlive)
|
|
{
|
|
logger.Log("Das Hexende wacht auf.");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
if (playersToKill.Count > 0)
|
|
{
|
|
logger.Log($"Der Spieler {playersToKill[0].Name} wird von den Werwölfen ausgewählt");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
logger.Log("Hexendes, moechtest du denjenigen retten?");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
bool res = getConfirmation(new List<Player>() { player });
|
|
if (res)
|
|
{
|
|
playersToKill.RemoveAt(0);
|
|
logger.Log("Das Hexende hat sich entschieden den Spieler zu retten");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
}
|
|
else
|
|
{
|
|
logger.Log("Das Hexende hat sich dagegen entschieden, den Spieler zu retten.");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
}
|
|
}
|
|
logger.Log("Witch, do you want to poison someone? (yes/no)");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
int posionRes = getPlayerId(players.Where(p=>p.isAlive == true && p.role != Player.Role.witch).ToList(),
|
|
new List<Player>() { player });
|
|
target = players.FirstOrDefault(p => p.id == posionRes);
|
|
if (target != null && target.isAlive)
|
|
{
|
|
playersToKill.Add(target);
|
|
logger.Log($"Witch has decided to poison player {target.Name}.");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
}
|
|
else
|
|
{
|
|
logger.Log("Witch has decided not to poison anyone.");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
}
|
|
}
|
|
|
|
foreach (Player p in playersToKill)
|
|
{
|
|
killPlayer(p);
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
|
|
}
|
|
|
|
public bool CheckWinConditions()
|
|
{
|
|
int werewolvesAlive = players.Count(p => p.isAlive && p.PlayerRole == Player.Role.werewolf);
|
|
int villagersAlive = players.Count(p => p.isAlive && p.PlayerRole != Player.Role.werewolf);
|
|
int totalAlive = players.Count(p => p.isAlive);
|
|
int loversAlive = players.Count(p => p.isAlive && p.tags.Contains(Player.Tag.lover));
|
|
if (werewolvesAlive == 0)
|
|
{
|
|
logger.Log("Villagers win!");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
return true;
|
|
}
|
|
else if (villagersAlive == 0)
|
|
{
|
|
logger.Log("Werewolves win!");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
return true;
|
|
}
|
|
else if(totalAlive == 2 && loversAlive == 2)
|
|
{
|
|
logger.Log("Lovers win!");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public void killPlayer(Player player)
|
|
{
|
|
if (player != null && player.isAlive)
|
|
{
|
|
player.isAlive = false;
|
|
logger.Log($"Player {player.Name} has been killed.");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
if (player.tags.Contains(Player.Tag.lover))
|
|
{
|
|
logger.Log($"Player {player.Name} was a lover, their lover also dies...");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
Player lover = players.FirstOrDefault(p => p.tags.Contains(Player.Tag.lover) && p != player);
|
|
player.tags.Remove(Player.Tag.lover);
|
|
if (lover != null)
|
|
{
|
|
killPlayer(lover);
|
|
}
|
|
}
|
|
if (player.PlayerRole == Player.Role.hunter)
|
|
{
|
|
logger.Log($"Player {player.Name} was the hunter, they can choose someone to kill...");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
int targetId = getPlayerId(players.Where(p => p.isAlive == true && p.role != Player.Role.hunter).ToList(),
|
|
new List<Player>() { player });
|
|
Player target = players.Find(p => p.id == targetId);
|
|
if (player != null && player.isAlive)
|
|
{
|
|
logger.Log($"Player {player.Name} has chosen to kill player {target.Name}.");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
killPlayer(target);
|
|
}
|
|
else
|
|
{
|
|
logger.Log("Hunter has decided not to kill anyone.");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
}
|
|
}
|
|
if (player.PlayerRole == Player.Role.werewolf)
|
|
{
|
|
logger.Log($"Player {player.Name} was a werewolf, the villagers rejoice!");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
}
|
|
if (player.PlayerRole == Player.Role.villager)
|
|
{
|
|
logger.Log($"Player {player.Name} was a villager, the werewolves rejoice!");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
}
|
|
if (player.PlayerRole == Player.Role.seer)
|
|
{
|
|
logger.Log($"Player {player.Name} was the seer, the werewolves rejoice!");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
}
|
|
if (player.PlayerRole == Player.Role.witch)
|
|
{
|
|
logger.Log($"Player {player.Name} was the witch, the werewolves rejoice!");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
logger.Log("Player not found.");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
}
|
|
}
|
|
|
|
public void RevealRoleToSeer(Player player)
|
|
{
|
|
if (player != null)
|
|
{
|
|
ShowRole(player);
|
|
}
|
|
else
|
|
{
|
|
logger.Log("Player not found.");
|
|
ttsClient.Read(logger.getLastLine(), readHistory);
|
|
}
|
|
}
|
|
|
|
|
|
public int getPlayerId(List<Player> targets, List<Player> pois)
|
|
{
|
|
try
|
|
{
|
|
int res = logicClient.GetPlayerId(targets, pois).WaitAsync(TimeSpan.FromSeconds(10)).Result;
|
|
if (res >= 0)
|
|
{
|
|
return res;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
public bool getConfirmation(List<Player> players)
|
|
{
|
|
try
|
|
{
|
|
bool res = logicClient.GetConfirmation(players).WaitAsync(TimeSpan.FromSeconds(10)).Result;
|
|
if (res)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public bool getConfirmationEveryoneAsleep()
|
|
{
|
|
try
|
|
{
|
|
return logicClient.GetConfirmationEveryoneAsleep().WaitAsync(TimeSpan.FromSeconds(30)).Result;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
}
|