Spaces:
Sleeping
Sleeping
File size: 4,765 Bytes
53b9b08 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | import chess
import random
import time
from . import evaluation
def random_move(board):
"""
Trả về một nước đi ngẫu nhiên từ các nước đi hợp lệ.
"""
legal_moves = list(board.legal_moves)
if not legal_moves:
return None
return random.choice(legal_moves)
def find_best_move(board, weights_dict, depth):
"""
Tìm nước đi tốt nhất sử dụng Minimax với Alpha-Beta Pruning.
"""
legal_moves = list(board.legal_moves)
if not legal_moves:
return None
start_time = time.time()
print(f"AI đang tính toán với độ sâu {depth}...")
best_move = None
max_eval = -float('inf')
alpha = -float('inf')
beta = float('inf')
nodes_evaluated = 0
# Sắp xếp các nước đi để tối ưu alpha-beta pruning
# Ưu tiên các nước đi ăn quân và chiếu
def move_priority(move):
score = 0
# Nước đi ăn quân có ưu tiên cao
if board.piece_at(move.to_square):
captured_piece = board.piece_at(move.to_square)
piece_values = {chess.PAWN: 10, chess.KNIGHT: 30, chess.BISHOP: 30,
chess.ROOK: 50, chess.QUEEN: 90, chess.KING: 900}
score += piece_values.get(captured_piece.piece_type, 0)
# Kiểm tra xem có chiếu không
board.push(move)
if board.is_check():
score += 50
board.pop()
return score
sorted_moves = sorted(legal_moves, key=move_priority, reverse=True)
for i, move in enumerate(sorted_moves):
board.push(move)
# Gọi minimax với negamax
eval_score = -minimax_search(board, weights_dict, depth - 1, -beta, -alpha)
nodes_evaluated += 1
board.pop()
if eval_score > max_eval:
max_eval = eval_score
best_move = move
alpha = max(alpha, eval_score)
if beta <= alpha:
break # Alpha-beta pruning
end_time = time.time()
elapsed_time = end_time - start_time
print(f"AI chọn nước đi: {best_move.uci() if best_move else 'None'}")
print(f"Điểm đánh giá: {max_eval:.2f}")
print(f"Thời gian: {elapsed_time:.2f}s, Nodes: {nodes_evaluated}")
return best_move
def minimax_search(board, weights_dict, depth, alpha, beta):
"""
Hàm đệ quy Minimax với Alpha-Beta Pruning (Negamax implementation)
"""
# Điều kiện dừng: game over
if board.is_game_over():
eval_score = evaluation.evaluate_board(board, weights_dict)
return eval_score if board.turn == chess.WHITE else -eval_score
# Khi depth = 0, sử dụng quiescence search
if depth == 0:
return quiescence_search(board, weights_dict, alpha, beta)
max_eval = -float('inf')
legal_moves = list(board.legal_moves)
# Sắp xếp nước đi để tối ưu pruning
def move_priority(move):
score = 0
if board.piece_at(move.to_square):
captured_piece = board.piece_at(move.to_square)
piece_values = {chess.PAWN: 10, chess.KNIGHT: 30, chess.BISHOP: 30,
chess.ROOK: 50, chess.QUEEN: 90, chess.KING: 900}
score += piece_values.get(captured_piece.piece_type, 0)
return score
sorted_moves = sorted(legal_moves, key=move_priority, reverse=True)
for move in sorted_moves:
board.push(move)
# Gọi đệ quy với negamax
eval_score = -minimax_search(board, weights_dict, depth - 1, -beta, -alpha)
board.pop()
max_eval = max(max_eval, eval_score)
alpha = max(alpha, eval_score)
# Alpha-beta pruning
if beta <= alpha:
break
return max_eval
def quiescence_search(board, weights_dict, alpha, beta):
"""
Quiescence search để đánh giá tốt hơn các vị trí có capture
"""
# Đánh giá vị trí hiện tại
stand_pat = evaluation.evaluate_board(board, weights_dict)
stand_pat = stand_pat if board.turn == chess.WHITE else -stand_pat
if stand_pat >= beta:
return beta
if alpha < stand_pat:
alpha = stand_pat
# Chỉ xem xét các nước đi capture
capture_moves = [move for move in board.legal_moves if board.piece_at(move.to_square)]
for move in capture_moves:
board.push(move)
score = -quiescence_search(board, weights_dict, -beta, -alpha)
board.pop()
if score >= beta:
return beta
if score > alpha:
alpha = score
return alpha |