diff --git a/SafariChess_AI.py b/SafariChess_AI.py index 0a1b9cc..3ec0209 100644 --- a/SafariChess_AI.py +++ b/SafariChess_AI.py @@ -7,112 +7,78 @@ import random from math import inf import collections -piece_score = {"7": 120, "1": 100, "6": 120, "5": 80, "4": 60,"3": 70,"2": 100} +piece_score = {"7": 180, "1": 200, "6": 120, "5": 80, "4": 60, "3": 50, "2": 81} mouse_score = [[13, 13, 13, 13, 12, 11, 10, 9, 8], - [25, 20, 15, 13, 12, 12, 10, 9, 8], - [50, 25, 20, 12, 11, 11, 10, 9, 8], + [25, 20, 15, 18, 16, 13, 10, 9, 8], + [50, 25, 20, 16, 15, 13, 10, 9, 8], [1919810, 50, 20, 11, 9, 9, 9, 9, 0], - [50, 25, 20, 9, 8, 8, 8, 8, 8], - [25, 20, 15, 9, 8, 8, 8, 8, 8], + [50, 25, 20, 16, 14, 12, 8, 8, 8], + [25, 20, 15, 17, 15, 12, 8, 8, 8], [11, 11, 10, 8, 8, 8, 8, 8, 8]] -# eagle_score = [[ 11, 12, 14, 13, 12, 11, 10, 8, -# 8], -# [ 15, 15, 14, 14, 0, 0, 0, 8, -# 8], -# [ 50, 20, 20, 0, 0, 0, 0, 8, -# 8], -# [100000, 50, 20, 13, 12, 11, 10, 8, -# 0], -# [ 50, 20, 20, 14, 0, 0, 0, 8, -# 8], -# [ 15, 12, 15, 14, 0, 0, 0, 8, -# 8], -# [ 11, 12, 14, 13, 12, 11, 10, 8, -# 8]] -eagle_score = [[14,13,10,12,14,13,10,8,7], - [15,15,14,0,0,0,9,8,6], - [50,20,20,0,0,0,7,5,4], - [1919810,50,20,13,12,11,10,8,0], - [50,20,20,0,0,0,7,5,4], - [15,12,15,0,0,0,9,8,6], - [14,12,10,13,14,13,10,8,7]] - -fox_score = [[ 11, 12, 14, 13, 12, 11, 10, 8, - 8], - [ 15, 15, 14, 0, 0, 0, 10, 8, - 8], - [ 50, 20, 20, 0, 0, 0, 10, 9, - 10], - [1919810, 50, 20, 13, 12, 11, 11, 10, - 0], - [ 50, 20, 20, 0, 0, 0, 10, 9, - 10], - [ 15, 12, 15, 0, 0, 0, 10, 8, - 8], - [ 11, 12, 14, 13, 12, 11, 10, 8, - 8]] - -wolf_score = [[ 11, 12, 14, 13, 12, 11, 10, 8, - 8], - [ 15, 15, 14, 0, 0, 0, 10, 8, - 8], - [ 50, 20, 20, 0, 0, 0, 10, 9, - 10], - [1919810, 50, 20, 13, 12, 11, 11, 10, - 0], - [ 50, 20, 20, 0, 0, 0, 10, 9, - 10], - [ 15, 12, 15, 0, 0, 0, 10, 8, - 8], - [ 11, 12, 14, 13, 12, 11, 10, 8, - 8]] - -leopard_score = [[ 11, 12, 14, 13, 12, 11, 10, 8, - 8], - [ 15, 15, 14, 0, 0, 0, 10, 8, - 8], - [ 50, 20, 20, 0, 0, 0, 10, 9, - 10], - [1919810, 50, 20, 13, 12, 11, 11, 10, - 0], - [ 50, 20, 20, 0, 0, 0, 10, 9, - 10], - [ 15, 12, 15, 0, 0, 0, 10, 8, - 8], - [ 11, 12, 14, 13, 12, 11, 10, 8, - 8]] - -lion_score = [[ 20, 20, 18, 15, 12, 11, 14, 12, - 5], - [ 40, 25, 30, 0, 0, 0, 16, 12, - 12], - [ 50, 40, 30, 0, 0, 0, 16, 12, - 12], - [1919810, 50, 20, 15, 15, 15, 9, 12, - 0], - [ 50, 40, 30, 0, 0, 0, 16, 12, - 12], - [ 40, 25, 30, 0, 0, 0, 16, 12, - 12], - [ 20, 20, 18, 15, 12, 11, 14, 12, - 5]] - -elephant_score = [[ 20, 20, 18, 15, 12, 11, 14, 12, - 5], - [ 40, 25, 30, 0, 0, 0, 16, 12, - 12], - [ 50, 40, 30, 0, 0, 0, 16, 12, - 12], - [1919810, 50, 20, 15, 15, 15, 9, 12, - 0], - [ 50, 40, 30, 0, 0, 0, 16, 12, - 12], - [ 40, 25, 30, 0, 0, 0, 16, 12, - 12], - [ 20, 20, 18, 15, 12, 11, 14, 12, - 5]] +# eagle_score = [[11, 12, 14, 13, 12, 11, 10, 8, 8], +# [15, 15, 14, 14, 0, 0, 0, 8, 8], +# [50, 20, 20, 0, 0, 0, 0, 8, 8], +# [100000, 50, 20, 13, 12, 11, 10, 8, 0], +# [50, 20, 20, 14, 0, 0, 0, 8, 8], +# [15, 12, 15, 14, 0, 0, 0, 8, 8], +# [11, 12, 14, 13, 12, 11, 10, 8, 8]] + +eagle_score = [[14, 13, 10, 12, 14, 13, 10, 8, 7], + [15, 15, 14, 0, 0, 0, 9, 8, 6], + [50, 20, 20, 0, 0, 0, 7, 5, 4], + [1919810, 50, 20, 14, 13, 11, 10, 8, 0], + [50, 20, 20, 0, 0, 0, 7, 5, 4], + [15, 12, 15, 0, 0, 0, 9, 8, 6], + [14, 12, 10, 13, 14, 13, 10, 8, 7]] + +fox_score = [[11, 12, 14, 13, 12, 11, 10, 8, 8], + [15, 15, 14, 0, 0, 0, 10, 8, 11], + [50, 20, 20, 0, 0, 0, 10, 9, 10], + [1919810, 50, 20, 13, 12, 11, 11, 10, 0], + [50, 20, 20, 0, 0, 0, 10, 9, 10], + [15, 12, 15, 0, 0, 0, 10, 8, 11], + [11, 12, 14, 13, 12, 11, 10, 8, 8]] + +# wolf_score = [[11, 12, 14, 13, 12, 11, 10, 8, 8], +# [15, 15, 14, 0, 0, 0, 10, 8, 8], +# [50, 20, 20, 0, 0, 0, 10, 9, 10], +# [1919810, 50, 20, 13, 12, 11, 11, 10, 0], +# [50, 20, 20, 0, 0, 0, 10, 9, 10], +# [15, 12, 15, 0, 0, 0, 10, 8, 8], +# [11, 12, 14, 13, 12, 11, 10, 8, 8]] +wolf_score = [[11, 12, 14, 13, 12, 11, 10, 10, 8], + [15, 15, 14, 0, 0, 0, 10, 13, 10], + [50, 20, 20, 0, 0, 0, 10, 12, 10], + [1919810, 50, 20, 12, 11, 10, 11, 12, 0], + [50, 20, 20, 0, 0, 0, 10, 13, 10], + [15, 12, 15, 0, 0, 0, 13, 14, 8], + [11, 12, 14, 15, 16, 17, 16, 15, 8]] + +leopard_score = [[11, 12, 14, 13, 12, 11, 10, 8, 8], + [15, 15, 14, 0, 0, 0, 10, 8, 8], + [50, 20, 20, 0, 0, 0, 10, 9, 10], + [1919810, 50, 20, 13, 12, 11, 11, 10, 0], + [50, 20, 20, 0, 0, 0, 10, 9, 10], + [15, 12, 15, 0, 0, 0, 10, 8, 8], + [11, 12, 14, 13, 12, 11, 10, 8, 8]] + +lion_score = [[20, 20, 18, 15, 12, 11, 14, 12, 5], + [40, 25, 30, 0, 0, 0, 16, 12, 12], + [50, 40, 30, 0, 0, 0, 16, 12, 12], + [1919810, 50, 20, 15, 15, 15, 9, 12, 0], + [50, 40, 30, 0, 0, 0, 16, 12, 12], + [40, 25, 30, 0, 0, 0, 16, 12, 12], + [20, 20, 18, 15, 12, 11, 14, 12, 5]] + +elephant_score = [[20, 20, 18, 15, 12, 11, 14, 12, 5], + [40, 25, 30, 0, 0, 0, 16, 12, 12], + [50, 40, 30, 0, 0, 0, 16, 12, 12], + [1919810, 50, 20, 15, 15, 15, 9, 12, 0], + [50, 40, 30, 0, 0, 0, 16, 12, 12], + [40, 25, 30, 0, 0, 0, 16, 12, 12], + [20, 20, 18, 15, 12, 11, 14, 12, 5]] piece_position_scores = {"r1": mouse_score, "b1": [line[::-1] for line in mouse_score[::-1]], @@ -130,17 +96,16 @@ piece_position_scores = {"r1": mouse_score, "b7": [line[::-1] for line in elephant_score[::-1]], } - - -DEN_CONQUESTED=10000 -DRAW=0 -global DEPTH #=4 +DEN_CONQUESTED = 10000 +DRAW = 0 +global DEPTH # =4 def findRandomMove(valid_moves): - return valid_moves[random.randint(0,len(valid_moves)-1)] + return valid_moves[random.randint(0, len(valid_moves) - 1)] + -#is greedy_move function used here? +# is greedy_move function used here? def find_GreadyMove(game_state, valid_moves): turnMultiplier = 1 if game_state.red_to_move else -1 maxScore = -DEN_CONQUESTED @@ -157,27 +122,38 @@ def find_GreadyMove(game_state, valid_moves): return bestMove -def scoreMaterial(game_state): # get the score +def scoreMaterial(game_state): # get the score + # input: current game_state score = 0 penalty_for_rep = 0 for row in range(len(game_state.board)): - for col in range(len(game_state.board[row])): + for col in range(len(game_state.board[row])): # 遍历整个棋盘 piece = game_state.board[row][col] if piece != "00": piece_position_score = 0 - piece_position_score = piece_position_scores[piece][row][col] - if piece_position_scores[piece][row][col] in last_moves: + piece_position_score = piece_position_scores[piece][row][col] # 获得当前位置的得分 + if piece_position_scores[piece][row][col] in last_moves: # 重复判罚 penalty_for_rep += 70 if piece[0] == 'r': - score += piece_position_score + piece_score[piece[1]] - penalty_for_rep + score += piece_position_score + piece_score[piece[1]] - penalty_for_rep elif piece[0] == 'b': - score -= piece_position_score + piece_score[piece[1]] - penalty_for_rep + score -= piece_position_score + piece_score[piece[1]] - penalty_for_rep # 注意:这个默认没有考虑”淘汰“的可能性? + #待检查: return score -def findMove_NegaMaxAlphaBeta(game_state, valid_moves, depth,DEPTH, alpha, beta, turn_multiplier): + +def findMove_NegaMaxAlphaBeta(game_state, valid_moves, depth, DEPTH, alpha, beta, turn_multiplier): + # 对于各个参数的理解: + # game_state:当前状态 + # valid_moves:可行的行动列表 + # depth:当前深度 + # DEPTH:限制深度 + # alpha:alpha限制值 + # beta:beta限制值 + # turn_multiplier:NegaMax特性 global next_move if depth == 0: return turn_multiplier * scoreMaterial(game_state) @@ -186,16 +162,16 @@ def findMove_NegaMaxAlphaBeta(game_state, valid_moves, depth,DEPTH, alpha, beta, for move in valid_moves: game_state.makeMove(move) next_moves = game_state.getAllMoves() - score = -findMove_NegaMaxAlphaBeta(game_state, next_moves, depth - 1,DEPTH, -beta, -alpha, -turn_multiplier) + score = -findMove_NegaMaxAlphaBeta(game_state, next_moves, depth - 1, DEPTH, -beta, -alpha, -turn_multiplier) - if score > max_score: # > or >= ?? + if score > max_score: # > or >= ?? max_score = score if depth == DEPTH: next_move = move game_state.undoMove() if max_score > alpha: - alpha = max_score + alpha = max_score if alpha >= beta: break return max_score @@ -204,26 +180,26 @@ def findMove_NegaMaxAlphaBeta(game_state, valid_moves, depth,DEPTH, alpha, beta, def findMove_MiniMaxAlphaBeta(game_state, valid_moves, depth, alpha, beta, turn_multiplier): global next_move - def max_value(game_state,next_moves, alpha, beta,depth): + def max_value(game_state, next_moves, alpha, beta, depth): if depth == 0: return turn_multiplier * scoreMaterial(game_state) v = -inf for move in valid_moves: next_moves = game_state.getAllMoves() - v = max(v, min_value(game_state,next_moves, alpha, beta,depth - 1)) + v = max(v, min_value(game_state, next_moves, alpha, beta, depth - 1)) game_state.undoMove() if v >= beta: return v alpha = max(alpha, v) return v - def min_value(game_state,next_moves, alpha, beta,depth): + def min_value(game_state, next_moves, alpha, beta, depth): if depth == 0: return turn_multiplier * scoreMaterial(game_state) v = -inf for move in valid_moves: next_moves = game_state.getAllMoves() - v = min(v, max_value(game_state,next_moves, alpha, beta,depth - 1)) + v = min(v, max_value(game_state, next_moves, alpha, beta, depth - 1)) game_state.undoMove() if v <= alpha: return v @@ -235,27 +211,29 @@ def findMove_MiniMaxAlphaBeta(game_state, valid_moves, depth, alpha, beta, turn_ beta = inf best_action = None for move in valid_moves: - v = min_value(game_state,valid_moves, best_score, beta,depth) + v = min_value(game_state, valid_moves, best_score, beta, depth) if v > best_score: best_score = v best_action = move return best_action -def find_BestMove(game_state, valid_moves,depth_p): + +def find_BestMove(game_state, valid_moves, depth_p): global next_move - DEPTH= depth_p + DEPTH = depth_p next_move = None global last_moves last_moves = collections.deque(maxlen=12) random.shuffle(valid_moves) - ordered_valid_moves=orderby_GreadyMove(game_state, valid_moves) + ordered_valid_moves = orderby_GreadyMove(game_state, valid_moves) # for i in valid_moves: # print(f"Possible: {i}") # for i in ordered_valid_moves: # print(f"New possible: {i}") - findMove_NegaMaxAlphaBeta(game_state, ordered_valid_moves,depth_p,DEPTH, -DEN_CONQUESTED, DEN_CONQUESTED,1 if game_state.red_to_move else -1) + findMove_NegaMaxAlphaBeta(game_state, ordered_valid_moves, depth_p, DEPTH, -DEN_CONQUESTED, DEN_CONQUESTED, + 1 if game_state.red_to_move else -1) last_moves.append(next_move) return next_move diff --git a/SafariChess_Gamev1.0.py b/SafariChess_Gamev1.0.py index 7dbb0d9..902dac0 100644 --- a/SafariChess_Gamev1.0.py +++ b/SafariChess_Gamev1.0.py @@ -250,6 +250,7 @@ def MainMenu(): pg.mixer.init() #mixer的初始化 music = pg.mixer.music.load(file) #载入一个音乐文件用于播放 pg.mixer.music.play(-1) #播放音乐,-1表示循环播放 + pg.mixer.music.set_volume(0) COLOR_INACTIVE = (255, 108, 0) COLOR_ACTIVE = (255, 208, 0) @@ -774,7 +775,7 @@ if __name__ == '__main__': #print("Loading...") #print("Initialing game...") mode = MainMenu() - #mode = 4 + # mode = 4 main(mode) diff --git a/__pycache__/SafariChess_AI.cpython-39.pyc b/__pycache__/SafariChess_AI.cpython-39.pyc index 7a4717a..d0af326 100644 Binary files a/__pycache__/SafariChess_AI.cpython-39.pyc and b/__pycache__/SafariChess_AI.cpython-39.pyc differ diff --git a/__pycache__/SafariChess_backend.cpython-39.pyc b/__pycache__/SafariChess_backend.cpython-39.pyc index 7ee8bb5..eafd3dc 100644 Binary files a/__pycache__/SafariChess_backend.cpython-39.pyc and b/__pycache__/SafariChess_backend.cpython-39.pyc differ