int Min(ChessBoardSnapshot boardPosition, int depth) { if (depth <= 0 || boardPosition.IsEndGame()) { return(GameManager.Instance.CalculateScore(boardPosition, playerType)); } int lowestScore = int.MaxValue; ChessBoardSnapshot[] nextBoardPositions = FindPossibleMoves(boardPosition, playerType.ToOpposite()); for (int i = 0; i < nextBoardPositions.Length; i++) { ChessBoardSnapshot board = nextBoardPositions[i]; int score = Max(board, depth - 1); if (score < lowestScore) { lowestScore = score; } } return(lowestScore); }
int AlphaBeta(ChessBoardSnapshot boardPosition, int depth, int alpha, int beta, bool maximizingPlayer) { int origAlpha = alpha; int origBeta = beta; MinimaxNode node = new MinimaxNode(); // Transposition Table Lookup; node is the lookup key for ttEntry ulong hash = boardPosition.board.ToZobristHash(); if (tTable.ContainsKey(hash)) { node = tTable[hash]; if (node.depth >= depth) { switch (node.flag) { case MinimaxNodeFlag.Exact: return(node.eval); case MinimaxNodeFlag.LowerBound: if (node.eval > alpha) { alpha = node.eval; } break; case MinimaxNodeFlag.UpperBound: if (node.eval < beta) { beta = node.eval; } break; } if (beta <= alpha) { return(node.eval); } } } // Minimax + Alpha Beta Pruning if (depth <= 0 || boardPosition.IsEndGame()) { return(GameManager.Instance.CalculateScore(boardPosition, playerType)); } int val = 0; if (maximizingPlayer) { val = int.MinValue; ChessBoardSnapshot[] nextBoardPositions = FindPossibleMoves(boardPosition, playerType); for (int i = 0; i < nextBoardPositions.Length; i++) { int newValue = AlphaBeta(nextBoardPositions[i], depth - 1, alpha, beta, false); if (newValue > val) { val = newValue; } if (val > alpha) { alpha = val; } if (beta <= alpha) { break; } } } else { val = int.MaxValue; ChessBoardSnapshot[] nextBoardPositions = FindPossibleMoves(boardPosition, playerType.ToOpposite()); for (int i = 0; i < nextBoardPositions.Length; i++) { int newValue = AlphaBeta(nextBoardPositions[i], depth - 1, alpha, beta, true); if (newValue < val) { val = newValue; } if (val < beta) { beta = val; } if (beta <= alpha) { break; } } } // Transposition Table Store; node is the lookup key for ttEntry node.hash = hash; node.eval = val; if (val <= origAlpha) { node.flag = MinimaxNodeFlag.UpperBound; } else if (val >= origBeta) { node.flag = MinimaxNodeFlag.LowerBound; } else { node.flag = MinimaxNodeFlag.Exact; } node.depth = depth; if (tTable.ContainsKey(hash)) { tTable[hash] = node; } else { tTable.Add(hash, node); } return(val); }