public void Test_Convert()
        {
            GameDefinition gd = XmlSerializerExt.Deserialize <GameDefinition>(
                Props.Global.Expand("${bds.DataDir}ai.pkr.metastrategy/leduc-he.gamedef.xml"));

            string testDir = UTHelper.GetTestResourceDir(Assembly.GetExecutingAssembly());

            ChanceTree ct1 = CreateChanceTreeByGameDef.Create(gd);
            // DumpChanceTree.ToTxt(ct1, Console.Out);

            MemoryStream ms = new MemoryStream();

            using (TextWriter tw = new StreamWriter(ms))
            {
                DumpChanceTree.ToTxt(ct1, tw);
            }
            byte[] buf = ms.ToArray();
            ms = new MemoryStream(buf);
            ChanceTree ct2;

            using (TextReader tr = new StreamReader(ms))
            {
                ct2 = DumpChanceTree.FromTxt(tr);
            }
            Assert.AreEqual(ct1.Version, ct2.Version);
            Assert.AreEqual(ct1.NodesCount, ct2.NodesCount);
            int roundsCount = ct1.CalculateRoundsCount();

            double[] potShare1 = new double[ct1.PlayersCount];
            double[] potShare2 = new double[ct1.PlayersCount];
            for (Int64 n = 0; n < ct2.NodesCount; ++n)
            {
                Assert.AreEqual(ct1.GetDepth(n), ct2.GetDepth(n));
                Assert.AreEqual(ct1.Nodes[n].Position, ct2.Nodes[n].Position);
                Assert.AreEqual(ct1.Nodes[n].Card, ct2.Nodes[n].Card);
                Assert.AreEqual(ct1.Nodes[n].Probab, ct2.Nodes[n].Probab);
                if (ct1.GetDepth(n) == ct1.PlayersCount * roundsCount)
                {
                    UInt16 [] activePlayerMasks = ActivePlayers.Get(ct1.PlayersCount, 2, ct1.PlayersCount);
                    foreach (UInt16 ap in activePlayerMasks)
                    {
                        ct1.Nodes[n].GetPotShare(ap, potShare1);
                        ct2.Nodes[n].GetPotShare(ap, potShare2);
                        Assert.AreEqual(potShare1, potShare2);
                    }
                }
            }
        }
示例#2
0
        private void PrepareHero()
        {
            _maxCard          = new int[PLAYERS_COUNT][];
            _chanceIndexSizes = new int[PLAYERS_COUNT][];
            _heroVarsInLeaves = new int[ActionTree.NodesCount][];

            _roundsCount = ChanceTree.CalculateRoundsCount();
            for (int p = 0; p < PLAYERS_COUNT; ++p)
            {
                _maxCard[p]          = new int[_roundsCount].Fill(int.MinValue);
                _chanceIndexSizes[p] = new int[_roundsCount].Fill(int.MinValue);
            }

            for (Int64 n = 1; n < ChanceTree.NodesCount; ++n)
            {
                int round = (ChanceTree.GetDepth(n) - 1) / PLAYERS_COUNT;
                if (_maxCard[ChanceTree.Nodes[n].Position][round] < ChanceTree.Nodes[n].Card)
                {
                    _maxCard[ChanceTree.Nodes[n].Position][round] = ChanceTree.Nodes[n].Card;
                }
            }

            for (int p = 0; p < PLAYERS_COUNT; ++p)
            {
                _chanceIndexSizes[p][0] = _maxCard[p][0] + 1;
                for (int r = 1; r < _roundsCount; ++r)
                {
                    _chanceIndexSizes[p][r] = _chanceIndexSizes[p][r - 1] * (_maxCard[p][r] + 1);
                }
            }

            _actionTreeIndex = new UFTreeChildrenIndex(ActionTree);

            for (Int64 n = 1; n < ActionTree.NodesCount; ++n)
            {
                if (_actionTreeIndex.GetChildrenCount(n) == 0)
                {
                    // This is a leaf
                    int round = ActionTree.Nodes[n].Round;
                    _heroVarsInLeaves[n] = new int[_chanceIndexSizes[HeroPosition][round]].Fill(-1);
                }
            }

            // Create hero variables
            WalkUFTreePP <StrategyTree, PrepareHeroVarsContext> wt = new WalkUFTreePP <StrategyTree, PrepareHeroVarsContext>();

            wt.OnNodeBegin = PrepareHero_OnNodeBegin;
            wt.Walk(Strategy, PLAYERS_COUNT);
        }
示例#3
0
        public static void ToTxt(ChanceTree t, TextWriter w)
        {
            int roundsCount = t.CalculateRoundsCount();

            if (t.PlayersCount != 2)
            {
                throw new ApplicationException("Only 2 players are supported");
            }
            w.WriteLine("SeralizationFormat {0}", SERIALIZATION_FORMAT);
            XmlWriterSettings s = new XmlWriterSettings {
                Indent = false, NewLineChars = ""
            };

            w.Write("Version ");
            XmlSerializerExt.Serialize(t.Version, w, s);
            w.WriteLine();
            w.WriteLine("NodesCount {0}", t.NodesCount);
            w.WriteLine("RoundsCount {0}", roundsCount);
            double [] potShare = new double[t.PlayersCount];
            for (Int64 n = 0; n < t.NodesCount; ++n)
            {
                w.WriteLine("Id {0}", n);
                byte depth = t.GetDepth(n);
                w.WriteLine("D {0}", depth);
                w.WriteLine("P {0}", t.Nodes[n].Position);
                w.WriteLine("C {0}", t.Nodes[n].Card);
                w.WriteLine("Pr {0}", TextDumpHelper.DoubleToBinString(t.Nodes[n].Probab));
                if (depth == roundsCount * t.PlayersCount)
                {
                    UInt16 [] activePlayerMasks = ActivePlayers.Get(t.PlayersCount, 2, t.PlayersCount);
                    foreach (UInt16 ap in activePlayerMasks)
                    {
                        t.Nodes[n].GetPotShare(ap, potShare);
                        w.Write("Ps {0:X}", ap);
                        foreach (double ps in potShare)
                        {
                            w.Write(" {0}", TextDumpHelper.DoubleToBinString(ps));
                        }
                        w.WriteLine();
                    }
                }
            }
        }
        public void Test_Kuhn()
        {
            GameDefinition gd = XmlSerializerExt.Deserialize <GameDefinition>(
                Props.Global.Expand("${bds.DataDir}ai.pkr.metastrategy/kuhn.gamedef.xml"));

            IChanceAbstraction[] abstractions = new IChanceAbstraction [] { new KuhnChanceAbstraction(), new KuhnChanceAbstraction() };

            ChanceTree ct  = CreateChanceTreeByGameDef.Create(gd);
            ChanceTree act = CreateChanceTreeByAbstraction.CreateS(gd, abstractions);

            VerifyChanceTree.VerifyS(act);

            VisChanceTree.Show(act, Path.Combine(_outDir, gd.Name + "-abct.gv"));

            UInt16[] activePlayersOne = ActivePlayers.Get(gd.MinPlayers, 1, 1);
            UInt16[] activePlayersAll = ActivePlayers.Get(gd.MinPlayers, 1, gd.MinPlayers);
            int      maxDepth         = gd.RoundsCount * gd.MinPlayers;

            Assert.AreEqual(act.PlayersCount, gd.MinPlayers);
            Assert.AreEqual(ct.NodesCount, act.NodesCount);
            double[] expPotShares = new double[gd.MinPlayers];
            double[] actPotShares = new double[gd.MinPlayers];
            for (int i = 0; i < ct.NodesCount; ++i)
            {
                Assert.AreEqual(ct.Nodes[i].Position, act.Nodes[i].Position);
                Assert.AreEqual(ct.Nodes[i].Card, act.Nodes[i].Card); // Kuhn abstraction has the same card
                Assert.AreEqual(ct.Nodes[i].Probab, act.Nodes[i].Probab);
                if (i == 0)
                {
                    continue;
                }
                UInt16[] activePlayers = ct.GetDepth(i) == maxDepth ? activePlayersAll : activePlayersOne;
                foreach (UInt16 ap in activePlayers)
                {
                    ct.Nodes[i].GetPotShare(ap, expPotShares);
                    act.Nodes[i].GetPotShare(ap, actPotShares);
                    Assert.AreEqual(expPotShares, actPotShares, String.Format("Node: {0}, ap: {1}", i, ap));
                }
            }
        }
示例#5
0
        private void Prepare()
        {
            _playersCount   = Strategies.Length;
            _maxCard        = new int[_playersCount][];
            _spArrayLengths = new int[_playersCount][];
            _spArrays       = new double[_playersCount][][].Fill(i => new double[ActionTree.NodesCount][]);
            if (PrepareVis)
            {
                _visLeaveValues = new double[_playersCount][][].Fill(i => new double[ActionTree.NodesCount][]);
            }
            _gameValues = new double[_playersCount];

            _roundsCount = ChanceTree.CalculateRoundsCount();
            for (int p = 0; p < _playersCount; ++p)
            {
                _maxCard[p]        = new int[_roundsCount].Fill(int.MinValue);
                _spArrayLengths[p] = new int[_roundsCount].Fill(int.MinValue);
            }

            for (Int64 n = 1; n < ChanceTree.NodesCount; ++n)
            {
                int round = (ChanceTree.GetDepth(n) - 1) / _playersCount;
                if (_maxCard[ChanceTree.Nodes[n].Position][round] < ChanceTree.Nodes[n].Card)
                {
                    _maxCard[ChanceTree.Nodes[n].Position][round] = ChanceTree.Nodes[n].Card;
                }
            }

            for (int p = 0; p < _playersCount; ++p)
            {
                _spArrayLengths[p][0] = _maxCard[p][0] + 1;
                for (int r = 1; r < _roundsCount; ++r)
                {
                    _spArrayLengths[p][r] = _spArrayLengths[p][r - 1] * (_maxCard[p][r] + 1);
                }
            }

            _actionTreeIndex = new UFTreeChildrenIndex(ActionTree);

            for (Int64 n = 1; n < ActionTree.NodesCount; ++n)
            {
                if (_actionTreeIndex.GetChildrenCount(n) == 0)
                {
                    // This is a leaf
                    int round = ActionTree.Nodes[n].Round;
                    for (int p = 0; p < _playersCount; ++p)
                    {
                        _spArrays[p][n] = new double[_spArrayLengths[p][round]];
                        if (PrepareVis)
                        {
                            _visLeaveValues[p][n] = new double[_spArrayLengths[p][round]];
                        }
                    }
                }
            }

            for (_curPlayer = 0; _curPlayer < _playersCount; ++_curPlayer)
            {
                WalkUFTreePP <StrategyTree, PrepareContext> wt = new WalkUFTreePP <StrategyTree, PrepareContext>();
                wt.OnNodeBegin = Prepare_OnNodeBegin;
                wt.Walk(Strategies[_curPlayer]);
            }
        }
        private void OnNodeBegin(ChanceTree tree, AnalyzeContext[] stack, int depth)
        {
            AnalyzeContext context = stack[depth];
            Int64          n       = context.NodeIdx;
            int            card    = tree.Nodes[n].Card;

            if (depth > 0)
            {
                int round = (depth - 1) / _playersCount;
                int pos   = tree.Nodes[n].Position;
                if (_seenCards[round][pos].Length <= card)
                {
                    Array.Resize(ref _seenCards[round][pos], card + 1);
                }
                _seenCards[round][pos][card] = true;
            }

            bool isLeaf = tree.GetDepth(n) == _maxDepth;

            if (!isLeaf)
            {
                return;
            }

            LeavesCount++;
            bool isZeroNode = false;

            double probab = tree.Nodes[n].Probab;

            if (probab == 0)
            {
                ZeroChanceLeavesCount++;
                isZeroNode = true;
            }

            UInt16[] activePlayers = ActivePlayers.Get(_playersCount, 2, _playersCount);

            double[] potShares     = new double[_playersCount];
            double   totalPotShare = 0;

            foreach (UInt16 ap in activePlayers)
            {
                tree.Nodes[n].GetPotShare(ap, potShares);
                for (int p = 0; p < _playersCount; ++p)
                {
                    SumPotShares[p] += potShares[p];
                    totalPotShare   += potShares[p];
                }
            }

            if (probab > 0 && totalPotShare == 0)
            {
                ZeroPotSharesCount++;
                isZeroNode = true;
            }

            if (isZeroNode && _zeroNodesLog != null)
            {
                _zeroNodesLog.Write("Node: {0,10} probab: {1:0.0000}, total pot share: {2:0.0000} ",
                                    n, probab, totalPotShare);
                for (int i = 1; i <= depth; ++i)
                {
                    _zeroNodesLog.Write("{0} ", tree.Nodes[stack[i].NodeIdx].ToStrategicString(null));
                }
                _zeroNodesLog.WriteLine();
            }
        }
示例#7
0
        private void Prepare()
        {
            CreateHeroStrategy();

            _playersCount     = Strategies.Length;
            _maxCard          = new int[_playersCount][];
            _chanceIndexSizes = new int[_playersCount][];
            _strategicProbabs = new double[_playersCount][][].Fill(i => new double[ActionTree.NodesCount][]);
            if (PrepareVis)
            {
                _visGameValues = new double[Strategies[HeroPosition].NodesCount];
            }
            else
            {
                _visGameValues = null;
            }

            _roundsCount = ChanceTree.CalculateRoundsCount();
            for (int p = 0; p < _playersCount; ++p)
            {
                _maxCard[p]          = new int[_roundsCount].Fill(int.MinValue);
                _chanceIndexSizes[p] = new int[_roundsCount].Fill(int.MinValue);
            }

            for (Int64 n = 1; n < ChanceTree.NodesCount; ++n)
            {
                int round = (ChanceTree.GetDepth(n) - 1) / _playersCount;
                if (_maxCard[ChanceTree.Nodes[n].Position][round] < ChanceTree.Nodes[n].Card)
                {
                    _maxCard[ChanceTree.Nodes[n].Position][round] = ChanceTree.Nodes[n].Card;
                }
            }

            for (int p = 0; p < _playersCount; ++p)
            {
                _chanceIndexSizes[p][0] = _maxCard[p][0] + 1;
                for (int r = 1; r < _roundsCount; ++r)
                {
                    _chanceIndexSizes[p][r] = _chanceIndexSizes[p][r - 1] * (_maxCard[p][r] + 1);
                }
            }

            _actionTreeIndex = new UFTreeChildrenIndex(ActionTree);

            for (Int64 n = 1; n < ActionTree.NodesCount; ++n)
            {
                if (_actionTreeIndex.GetChildrenCount(n) == 0)
                {
                    // This is a leaf
                    int round = ActionTree.Nodes[n].Round;
                    for (int p = 0; p < _playersCount; ++p)
                    {
                        if (p != HeroPosition)
                        {
                            _strategicProbabs[p][n] = new double[_chanceIndexSizes[p][round]];
                        }
                    }
                }
            }

            // Fill strategic probability for each player except the hero.
            for (_curPlayer = 0; _curPlayer < _playersCount; ++_curPlayer)
            {
                if (_curPlayer == HeroPosition)
                {
                    continue;
                }
                WalkUFTreePP <StrategyTree, PrepareStrategicProbabsContext> wt = new WalkUFTreePP <StrategyTree, PrepareStrategicProbabsContext>();
                wt.OnNodeBegin = PrepareStrategicProbabs_OnNodeBegin;
                wt.Walk(Strategies[_curPlayer]);
            }

            _chanceTreeNodes = new int[_roundsCount][][];

            for (int r = 0; r < _roundsCount; ++r)
            {
                int oppChanceIndexSize = 1;
                for (int p = 0; p < _playersCount; ++p)
                {
                    if (p == HeroPosition)
                    {
                        continue;
                    }
                    oppChanceIndexSize *= _chanceIndexSizes[p][r];
                }
                int size = _chanceIndexSizes[HeroPosition][r];
                _chanceTreeNodes[r] = new int[size][];
                for (int i = 0; i < size; ++i)
                {
                    _chanceTreeNodes[r][i] = new int[oppChanceIndexSize];
                }
            }


            WalkUFTreePP <ChanceTree, PrepareChanceIndexContext> wt1 = new WalkUFTreePP <ChanceTree, PrepareChanceIndexContext>();

            wt1.OnNodeBegin = PrepareChanceIndex_OnNodeBegin;
            wt1.Walk(ChanceTree);
        }