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.updateByEnemyMove(mLastMove); mValue = result[0]; mProb = result[1]; } if (depth >= 4) { ulong hash = mField.TransPositionHash(); MaxNode node = null; if (maxNodsCache.TryGetValue(hash, out node)) { mScore = node.getScore(); return(mScore); } else { maxNodsCache.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 <MinNode>(moveList.Count); foreach (Move m in moveList) { mChildList.Add(new MinNode(m, this)); } } else { // 降順 mChildList.Sort((MinNode n0, MinNode n1) => { return(n0.getScore() > n1.getScore() ? -1 : n0.getScore() < n1.getScore() ? 1 : 0); }); } mScore = Double.NegativeInfinity; foreach (MinNode node in mChildList) { double s = mProb * mValue; if (s + (1.0 - mProb) <= 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; mBestChild = node; if (s > alpha) { alpha = s; if (s >= beta) { break; } } } } return(mScore); }