void Initialize() { DateTime startTime = DateTime.Now; _at = ActionTree.Read <ActionTree>(ActionTreeFile); if (IsVerbose) { Console.WriteLine("Action tree: {0}", _at.Version.ToString()); } _init = new InitData(this); _playersCount = _at.PlayersCount; _epsilonLog = new List <EpsilonLogEntry>(); _snapshotSwitcher = new SnapshotSwitcher(OutputPath, GetSnapshotHeaderFileName(), SnapshotsCount); _curSnapshotInfo = new SnapshotInfo(_snapshotSwitcher.CurrentSnapshotPath, _playersCount); IterationCounts = new int[_playersCount]; LastBrValues = new double[_playersCount]; _ptExt = new Node[_playersCount][]; _rng = new System.Random(RngSeed); _mcDealer = new McDealer(GameDef, _rng); _hands = new int[_playersCount][].Fill(i => new int[_mcDealer.HandSize]); _handSizes = GameDef.GetHandSizes(); _oppGv = new double[_at.NodesCount]; bool isNewSnapshot = !_snapshotSwitcher.IsSnapshotAvailable; if (isNewSnapshot) { CreateNewSnapshot(); } //LoadSnapshot(); CreatePlayerTrees(); for (int p = 0; p < _playersCount; ++p) { if (TraceDir != null) { Vis.Show(this, p, GetTraceFileName(p, "tree", "init-pt", "gv")); } } if (TraceDir != null) { VisChanceTree.Show(_init.PlayerCt, GetTraceFileName(0, "pct", "", "gv")); } PrintInitDone(); // Clean-up _init = null; double time = (DateTime.Now - startTime).TotalSeconds; if (IsVerbose) { Console.WriteLine("Initialization done in {0:0.0} s", time); } }
/// <summary> /// Generates some random hands and verifies the result. /// </summary> /// <param name="gd"></param> /// <param name="repCount"></param> void Verify(GameDefinition gd, int playersCount, int repCount) { int seed = (int)DateTime.Now.Ticks; Console.WriteLine("Game: {0}, players: {1}, RNG seed: {2}", gd.Name, playersCount, seed); McDealer mcDealer = new McDealer(gd, seed); List <bool> isSharedDeal = new List <bool>(); int totalCardsCount = 0; for (int r = 0; r < gd.RoundsCount; ++r) { for (int i = 0; i < gd.PublicCardsCount[r] + gd.PrivateCardsCount[r]; ++i) { isSharedDeal.Add(false); } totalCardsCount += (gd.PublicCardsCount[r] + gd.PrivateCardsCount[r]) * playersCount; for (int i = 0; i < gd.SharedCardsCount[r]; ++i) { isSharedDeal.Add(true); } totalCardsCount += gd.SharedCardsCount[r]; } Assert.AreEqual(isSharedDeal.Count, mcDealer.HandSize); int [][] hands = new int[playersCount][].Fill(i => new int[isSharedDeal.Count]); for (int rep = 0; rep < repCount; ++rep) { mcDealer.NextDeal(hands); HashSet <int> distinctCards = new HashSet <int>(); for (int d = 0; d < isSharedDeal.Count; ++d) { if (isSharedDeal[d]) { // Make sure all players has the same card. for (int p = 0; p < playersCount; ++p) { Assert.AreEqual(hands[0][d], hands[p][d]); } Assert.IsFalse(distinctCards.Contains(hands[0][d])); distinctCards.Add(hands[0][d]); } else { // Add cards of each player to the set. If multiple players have // this card or it was dealt before, we will get an error. for (int p = 0; p < playersCount; ++p) { Assert.IsFalse(distinctCards.Contains(hands[p][d])); distinctCards.Add(hands[p][d]); } } } Assert.AreEqual(totalCardsCount, distinctCards.Count); } }
void Benchmark(GameDefinition gd, int playersCount, int repCount) { int seed = (int)DateTime.Now.Ticks; McDealer mcDealer = new McDealer(gd, seed); int[][] hands = new int[playersCount][].Fill(i => new int[mcDealer.HandSize]); int checksum = 0; DateTime startTime = DateTime.Now; for (int rep = 0; rep < repCount; ++rep) { mcDealer.NextDeal(hands); checksum += hands[0][0]; } double time = (DateTime.Now - startTime).TotalSeconds; Console.WriteLine("Game: {0}, players: {1}, repetitions: {2:0,0}, time: {3:0.000} s, {4:0,0} deals/s", gd.Name, playersCount, repCount, time, repCount / time); }
/// <summary> /// Generate an internal chance tree by MC sampling. /// </summary> /// <param name="chanceAbstractions">An array of chance abstractions</param> /// <param name="areAbstractionsEqual">If the absractions are equal, /// one MC sample will update multiple nodes of the chance tree.</param> /// <param name="samplesCount">Number of samples. If equal absractions are used, /// less MC samples will be actually done to reach the specified numbers of updates.</param> /// <param name="rngSeed">RNG seed.</param> /// <param name="feedback">User feedback callback.</param> /// <returns></returns> public static Tree Generate(GameDefinition gd, IChanceAbstraction[] chanceAbstractions, bool areAbstractionsEqual, long samplesCount, int rngSeed, FeedbackDelegate feedback) { if (chanceAbstractions.Length != 2) { throw new ArgumentOutOfRangeException("Only heads up games are supported now"); } McDealer mcDealer = new McDealer(gd, rngSeed); int [][] hands = new int[chanceAbstractions.Length][].Fill(i => new int[mcDealer.HandSize]); int[] handSizes = gd.GetHandSizes(); Tree tree = new Tree { PlayersCount = chanceAbstractions.Length, RoundsCount = gd.RoundsCount, SourceInfo = GetSourceInfo(gd, chanceAbstractions) }; Node root = tree.Root; byte[] abstrCards = new byte[gd.RoundsCount * chanceAbstractions.Length]; uint[] ranks = new uint[chanceAbstractions.Length]; Int64 samplesDone; int updateCount = areAbstractionsEqual ? 2 : 1; for (samplesDone = 0; samplesDone < samplesCount; samplesDone += updateCount) { if (feedback != null && (samplesDone % FEEDBACK_PERIOD == 0)) { if (!feedback(samplesDone)) { break; } } mcDealer.NextDeal(hands); gd.GameRules.Showdown(gd, hands, ranks); int c = 0; for (int r = 0; r < gd.RoundsCount; ++r) { for (int p = 0; p < chanceAbstractions.Length; ++p) { int abstrCard = chanceAbstractions[p].GetAbstractCard(hands[p], handSizes[r]); if (abstrCard < byte.MinValue || abstrCard > byte.MaxValue) { throw new ApplicationException(string.Format("Abstract card {0} out of byte range", abstrCard)); } abstrCards[c++] = (byte)abstrCard; } } for (int u = 0; ;) { LeafT[] leaves = tree.GetLeavesByCards(abstrCards); int lastCard = abstrCards[abstrCards.Length - 1]; leaves[lastCard].Update(ranks); if (++u == updateCount) { break; } // If the abstractions are equal, we can update another node // by permuting cards and results // Note: implemented for 2 players only for (c = 0; c < abstrCards.Length; c += 2) { ShortSequence.Swap(ref abstrCards[c], ref abstrCards[c + 1]); } ShortSequence.Swap(ref ranks[0], ref ranks[1]); } } tree.SamplesCount = (UInt64)samplesDone; tree.UpdateDescription(); return(tree); }