|
|
|
@ -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
|
|
|
|
|