initial commit

This commit is contained in:
2025-08-14 08:35:04 +02:00
commit 6d40bfcf4c
96 changed files with 85096 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
namespace YatzyGame.Components
{
public class Dice
{
public int sides = 6;
Random random = new Random();
public Dice(int sides)
{
this.sides = sides;
}
public Dice()
{
}
public int Throw()
{
return random.Next(1, this.sides + 1);
}
}
}

View File

@@ -0,0 +1,323 @@
using YatzyLibrary;
namespace YatzyGame.Components
{
public class GameController
{
YatzyCheckers yatzyCheckers = new YatzyCheckers();
private Dictionary<string, Player> Players = new Dictionary<string, Player>();
public bool gameStarted = false;
public int rerolls = 0;
public Dictionary<int, int> Dices = new Dictionary<int, int>();
public List<int> selectedDices = new List<int>();
public Player currentPlayer;
public string gameID;
public bool onlineMultiplayer = false;
public string joinCode = string.Empty;
public GameController(string gameID, bool onlineMultiplayer, string joinCode)
{
this.gameID = gameID;
this.onlineMultiplayer = onlineMultiplayer;
this.joinCode = joinCode;
}
public void AddPlayer(string name)
{
Players.Add(name, new Player(name));
}
public void AddPlayer(string name, string playerID, bool owner = false)
{
Players.Add(name, new Player(name, playerID, owner));
}
public void RemovePlayer(string name)
{
Players.Remove(name);
}
public Player GetPlayer(string name)
{
return Players.FirstOrDefault(x => x.Key.Equals(name)).Value;
}
public List<Player> GetPlayers()
{
return Players.Select(x => x.Value).ToList();
}
public Dictionary<ScoreLine, int> GetPlayerScores(string name)
{
return GetPlayer(name).scores;
}
public void SetOrUpdatePlayerScore(string name, ScoreLine type, int value)
{
var playerScores = GetPlayerScores(name);
if (!playerScores.ContainsKey(type))
{
playerScores.Add(type, value);
}
else
{
playerScores[type] = value;
}
}
public void startGame()
{
this.gameStarted = true;
StartTurn(GetPlayers().FirstOrDefault());
}
public void stopGame()
{
this.gameStarted = false;
// Players.Clear();
}
public List<int> ThrowMany(List<Dice> dices)
{
var retval = new List<int>();
foreach (var dice in dices)
{
retval.Add(dice.Throw());
}
return retval;
}
public void StartTurn(Player player)
{
CheckForBonusesAndUpdateTopSum();
this.rerolls = 2;
this.selectedDices.Clear();
Dices.Clear();
for (int i = 0; i < 5; i++)
{
Dices.Add(i, new Dice(6).Throw());
}
currentPlayer = player;
}
public void SelectDice(int key)
{
if (selectedDices.Contains(key))
{
selectedDices.Remove(key);
}
else
{
selectedDices.Add(key);
}
}
public void RerollSelected()
{
if (rerolls <= 0)
return;
foreach (var key in selectedDices)
{
Dices[key] = new Dice(6).Throw();
}
rerolls--;
selectedDices.Clear();
}
public void InsertPoint(string type, List<int> dices)
{
var result = 0;
switch (type)
{
case "one":
result = yatzyCheckers.SingleThingy(dices, 1).value;
break;
case "two":
result = yatzyCheckers.SingleThingy(dices, 2).value;
break;
case "three":
result = yatzyCheckers.SingleThingy(dices, 3).value;
break;
case "four":
result = yatzyCheckers.SingleThingy(dices, 4).value;
break;
case "five":
result = yatzyCheckers.SingleThingy(dices, 5).value;
break;
case "six":
result = yatzyCheckers.SingleThingy(dices, 6).value;
break;
case "sum":
case "bonus":
break;
case "one_pair":
result = yatzyCheckers.PairChecker(dices, 1).value;
break;
case "two_pair":
result = yatzyCheckers.PairChecker(dices, 2).value;
break;
case "three_matching":
result = yatzyCheckers.SameNumberChecker(dices, 3).value;
break;
case "four_matching":
result = yatzyCheckers.SameNumberChecker(dices, 4).value;
break;
case "little_straight":
result = yatzyCheckers.StraightChecker(dices, "small").value;
break;
case "large_straight":
result = yatzyCheckers.StraightChecker(dices, "large").value;
break;
case "house":
result = yatzyCheckers.FullHouse(dices).value;
break;
case "chance":
result = yatzyCheckers.Chance(dices).value;
break;
case "yatzy":
result = yatzyCheckers.Yatzy(dices).value;
break;
default:
break;
}
var enu = (ScoreLine)Enum.Parse(typeof(ScoreLine), type);
SetOrUpdatePlayerScore(currentPlayer.name, enu, result);
NextTurn();
}
public void NextTurn()
{
var nextUser = GetNextKey(Players, currentPlayer.name);
var nextPlayer = Players.Where(x => x.Key.Equals(nextUser)).First().Value;
StartTurn(nextPlayer);
}
static TKey GetNextKey<TKey, TValue>(Dictionary<TKey, TValue> dict, TKey currentKey)
{
var keys = dict.Keys.ToList();
int index = keys.IndexOf(currentKey);
if (index == -1)
throw new ArgumentException("Key not found in dictionary.");
int nextIndex = (index + 1) % keys.Count; // Wrap around
return keys[nextIndex];
}
public void CheckForBonusesAndUpdateTopSum()
{
var scoresToGet = new[]
{
ScoreLine.one,
ScoreLine.two,
ScoreLine.three,
ScoreLine.four,
ScoreLine.four,
ScoreLine.five,
ScoreLine.six
};
foreach (var player in Players)
{
if (player.Value.scores.Where(x => scoresToGet.Contains(x.Key)).Select(x => x.Value).Sum() >= 63)
{
SetOrUpdatePlayerScore(player.Key, ScoreLine.bonus, 50);
}
else if (scoresToGet.All(req => player.Value.scores.ContainsKey(req)))
{
SetOrUpdatePlayerScore(player.Key, ScoreLine.bonus, 0);
}
SetOrUpdatePlayerScore(player.Key, ScoreLine.top_sum, player.Value.scores.Where(x => scoresToGet.Contains(x.Key)).Select(x => x.Value).Sum());
}
}
public static string TypeLabel(ScoreLine scoreLine)
{
return scoreLine switch
{
ScoreLine.one => "Ones",
ScoreLine.two => "Twos",
ScoreLine.three => "Threes",
ScoreLine.four => "Fours",
ScoreLine.five => "Fives",
ScoreLine.six => "Sixes",
ScoreLine.top_sum => "Top Sum",
ScoreLine.bonus => "Bonus",
ScoreLine.one_pair => "One Pair",
ScoreLine.two_pair => "Two Pair",
ScoreLine.three_matching => "Three of a Kind",
ScoreLine.four_matching => "Four of a Kind",
ScoreLine.little_straight => "Small Straight",
ScoreLine.large_straight => "Large Straight",
ScoreLine.house => "Full House",
ScoreLine.chance => "Chance",
ScoreLine.yatzy => "Yatzy",
_ => "Unknown"
};
}
public Player GetPlayerById(string id)
{
return Players.Where(x => x.Value.playerId.Equals(id)).First().Value;
}
}
public class Player
{
public Player(string name)
{
this.name = name;
this.scores = new Dictionary<ScoreLine, int>();
}
public Player(string name, string playerID, bool owner)
{
this.name = name;
this.scores = new Dictionary<ScoreLine, int>();
this.playerId = playerID;
this.Owner = owner;
}
public string name { get; set; }
public Dictionary<ScoreLine, int> scores { get; set; }
public string playerId { get; set; }
public bool Owner { get; set; }
}
public enum ScoreLine
{
one,
two,
three,
four,
five,
six,
top_sum,
bonus,
one_pair,
two_pair,
three_matching,
four_matching,
little_straight,
large_straight,
house,
chance,
yatzy
}
}

View File

@@ -0,0 +1,66 @@
namespace YatzyGame.Components
{
public class MultiplayerController
{
public Dictionary<string, GameController> gameControllers = new Dictionary<string, GameController>();
public Dictionary<string, string> playerGameControllerRelation = new Dictionary<string, string>();
public Dictionary<string, string> JoinCodes = new Dictionary<string, string>();
public string CreateGame(bool onlineMultiplayer, string name, string playerId)
{
var randomId = Guid.NewGuid().ToString();
var joinCode = new Random().Next(1, 99999).ToString();
gameControllers.Add(randomId, new GameController(randomId, onlineMultiplayer, joinCode));
JoinCodes.Add(joinCode, randomId);
GetGameController(randomId).AddPlayer(name, playerId, true);
return randomId;
}
public GameController GetGameController(string id)
{
if (gameControllers.ContainsKey(id))
{
return gameControllers[id];
}
return null;
}
public GameController GetPlayerGameController(string id)
{
if (playerGameControllerRelation.ContainsKey(id))
{
return GetGameController(playerGameControllerRelation[id]);
}
return null;
}
public GameController GetGameControllerFromJoinCode(string joinCode)
{
var gameId = JoinCodes.Where(x => x.Key.Equals(joinCode)).First().Value;
var gameController = GetGameController(gameId);
if (gameController != null)
{
return gameController;
}
return null;
}
public void CreatePlayer(string gameID, string playerId, string name)
{
var controller = GetGameController(gameID);
controller.AddPlayer(name, playerId);
playerGameControllerRelation.Add(playerId, gameID);
}
}
}

View File

@@ -0,0 +1,48 @@
using System.Collections.Concurrent;
using System.Net.WebSockets;
using System.Text;
namespace MyApp.WebSockets;
public class WebSocketManager
{
private readonly ConcurrentDictionary<string, WebSocket> _sockets = new();
public IReadOnlyDictionary<string, WebSocket> Sockets => _sockets;
public void AddSocket(string id, WebSocket socket)
{
_sockets[id] = socket;
}
public bool RemoveSocket(string id)
{
return _sockets.TryRemove(id, out _);
}
public async Task SendToClientAsync(string id, string message, CancellationToken ct = default)
{
if (_sockets.TryGetValue(id, out var socket) && socket.State == WebSocketState.Open)
{
var buffer = Encoding.UTF8.GetBytes(message);
await socket.SendAsync(buffer, WebSocketMessageType.Text, true, ct);
}
}
public async Task BroadcastAsync(string message, CancellationToken ct = default)
{
var buffer = Encoding.UTF8.GetBytes(message);
foreach (var (id, socket) in _sockets.ToArray())
{
if (socket.State == WebSocketState.Open)
{
await socket.SendAsync(buffer, WebSocketMessageType.Text, true, ct);
}
else
{
RemoveSocket(id);
}
}
}
}

View File

@@ -0,0 +1,62 @@
using System.Net.WebSockets;
using MyApp.WebSockets;
namespace MyApp.WebSockets;
public class WebSocketMiddleware
{
private readonly RequestDelegate _next;
private readonly WebSocketManager _manager;
public WebSocketMiddleware(RequestDelegate next, WebSocketManager manager)
{
_next = next;
_manager = manager;
}
public async Task InvokeAsync(HttpContext context)
{
if (context.Request.Path == "/ws")
{
if (!context.WebSockets.IsWebSocketRequest)
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
return;
}
// Let the client pass a stable id: ws://host/ws?clientId=abc123
var clientId = context.Request.Query["clientId"].ToString();
if (string.IsNullOrWhiteSpace(clientId))
{
clientId = Guid.NewGuid().ToString("N");
}
using var socket = await context.WebSockets.AcceptWebSocketAsync();
_manager.AddSocket(clientId, socket);
await ReceiveLoop(clientId, socket);
_manager.RemoveSocket(clientId);
return;
}
await _next(context);
}
private static async Task ReceiveLoop(string id, WebSocket socket)
{
var buffer = new byte[4 * 1024];
while (socket.State == WebSocketState.Open)
{
var result = await socket.ReceiveAsync(buffer, CancellationToken.None);
if (result.MessageType == WebSocketMessageType.Close)
{
await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
break;
}
// (Optional) handle incoming messages here if you need two-way comms.
}
}
}