Files
HokmPlay/server/tools/Hokm.Sim/Program.cs
T

53 lines
1.7 KiB
C#
Raw Normal View History

using Hokm.Engine;
// All-AI simulation to validate the C# engine port (mirrors scripts/sim.ts).
var rng = new Random(12345);
int N = 300;
int totalRounds = 0;
for (int i = 0; i < N; i++)
{
var (rounds, tricks) = PlayMatch(rng);
totalRounds += rounds;
if (tricks <= 0) throw new Exception("no tricks played");
}
Console.WriteLine($"OK: {N} matches completed. avg rounds/match = {(double)totalRounds / N:0.0}");
static (int rounds, int tricks) PlayMatch(Random rng)
{
var g = Rules.CreateInitial(new[] { "P0", "P1", "P2", "P3" }, 7);
Rules.SelectHakem(g, rng);
Rules.DealForTrump(g, rng);
int rounds = 0, tricks = 0, guard = 0;
while (g.Phase != Phase.MatchOver)
{
if (++guard > 200000) throw new Exception("loop guard tripped");
switch (g.Phase)
{
case Phase.ChoosingTrump:
Rules.ChooseTrump(g, Ai.ChooseTrump(g.Players[g.Hakem!.Value].Hand));
break;
case Phase.Playing:
int seat = g.Turn!.Value;
Rules.PlayCard(g, seat, Ai.ChooseCard(g, seat));
break;
case Phase.TrickComplete:
tricks++;
if (g.CurrentTrick.Count != 4) throw new Exception("trick not full");
Rules.AdvanceAfterTrick(g, 2);
break;
case Phase.RoundOver:
rounds++;
if (g.RoundTricks[0] + g.RoundTricks[1] > 13) throw new Exception("too many tricks");
Rules.StartNextRound(g, rng);
break;
default:
throw new Exception("unexpected phase: " + g.Phase);
}
}
return (rounds, tricks);
}