private double AlphaBeta(Board b, int depth, double alpha, double beta, int colour, ref Move bestMoveYet) { if (depth == 0) return b.ScoreBoard(); else { if (colour == 1) { for (int i = 0; i < b.AllMovesCount; i++) { Move move = b.AllMoves[i]; double result = AlphaBeta(b.GetBoardAfterMove(move.From, move.To), depth - 1, alpha, beta, -colour, ref bestMoveYet); nodesVisited++; if (result > alpha) { alpha = result; if (depth == MaxAlphaBetaDepth) bestMoveYet = move; } if (beta <= alpha) { betaSkips++; goto skip1; } } skip1: return alpha; } else if (colour == -1) { for (int i = 0; i < b.AllMovesCount; i++) { Move move = b.AllMoves[i]; double result = AlphaBeta(b.GetBoardAfterMove(move.From, move.To), depth - 1, alpha, beta, -colour, ref bestMoveYet); nodesVisited++; if (result < beta) { beta = result; if (depth == MaxAlphaBetaDepth) bestMoveYet = move; //bestMoveYet = move; } if (beta <= alpha) { betaSkips++; goto skip2; } } skip2: return beta; } else throw new ApplicationException(); } throw new ApplicationException(); }
private double Negamax(Board b, int depth, double alpha, double beta, int colour) { Tuple<int, double> tuple = m_Zasher.GetDepthScoreTuple(b); // If the same or better calculation of this state has already been made, use it. if (tuple != null && tuple.Item1 >= depth && depth < MaxNegamaxDepth) { if (depth > 0) hashUsed++; if (depth >= 0) hashUsed++; return colour * tuple.Item2; } if (depth == 0) { double score = b.ScoreBoard(); m_Zasher.SetDepthScoreTuple(b, new Tuple<int, double>(0, score)); hashNotUsed++; return colour * score; } else { for (int i = 0; i < b.AllMovesCount; i++) { Move move = b.AllMoves[i]; Board boardAfterMove = new Board(b); bool moveOk = boardAfterMove.MakeMove(move.From, move.To); if (moveOk) { double score = -Negamax(boardAfterMove, depth - 1, -beta, -alpha, -colour); // Cache this score m_Zasher.AddIfBetter(boardAfterMove, new Tuple<int, double>(depth - 1, colour * score)); nodesVisited++; if (score >= beta) return score; if (score > alpha) { alpha = score; } if (depth == MaxNegamaxDepth) { m_RankedMoves.Add(new Tuple<Move, double>(move, colour * score)); m_Zasher.AddIfBetter(b, new Tuple<int, double>(depth, colour * score)); } } } return alpha; } }