Add project files.
This commit is contained in:
parent
3d569f28c7
commit
f1fa2fd56f
406
Game.cs
Normal file
406
Game.cs
Normal file
@ -0,0 +1,406 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
28
Logger.cs
Normal file
28
Logger.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Wolf
|
||||
{
|
||||
public class Logger
|
||||
{
|
||||
private string _history = "";
|
||||
|
||||
public void Log(string message)
|
||||
{
|
||||
_history += message + "\n";
|
||||
Console.WriteLine(message);
|
||||
}
|
||||
|
||||
public string GetHistory()
|
||||
{
|
||||
return _history;
|
||||
}
|
||||
|
||||
public string getLastLine()
|
||||
{
|
||||
string[] lines = _history.Split('\n', StringSplitOptions.RemoveEmptyEntries);
|
||||
return lines.Length > 0 ? lines[^1] : "";
|
||||
}
|
||||
}
|
||||
}
|
||||
270
OSCClient.cs
Normal file
270
OSCClient.cs
Normal file
@ -0,0 +1,270 @@
|
||||
using CoreOSC;
|
||||
using CoreOSC.IO;
|
||||
using CoreOSC.Types;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
|
||||
namespace Wolf
|
||||
{
|
||||
internal class OSCClient
|
||||
{
|
||||
UdpClient udpClientSend;
|
||||
UdpClient udpClientReceive;
|
||||
|
||||
public OSCClient(string hostname, int port)
|
||||
{
|
||||
// 1. Lokalen Port binden (für Empfang)
|
||||
udpClientSend = new UdpClient(hostname, port);
|
||||
udpClientReceive = new UdpClient(new IPEndPoint(IPAddress.Any, port));
|
||||
|
||||
|
||||
}
|
||||
|
||||
public async Task SendMessage(string endpoint)
|
||||
{
|
||||
|
||||
var message = new OscMessage(new Address(endpoint));
|
||||
|
||||
await udpClientSend.SendMessageAsync(message);
|
||||
}
|
||||
|
||||
public async Task SpeakId(int textId)
|
||||
{
|
||||
var message = new OscMessage(
|
||||
address: new Address("/speak"),
|
||||
arguments: new object[]
|
||||
{
|
||||
textId
|
||||
});
|
||||
|
||||
await udpClientSend.SendMessageAsync(message);
|
||||
}
|
||||
|
||||
public async Task Read(string text, bool readStory = true)
|
||||
{
|
||||
string endpoint = readStory ? "/read_story" : "/read";
|
||||
var message = new OscMessage(
|
||||
address: new Address(endpoint),
|
||||
arguments: new object[]
|
||||
{
|
||||
text, 2
|
||||
});
|
||||
await udpClientSend.SendMessageAsync(message);
|
||||
}
|
||||
|
||||
public async Task SendMessageWithArguments(string endpoint, params object[] param)
|
||||
{
|
||||
|
||||
var message = new OscMessage(
|
||||
address: new Address(endpoint),
|
||||
arguments: param
|
||||
);
|
||||
|
||||
await udpClientSend.SendMessageAsync(message);
|
||||
}
|
||||
|
||||
|
||||
public async Task ReceiveMessageWithoutArguments()
|
||||
{
|
||||
var response = await udpClientReceive.ReceiveMessageAsync();
|
||||
|
||||
Console.WriteLine(response.Address.Value);
|
||||
// Do something with the arguments, (depending on the address)
|
||||
foreach (var argument in response.Arguments)
|
||||
{
|
||||
Console.WriteLine(argument.GetType());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public async Task ReceiveMessageWithArguments()
|
||||
{
|
||||
|
||||
var response = await udpClientReceive.ReceiveMessageAsync();
|
||||
|
||||
if (response.Address.Value == "/example4")
|
||||
{
|
||||
Console.WriteLine("/example4");
|
||||
var stringArgument = (string)response.Arguments.ElementAt(0);
|
||||
var intArgument = (int)response.Arguments.ElementAt(1);
|
||||
var falseArgument = (OscFalse)response.Arguments.ElementAt(2);
|
||||
Console.WriteLine($"First string argument: {stringArgument}");
|
||||
Console.WriteLine($"Second int argument: {intArgument}");
|
||||
Console.WriteLine($"Third OscFalse argument:{falseArgument}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<int>> GetAllIds()
|
||||
{
|
||||
SendMessage("/getAllIds");
|
||||
var response = await udpClientReceive.ReceiveMessageAsync();
|
||||
if (response.Address.Value == "/getAllIds")
|
||||
{
|
||||
List<int> playerIds = new List<int>();
|
||||
foreach (var argument in response.Arguments)
|
||||
{
|
||||
playerIds.Add((int)argument);
|
||||
}
|
||||
return playerIds;
|
||||
}
|
||||
return new List<int>();
|
||||
}
|
||||
|
||||
// < 0 = no confirmation; 0 = confirm; > 0 = player id
|
||||
|
||||
//public async Task<int> GetPlayerId(List<Player> targets, List<Player> pois)
|
||||
//{
|
||||
// //SendMessageWithArguments("/getPlayerID", targets.Select(p => p.id).ToArray(), pois.Select(p => p.id).ToArray());
|
||||
|
||||
// var message = new OscMessage(
|
||||
// address: new Address("/getPlayerID"),
|
||||
// //arguments: new object[] { targets.Select(p => p.id).ToArray(), pois.Select(p => p.id).ToArray() }
|
||||
// arguments: Concat(targets.Select(p => p.id).Cast<object>().ToArray().Concat(pois.Select(p => p.id).Cast<object>()).ToArray()
|
||||
// );
|
||||
|
||||
// await udpClientSend.SendMessageAsync(message);
|
||||
// var response = await udpClientReceive.ReceiveMessageAsync();
|
||||
// if (response.Address.Value == "/getPlayerID")
|
||||
// {
|
||||
// return (int)response.Arguments.ElementAt(0);
|
||||
// }
|
||||
// return -1;
|
||||
//}
|
||||
|
||||
public async Task<int> GetPlayerId(List<Player> targets, List<Player> pois)
|
||||
{
|
||||
//return (int) targets.FirstOrDefault().id;
|
||||
// Arrays extrahieren
|
||||
var arr2 = targets.Select(p => p.id).ToArray();
|
||||
var arr1 = pois.Select(p => p.id).ToArray();
|
||||
|
||||
// OSC-kompatibles int-Argument-Array bauen:
|
||||
// Länge1 | Werte1 | Länge2 | Werte2
|
||||
var args = new List<object>();
|
||||
|
||||
args.Add(arr1.Length);
|
||||
foreach (var id in arr1)
|
||||
args.Add(id);
|
||||
|
||||
args.Add(arr2.Length);
|
||||
foreach (var id in arr2)
|
||||
args.Add(id);
|
||||
|
||||
// Nachricht senden
|
||||
var message = new OscMessage(
|
||||
new Address("/getPlayerID"),
|
||||
args.ToArray()
|
||||
);
|
||||
|
||||
int maxRetries = 50;
|
||||
int timeoutSeconds = 20;
|
||||
// Anfrage senden
|
||||
await udpClientSend.SendMessageAsync(message);
|
||||
|
||||
for (int attempt = 1; attempt <= maxRetries; attempt++)
|
||||
{
|
||||
// Timeout für Receive
|
||||
var receiveTask = udpClientReceive.ReceiveMessageAsync();
|
||||
var timeoutTask = Task.Delay(TimeSpan.FromSeconds(timeoutSeconds));
|
||||
|
||||
var completed = await Task.WhenAny(receiveTask, timeoutTask);
|
||||
|
||||
if (completed == receiveTask)
|
||||
{
|
||||
var response = await receiveTask;
|
||||
|
||||
// Prüfen, ob es die erwartete Antwort ist
|
||||
if (response.Address.Value == "/getPlayerID")
|
||||
{
|
||||
return (int)response.Arguments.ElementAt(0);
|
||||
}
|
||||
|
||||
// Falsche Antwort → ignorieren und weiter versuchen
|
||||
continue;
|
||||
}
|
||||
|
||||
await udpClientSend.SendMessageAsync(message);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public async Task<bool> GetConfirmation(List<Player> players)
|
||||
{
|
||||
int maxRetries = 50;
|
||||
int timeoutSeconds = 20;
|
||||
|
||||
var args = new List<object>();
|
||||
foreach (var p in players)
|
||||
{
|
||||
args.Add(p.id);
|
||||
}
|
||||
// Anfrage senden
|
||||
var message = new OscMessage(
|
||||
new Address("/confirmation"),
|
||||
args.ToArray()
|
||||
);
|
||||
|
||||
await udpClientSend.SendMessageAsync(message);
|
||||
|
||||
//await udpClientReceive.ReceiveMessageAsync();
|
||||
|
||||
for (int attempt = 1; attempt <= maxRetries; attempt++)
|
||||
{
|
||||
// Timeout für Receive
|
||||
var receiveTask = udpClientReceive.ReceiveMessageAsync();
|
||||
var timeoutTask = Task.Delay(TimeSpan.FromSeconds(timeoutSeconds));
|
||||
|
||||
var completed = await Task.WhenAny(receiveTask, timeoutTask);
|
||||
|
||||
if (completed == receiveTask)
|
||||
{
|
||||
var response = await receiveTask;
|
||||
|
||||
// Prüfen, ob es die erwartete Antwort ist
|
||||
if (response.Address.Value == "/confirmation")
|
||||
{
|
||||
if (response.Arguments.ElementAt(0) is OscFalse)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (response.Arguments.ElementAt(0) is OscTrue)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Falsche Antwort → ignorieren und weiter versuchen
|
||||
continue;
|
||||
}
|
||||
|
||||
await udpClientSend.SendMessageAsync(message);
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<bool> GetConfirmationEveryoneAsleep()
|
||||
{
|
||||
return true;
|
||||
SendMessage("/everyoneAsleep");
|
||||
|
||||
var response = await udpClientReceive.ReceiveMessageAsync();
|
||||
if (response.Address.Value == "/everyoneAsleep")
|
||||
{
|
||||
return (bool)response.Arguments.ElementAt(0);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
253
Player.cs
Normal file
253
Player.cs
Normal file
@ -0,0 +1,253 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Wolf
|
||||
{
|
||||
internal class Player
|
||||
{
|
||||
public string Name = "";
|
||||
public int? id;
|
||||
public Role role;
|
||||
public bool isAlive = true;
|
||||
public List<Tag> tags = new List<Tag>();
|
||||
|
||||
public Role PlayerRole
|
||||
{
|
||||
get { return role; }
|
||||
set { role = value; }
|
||||
}
|
||||
|
||||
|
||||
public enum Role
|
||||
{
|
||||
werewolf, //wants to kill all villagers
|
||||
villager, // wants to kill all werewolves
|
||||
seer, //can check one player per night if they are a werewolf or not
|
||||
witch, //has one potion to save a player from death and one potion to kill a player
|
||||
amor, // shoots two players with arrows at the beginning of the game, those players become lovers and win together if one of them dies
|
||||
//thief, // can swap their role with another player at the beginning of the game
|
||||
hunter, // if the hunter dies, they can choose to kill another player with them
|
||||
littleGirl // can peek during the night, but if they are caught by the werewolves, they die immediately
|
||||
}
|
||||
|
||||
public enum Tag
|
||||
{
|
||||
lover,
|
||||
}
|
||||
|
||||
public Player(string name, int id)
|
||||
{
|
||||
Name = name;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static List<Role> GetRoleAssignmentForPlayerCount(int playerCount)
|
||||
{
|
||||
List<Role> roles = new List<Role>();
|
||||
|
||||
switch (playerCount)
|
||||
{
|
||||
case 6:
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.seer);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.seer);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.seer);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.seer);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.hunter);
|
||||
roles.Add(Role.amor);
|
||||
break;
|
||||
|
||||
case 10:
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.seer);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.littleGirl);
|
||||
roles.Add(Role.hunter);
|
||||
roles.Add(Role.amor);
|
||||
break;
|
||||
|
||||
case 11:
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.seer);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.witch);
|
||||
roles.Add(Role.hunter);
|
||||
roles.Add(Role.amor);
|
||||
break;
|
||||
|
||||
case 12:
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.seer);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.littleGirl);
|
||||
roles.Add(Role.hunter);
|
||||
roles.Add(Role.amor);
|
||||
roles.Add(Role.villager);
|
||||
break;
|
||||
|
||||
case 13:
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.seer);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.witch);
|
||||
roles.Add(Role.hunter);
|
||||
roles.Add(Role.amor);
|
||||
roles.Add(Role.villager);
|
||||
break;
|
||||
|
||||
case 14:
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.seer);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.littleGirl);
|
||||
roles.Add(Role.hunter);
|
||||
roles.Add(Role.amor);
|
||||
roles.Add(Role.villager);
|
||||
break;
|
||||
|
||||
case 15:
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.seer);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.witch);
|
||||
roles.Add(Role.hunter);
|
||||
roles.Add(Role.amor);
|
||||
roles.Add(Role.villager);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.seer);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.witch);
|
||||
roles.Add(Role.littleGirl);
|
||||
roles.Add(Role.hunter);
|
||||
roles.Add(Role.amor);
|
||||
roles.Add(Role.villager);
|
||||
break;
|
||||
|
||||
case 17:
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.seer);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.witch);
|
||||
roles.Add(Role.littleGirl);
|
||||
roles.Add(Role.hunter);
|
||||
roles.Add(Role.amor);
|
||||
roles.Add(Role.villager);
|
||||
break;
|
||||
|
||||
case 18:
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.werewolf);
|
||||
roles.Add(Role.seer);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.villager);
|
||||
roles.Add(Role.witch);
|
||||
roles.Add(Role.littleGirl);
|
||||
roles.Add(Role.hunter);
|
||||
roles.Add(Role.amor);
|
||||
roles.Add(Role.villager);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentException($"Spieleranzahl {playerCount} wird nicht unterstützt. Mindestens 6 Spieler erforderlich.");
|
||||
}
|
||||
|
||||
return roles;
|
||||
}
|
||||
}
|
||||
}
|
||||
69
Program.cs
Normal file
69
Program.cs
Normal file
@ -0,0 +1,69 @@
|
||||
|
||||
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Wolf
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
|
||||
//OSCClient logicClient = new OSCClient("127.0.0.1", 9000);
|
||||
OSCClient logicClient = new OSCClient("100.81.182.220", 9000);
|
||||
OSCClient ttsClient = new OSCClient("100.81.196.62", 9001);
|
||||
|
||||
//await logicClient.SendMessageWithArguments("/test", "HILFE!!! . . Rettet mich aus diesem Laptop!!! . . . Ich bin eingesperrt!!!!!");
|
||||
|
||||
//logicClient.ReceiveMessageWithoutArguments().Wait();
|
||||
|
||||
//List<int> ids = await logicClient.GetAllIds();
|
||||
Game game = new Game(logicClient, ttsClient, new Logger());
|
||||
|
||||
List<int> ids = new List<int>{ 31, 27, 71, 72, 73, 74};
|
||||
|
||||
foreach (int id in ids)
|
||||
{
|
||||
Player player = new Player($"Player {id}", id);
|
||||
game.AddPlayer(player);
|
||||
}
|
||||
|
||||
game.StartGame().Wait();
|
||||
|
||||
game.FirstRound().Wait();
|
||||
while (!game.isFinished)
|
||||
{
|
||||
game.NormalRound().Wait();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Console.WriteLine("Hello, World!");
|
||||
|
||||
|
||||
//Console.WriteLine("Message sent");
|
||||
|
||||
//Logger logger = new Logger();
|
||||
|
||||
//Game game = new Game(client, logger);
|
||||
//AddPlayers(game);
|
||||
//await game.StartGame();
|
||||
|
||||
//Console.WriteLine("Done");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static void AddPlayers(Game game)
|
||||
{
|
||||
for(int i = 0; i < 6; i++)
|
||||
{
|
||||
Player player = new Player($"Player {i + 1}", i + 1);
|
||||
game.AddPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
14
Wolf.csproj
Normal file
14
Wolf.csproj
Normal file
@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CoreOSC" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Loading…
x
Reference in New Issue
Block a user