public double search(int depth, double alpha, double beta, Stopwatch sw, Dictionary <ulong, MaxNode> maxNodsCache, Dictionary <ulong, MinNode> minNodesCache) { if (mField == null) { if (sw.ElapsedMilliseconds > 200) { return(-1.0); } mField = new MaxMinBitField(mParent.getField()); var result = mField.updateByMyMove(mLastMove); mValue = result[0]; mProb = result[1]; } if (depth >= 4) { ulong hash = mField.TransPositionHash(); MinNode node = null; if (minNodesCache.TryGetValue(hash, out node)) { mScore = node.getScore(); return(mScore); } else { minNodesCache.Add(hash, this); } } if (mProb == 1.0) { mScore = mValue; return(mValue); } if (depth <= 0) { mScore = mProb * mValue + (1.0 - mProb) * MaxMinVotingPlayer.Score(mField); return(mScore); } if (mChildList == null) { var moveList = MaxMinBitField.CreateMoves(mField, mField.getNextPlayerId()); mChildList = new List <MaxNode>(moveList.Count); foreach (Move m in moveList) { mChildList.Add(new MaxNode(m, this)); } } else { // 昇順 mChildList.Sort((MaxNode n0, MaxNode n1) => { return(n0.getScore() > n1.getScore() ? 1 : n0.getScore() < n1.getScore() ? -1 : 0); }); } mScore = Double.PositiveInfinity; foreach (MaxNode node in mChildList) { double s = mProb * mValue; if (s >= mScore) { continue; } double childValue = node.search(depth - 1, alpha, beta, sw, maxNodsCache, minNodesCache); if (childValue < 0) { //打ち切り return(childValue); } s += (1.0 - mProb) * childValue; if (s < mScore) { mScore = s; if (s < beta) { beta = s; if (s <= alpha) { break; } } } } return(mScore); }
public MaxNode(Move lastMove, MinNode parent) { mLastMove = lastMove; mParent = parent; mScore = Double.PositiveInfinity; }