Beispiel #1
0
        void EnumeratePlayersChanceIndex(Int64 actionTreeNodeIdx, int[] chanceNodes, StrategicState state, Constraint constr)
        {
            for (int i = 0; i < _heroVarsInLeaves[actionTreeNodeIdx].Length; ++i)
            {
                int chanceNodeIdx = chanceNodes[i];
                if (chanceNodeIdx == 0)
                {
                    // There is no existing cards for this index (a "hole")
                    continue;
                }
                int varH = _heroVarsInLeaves[actionTreeNodeIdx][i];

                double[] potShares     = new double[PLAYERS_COUNT];
                UInt16   activePlayers = ActionTree.Nodes[actionTreeNodeIdx].ActivePlayers;
                //Debug.Assert(round == _roundsCount - 1 || CountBits.Count(activePlayers) == 1, "Must be either chance leaf or single active player");

                ChanceTree.Nodes[chanceNodeIdx].GetPotShare(activePlayers, potShares);
                double chanceProbab = ChanceTree.Nodes[chanceNodeIdx].Probab;
                double result       = state.Pot * potShares[HeroPosition] - state.InPot[HeroPosition];
                double coeff        = chanceProbab * result;
                if (varH != -1)
                {
                    constr.AddVariable(varH, coeff);
                }
                else
                {
                    // Special case - opponent folded before the hero has acted (e.g. small blind folds at the very beginning).
                    // In this case there is no hero variable, and the v-variable is constant.
                    // Constaint has the form: v3 = k3 + k13, or -v3 = -k3 - k13
                    constr.RightHandSide -= coeff;
                }
            }
        }
Beispiel #2
0
        void PrepareHero_OnNodeBegin(StrategyTree tree, PrepareHeroVarsContext[] stack, int depth)
        {
            PrepareHeroVarsContext context = stack[depth];
            Int64 n = context.NodeIdx;

            if (depth == PLAYERS_COUNT)
            {
                // Skip blinds
                context.ActionTreeIdx = PLAYERS_COUNT;
            }
            else
            {
                context.ActionTreeIdx = stack[depth - 1].ActionTreeIdx;
                context.Round         = stack[depth - 1].Round;
                context.ChanceIdx     = stack[depth - 1].ChanceIdx;
                context.VarH          = stack[depth - 1].VarH;
                context.EqConstr      = null;

                if (tree.Nodes[n].IsDealerAction)
                {
                    context.Round++;
                    context.ChanceIdx += CalculateChanceOffset(context.Round, HeroPosition) * tree.Nodes[n].Card;
                }
                else
                {
                    context.ActionTreeIdx = FindActionTreeNodeIdx(tree, n, context.ActionTreeIdx, stack[depth - 1].ChildrenCount - 1);
                    if (tree.Nodes[n].IsPlayerAction(HeroPosition))
                    {
                        Constraint constr = stack[depth - 1].EqConstr;
                        if (stack[depth - 1].EqConstr == null)
                        {
                            // Create new constraint
                            constr = new Constraint();
                            stack[depth - 1].EqConstr = constr;
                            _constraintsEQ.Add(constr);
                            if (context.VarH == -1)
                            {
                                // This is the very first move of the hero in this tree branch,
                                // add constraint Sum(h_child) = 1
                                constr.RightHandSide = 1;
                            }
                            else
                            {
                                // Add constraint h_prev_move = Sum(h_child)
                                constr.RightHandSide = 0;
                                constr.AddVariable(stack[depth - 1].VarH, -1);
                            }
                        }
                        context.VarH = _variables.Add("h", (int)n);
                        constr.AddVariable(context.VarH, 1);
                    }

                    if (_actionTreeIndex.GetChildrenCount(context.ActionTreeIdx) == 0)
                    {
                        // A leaf.
                        _heroVarsInLeaves[context.ActionTreeIdx][context.ChanceIdx] = context.VarH;
                    }
                }
            }
        }
Beispiel #3
0
        protected bool Step2_OnNodeBegin(TreeNode tree, TreeNode node, List <Context> stack, int depth)
        {
            Context context = stack[depth];

            _heroNodeCount++;

            if (node.State.HasPlayerActed(HeroPosition))
            {
                context.HasHeroActedAtLeastOnce = true;
            }
            else if (depth > 0)
            {
                context.HasHeroActedAtLeastOnce = stack[depth - 1].HasHeroActedAtLeastOnce;
                node.Var_h = stack[depth - 1].Node.Var_h;
            }

            if (node.State.IsPlayerActing(HeroPosition))
            {
                Constraint constr = new Constraint();
                if (node.Var_h == -1)
                {
                    // This is the very first move of the hero in this tree branch,
                    // add constraint Sum(h_child) = 1
                    constr.RightHandSide = 1;
                    for (int c = 0; c < node.Children.Count; ++c)
                    {
                        node.Children[c].Var_h             = Vars.Add("h", node.Children[c].Id);
                        VarHToCard[node.Children[c].Var_h] = node.State.Players[HeroPosition].PrivateCards;
                        constr.AddVariable(node.Children[c].Var_h, 1);
                    }
                }
                else
                {
                    // Add constraint h_prev_move = Sum(h_child)
                    constr.RightHandSide = 0;
                    constr.AddVariable(node.Var_h, -1);
                    for (int c = 0; c < node.Children.Count; ++c)
                    {
                        node.Children[c].Var_h             = Vars.Add("h", node.Children[c].Id);
                        VarHToCard[node.Children[c].Var_h] = node.State.Players[HeroPosition].PrivateCards;
                        constr.AddVariable(node.Children[c].Var_h, 1);
                    }
                }
                _constraintsEQ.Add(constr);
            }
            return(true);
        }
Beispiel #4
0
        protected void Step5OnNodeEnd(TreeNode tree, TreeNode node, List <Context> stack, int depth)
        {
            Context context = stack[depth];

            if (node.Children.Count == 0)
            {
                // Terminal nodes, add new variables and constraints:
                // v6 = res6 * t14 + res15 * t23
                node.Var_v = Vars.Add("v", node.Id);
                Constraint constr = new Constraint();
                constr.RightHandSide = 0;
                for (int i = 0; i < node.TerminalCoeffs_h.Count; i++)
                {
                    constr.AddVariable(node.TerminalVars_h[i], node.TerminalCoeffs_h[i]);
                }
                constr.AddVariable(node.Var_v, -1);
                _constraintsEQ.Add(constr);
            }
            else if (node.State.IsPlayerActing(1 - HeroPosition))
            {
                //v2 = r3 + r8
                //r3 + r8 <= v3
                //r3 + r8 <= v8

                // Add new variables: v_i and r_*
                node.Var_v = Vars.Add("v", node.Id);
                List <int> var_r = new List <int>();
                for (int i = 0; i < node.Children.Count; i++)
                {
                    int rIdx = Vars.Add("r", node.Children[i].Id);
                    var_r.Add(rIdx);
                }

                // Add 1 eq constraint
                Constraint constr = new Constraint();
                constr.RightHandSide = 0;
                for (int i = 0; i < var_r.Count; ++i)
                {
                    constr.AddVariable(var_r[i], 1);
                }
                constr.AddVariable(node.Var_v, -1);
                _constraintsEQ.Add(constr);


                // For each child add a le constraint
                for (int i = 0; i < node.Children.Count; i++)
                {
                    Constraint constrLE = new Constraint();
                    constrLE.RightHandSide = 0;
                    for (int j = 0; j < var_r.Count; ++j)
                    {
                        constrLE.AddVariable(var_r[j], 1);
                    }
                    constrLE.AddVariable(node.Children[i].Var_v, -1);
                    _constraintsLE.Add(constrLE);
                }
            }
            else
            {
                // Sum all the children:
                // v3 = v4 + v5
                node.Var_v = Vars.Add("v", node.Id);
                Constraint constr = new Constraint();
                constr.RightHandSide = 0;
                for (int i = 0; i < node.Children.Count; i++)
                {
                    constr.AddVariable(node.Children[i].Var_v, 1);
                }
                constr.AddVariable(node.Var_v, -1);
                _constraintsEQ.Add(constr);
            }
        }
Beispiel #5
0
        void PrepareOpp_OnNodeEnd(StrategyTree tree, PrepareOppContext[] stack, int depth)
        {
            PrepareOppContext context = stack[depth];
            Int64             n       = context.NodeIdx;

            if (_actionTreeIndex.GetChildrenCount(context.ActionTreeIdx) == 0)
            {
                // A leaf, add new variables and constraints:
                // v6 = k16 * h16 + k26 * h26
                Constraint constr = new Constraint();
                constr.RightHandSide = 0;
                constr.AddVariable(context.VarV, -1);
                _constraintsEQ.Add(constr);
                int[] chanceNodes = _chanceTreeNodes[context.Round][context.OppChanceIdx];
                EnumeratePlayersChanceIndex(context.ActionTreeIdx, chanceNodes, context.State, constr);
            }

            if (n == PLAYERS_COUNT)
            {
                return;
            }

            // Update parent.

            Int64             pn            = stack[depth - 1].NodeIdx;
            PrepareOppContext parentContext = stack[depth - 1];

            Constraint constrEq = parentContext.EqConstr;

            if (constrEq == null)
            {
                // Create new eq constraint in the parent.
                constrEq = new Constraint();
                parentContext.EqConstr = constrEq;
                constrEq.RightHandSide = 0;
                constrEq.AddVariable(parentContext.VarV, -1);
                _constraintsEQ.Add(constrEq);
            }

            if (tree.Nodes[n].IsPlayerAction(_oppPosition))
            {
                // v2 = r3 + r8
                // Add r-variable for each node where opponent have acted.
                int varR = _variables.Add("r", (int)n);
                constrEq.AddVariable(varR, 1);
                parentContext.ChildVarsR.Add(varR);
                parentContext.ChildVarsV.Add(context.VarV);
            }
            else
            {
                Debug.Assert(context.ChildVarsV.Count == context.ChildVarsR.Count);
                // If it is the node where the opponent is acting,
                // add le-constraints.
                // r3 + r8 <= v3
                // r3 + r8 <= v8
                foreach (int varV in context.ChildVarsV)
                {
                    Constraint constrLe = new Constraint();
                    _constraintsLE.Add(constrLe);
                    constrLe.RightHandSide = 0;
                    constrLe.AddVariable(varV, -1);
                    foreach (int varR in context.ChildVarsR)
                    {
                        constrLe.AddVariable(varR, 1);
                    }
                }

                // Sum all the children in the parent:
                // v3 = v4 + v5
                constrEq.AddVariable(context.VarV, 1);
            }
        }