| 195 | } |
| 196 | |
| 197 | int MachineGame::alphaBeta(int depth, int alpha, int beta, bool isMaximizing) |
| 198 | { |
| 199 | if (depth == 0) |
| 200 | return calcScore(); |
| 201 | |
| 202 | // 检查将帅是否已死 |
| 203 | if (m_ChessPieces[4].m_bDead) // 黑将死 |
| 204 | return m_bAiIsRed ? 100000 + depth : -(100000 + depth); |
| 205 | if (m_ChessPieces[20].m_bDead) // 红帅死 |
| 206 | return m_bAiIsRed ? -(100000 + depth) : 100000 + depth; |
| 207 | |
| 208 | QVector<ChessStep*> steps; |
| 209 | bool forRed = m_bIsRed; |
| 210 | getAllMoves(steps, forRed); |
| 211 | |
| 212 | if (steps.isEmpty()) { |
| 213 | return isMaximizing ? -(99999 + depth) : (99999 + depth); |
| 214 | } |
| 215 | |
| 216 | // 走法排序:吃子走法优先 |
| 217 | std::sort(steps.begin(), steps.end(), [](ChessStep* a, ChessStep* b) { |
| 218 | return (a->m_nKillID != -1) > (b->m_nKillID != -1); |
| 219 | }); |
| 220 | |
| 221 | int bestVal = isMaximizing ? INT_MIN : INT_MAX; |
| 222 | |
| 223 | for (auto* step : steps) { |
| 224 | fakeMove(step); |
| 225 | int val = alphaBeta(depth - 1, alpha, beta, !isMaximizing); |
| 226 | unFakeMove(step); |
| 227 | |
| 228 | if (isMaximizing) { |
| 229 | if (val > bestVal) bestVal = val; |
| 230 | if (val > alpha) alpha = val; |
| 231 | } else { |
| 232 | if (val < bestVal) bestVal = val; |
| 233 | if (val < beta) beta = val; |
| 234 | } |
| 235 | if (alpha >= beta) |
| 236 | break; |
| 237 | } |
| 238 | |
| 239 | for (auto* s : steps) delete s; |
| 240 | return bestVal; |
| 241 | } |
| 242 | |
| 243 | ChessStep* MachineGame::getBestMove() |
| 244 | { |
nothing calls this directly
no outgoing calls
no test coverage detected