aaf66b921f
- server/ monorepo: Hokm.Engine (C# port of TS engine+AI, validated by sim), Hokm.Server (SignalR GameHub, in-memory matchmaking/rooms, server-side turn timers + bot fill + disconnect handling, per-seat state broadcast), Hokm.Sim - JWT dev auth (OTP 1234 + email); CORS for the Next client; /hub/game - NuGet restored from mirrors (Soroush Nexus + Liara); NuGetAudit off - README + .NET .gitignore; static class Engine renamed Rules (namespace clash) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
41 lines
1.1 KiB
C#
41 lines
1.1 KiB
C#
namespace Hokm.Engine;
|
||
|
||
public static class Deck
|
||
{
|
||
public static readonly Suit[] Suits = { Suit.Spades, Suit.Hearts, Suit.Diamonds, Suit.Clubs };
|
||
|
||
public static List<Card> Create()
|
||
{
|
||
var deck = new List<Card>(52);
|
||
foreach (var suit in Suits)
|
||
for (int rank = 2; rank <= 14; rank++)
|
||
deck.Add(new Card(suit, rank));
|
||
return deck;
|
||
}
|
||
|
||
/// <summary>Fisher–Yates shuffle into a new list.</summary>
|
||
public static List<Card> Shuffle(IReadOnlyList<Card> input, Random rng)
|
||
{
|
||
var arr = input.ToList();
|
||
for (int i = arr.Count - 1; i > 0; i--)
|
||
{
|
||
int j = rng.Next(i + 1);
|
||
(arr[i], arr[j]) = (arr[j], arr[i]);
|
||
}
|
||
return arr;
|
||
}
|
||
|
||
public static List<Card> SortHand(IEnumerable<Card> hand)
|
||
{
|
||
static int Order(Suit s) => s switch
|
||
{
|
||
Suit.Spades => 0,
|
||
Suit.Hearts => 1,
|
||
Suit.Clubs => 2,
|
||
Suit.Diamonds => 3,
|
||
_ => 4,
|
||
};
|
||
return hand.OrderBy(c => Order(c.Suit)).ThenByDescending(c => c.Rank).ToList();
|
||
}
|
||
}
|