void CalculateValues_OnNodeBegin(StrategyTree tree, CalculateValuesContext[] stack, int depth) { CalculateValuesContext context = stack[depth]; Int64 n = context.NodeIdx; // We'll use the probability to store game values temporarily. // Initialize with an unique value works both for summing and maximization. tree.Nodes[n].Probab = double.MinValue; if (depth == 0) { context.ActionTreeIdx = 0; context.State = new StrategicState(_playersCount); } else { context.ActionTreeIdx = stack[depth - 1].ActionTreeIdx; context.Round = stack[depth - 1].Round; context.HeroChanceIdx = stack[depth - 1].HeroChanceIdx; if (tree.Nodes[n].IsDealerAction) { context.Round++; context.HeroChanceIdx += CalculateChanceOffset(context.Round, HeroPosition) * 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 CalculateValues_OnNodeEnd(StrategyTree tree, CalculateValuesContext[] stack, int depth) { CalculateValuesContext context = stack[depth]; Int64 n = context.NodeIdx; if (_actionTreeIndex.GetChildrenCount(context.ActionTreeIdx) == 0) { // A leaf. int[] chanceNodes = _chanceTreeNodes[context.Round][context.HeroChanceIdx]; double nodeValue = 0; EnumeratePlayersChanceIndex(context.Round, 0, context.ActionTreeIdx, chanceNodes, 0, 1, 1.0, context.State, ref nodeValue); tree.Nodes[n].Probab = nodeValue; } if (PrepareVis) { _visGameValues[n] = tree.Nodes[n].Probab; } if (n == 0) { return; } // Update parent. Int64 pn = stack[depth - 1].NodeIdx; if (tree.Nodes[n].IsPlayerAction(HeroPosition)) { tree.Nodes[pn].Probab = Math.Max(tree.Nodes[pn].Probab, tree.Nodes[n].Probab); } else { // Sum values if (tree.Nodes[pn].Probab == double.MinValue) { tree.Nodes[pn].Probab = 0; } tree.Nodes[pn].Probab += tree.Nodes[n].Probab; } }