void PrepareOpp_OnNodeBegin(StrategyTree tree, PrepareOppContext[] stack, int depth) { PrepareOppContext context = stack[depth]; Int64 n = context.NodeIdx; // Add v-var here once for all cases. context.VarV = _variables.Add("v", (int)n); // Initialize fields for post-oreder procecessing, etc. context.EqConstr = null; context.ChildVarsR.Clear(); context.ChildVarsV.Clear(); //context.LeConstr = null; if (depth == PLAYERS_COUNT) { // Skip blinds context.ActionTreeIdx = PLAYERS_COUNT; context.State = new StrategicState(PLAYERS_COUNT); for (int a = 1; a <= PLAYERS_COUNT; ++a) { context.State = context.State.GetNextState(ActionTree.Nodes[a]); } } else { context.ActionTreeIdx = stack[depth - 1].ActionTreeIdx; context.Round = stack[depth - 1].Round; context.OppChanceIdx = stack[depth - 1].OppChanceIdx; if (tree.Nodes[n].IsDealerAction) { context.Round++; context.OppChanceIdx += CalculateChanceOffset(context.Round, _oppPosition) * tree.Nodes[n].Card; context.State = stack[depth - 1].State; } else { context.ActionTreeIdx = FindActionTreeNodeIdx(tree, n, context.ActionTreeIdx, stack[depth - 1].ChildrenCount - 1); context.State = stack[depth - 1].State.GetNextState(ActionTree.Nodes[context.ActionTreeIdx]); } } }
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); } }