private void GoDown(TNode node, TState state, int depth, TNode splittedFrom) { if (_cancellationToken.IsCancellationRequested) { return; } if (splittedFrom.IsFinalized) { return; } if (depth == 0) { if (node.IsEvaluated) { node.Update(node.TerminationResult); } else { node.Update(_evaluator.Evaluate(state)); } GoUp(node, depth, state); return; } if (node.Children == null) { _brancher.Branch(node, state); } if (node.Children.Length == 0) { node.Update(_evaluator.Evaluate(state)); GoUp(node, depth, state); return; } foreach (var child in node.Children) { if (child.TryLockNode()) { child.UpdateAlfaBeta(node); state = _stateTransitions.GoDown(state, child); GoDown(child, state, depth - 1, splittedFrom); break; } } }
public void Branch(GameNode node, BoardMinified practiceBoard) { // todo - remove list to speed up perfomance var children = new List <GameNode> { Capacity = 16 }; node.ExpectedFinalizedFlag = 0; practiceBoard = _rules.FastForwardAvailableMoves(practiceBoard); var activeSetPtr = practiceBoard.ActivePlayer ? practiceBoard.Player1Pieces : practiceBoard.Player2Pieces; var childBitIndex = 0; for (var i = 0; i < BoardMinified.BufferSize; i++) { var piece = (PieceMinified)(*(activeSetPtr + i)); if (piece.IsEmpty()) { break; } foreach (var move in piece.GetAvailableMoves()) { if (move.IsNotNull) { var child = new GameNode(!practiceBoard.ActivePlayer); child.Move = new HistoryItemMinified(new Cell(piece.X, piece.Y), move, practiceBoard.ActivePlayer); // todo - remove - duplicated information child.Parent = node; children.Add(child); child.ChildAddressBit = 1 << childBitIndex; node.ExpectedFinalizedFlag += child.ChildAddressBit; childBitIndex++; } else { break; } } } foreach (var child in children) { var copy = _stateTransitions.Copy(practiceBoard); var localState = _stateTransitions.GoDown(copy, child); child.TerminationResult = _evaluator.Evaluate(localState); child.IsEvaluated = true; } node.Children = children.ToArray(); InsertionSort(node.Children, node.IsMaxPlayer); }
public TMetric Search(TNode node, int depth, TMetric alfa, TMetric beta, TState state, CancellationToken ct) { ct.ThrowIfCancellationRequested(); if (node.Children == null && depth > 0) { _brancher.Branch(node, state); } if (depth == 0 || node.Children.Length == 0) { var result = _evaluator.Evaluate(state); node.Result = result; return(result); } if (node.IsMaxPlayer) { var maxVal = _minValue; foreach (var child in node.Children) { var childState = _stateTransitions.GoDown(state, child); var result = Search(child, depth - 1, alfa, beta, childState, ct); state = _stateTransitions.GoUp(childState, child); if (!_comparator.IsBigger(maxVal, result)) { maxVal = result; node.BestChild = child; } if (!_comparator.IsBigger(beta, result)) { break; } alfa = _comparator.IsBigger(result, alfa) ? result : alfa; } // todo - refactor - remove extra variables node.Result = maxVal; return(maxVal); } var minVal = _maxValue; foreach (var child in node.Children) { var childState = _stateTransitions.GoDown(state, child); var result = Search(child, depth - 1, alfa, beta, childState, ct); state = _stateTransitions.GoUp(childState, child); if (!_comparator.IsBigger(result, minVal)) { minVal = result; node.BestChild = child; } if (!_comparator.IsBigger(result, alfa)) { break; } beta = _comparator.IsBigger(beta, result) ? result : beta; } // todo - refactor - remove extra variables node.Result = minVal; return(minVal); }