from abc import ABC, abstractmethod from tkinter import Tk, Canvas import tkinter as tk from functools import partial count = 0 class chess(ABC): def __init__(self, x:int, y:int, color:bool, type:int)->None: self.x = x self.y = y self.color = color self.type = type def move_able(self, map:map, x1:int, y1:int)->bool: chess_map = map.chess_map try: chess_color = map.chess_map[x1][y1].color color = self.color if chess_color < 2 and color != chess_color or chess_color == 2: return True else: return False except: print((x1, y1)) print((len(chess_map), len(chess_map[0]))) return False def if_blank(self, map:map, x1:int, y1:int)->bool: chess_color = map.chess_map[x1][y1].color if chess_color == 2: return True else: return False def if_enemy(self, map:map, x1:int, y1:int)->bool: chess_color = map.chess_map[x1][y1].color color = self.color if chess_color < 2 and chess_color != color: return True else: return False def within_range(self, map:map, x1:int, y1:int)->bool: edge = map.edge row = map.row col = map.col return edge <= x1 < edge + col and edge <= y1 < edge + row def not_pass_river(self, map:map, y1)->bool: y = map.river[self.color] return y[0] <= y1 <= y[1] @abstractmethod def get_all_moveable_position(self, map:map): pass @abstractmethod def __repr__(self): pass class chess_che(chess): vector = [(1, 0), (0, 1), (-1, 0), (0, -1)] def get_all_moveable_position(self, map:map)->list: x1 = self.x y1 = self.y vector = self.vector ans = [] if_enemy = self.if_enemy if_blank = self.if_blank for i in vector: delta_x = i[0] delta_y = i[1] x = x1 + delta_x y = y1 + delta_y while if_blank(map, x, y): ans.append((x, y)) x += delta_x y += delta_y if if_enemy(map, x, y): ans.append((x, y)) return ans def __repr__(self): return "车" class chess_ma(chess): vector = [(1, 2, 0, 1), (1, -2, 0, -1), (2, 1, 1, 0), (2, -1, 1, 0), (-2, 1, -1, 0), (-1, 2, 0, 1), (-1, -2, 0, -1), (-2, -1, -1, 0)] def get_all_moveable_position(self, map:map)->list: x = self.x y = self.y vector = self.vector move_able = self.move_able if_blank = self.if_blank return [(x + i[0], y + i[1]) for i in vector if move_able(map, x + i[0], y + i[1]) and if_blank(map, x + i[2], y + i[3])] def __repr__(self): return "马" class chess_xiang(chess): vector = [(2, 2), (2, -2), (-2, 2), (-2, -2)] def get_all_moveable_position(self, map:map): x = self.x y = self.y vector = self.vector move_able = self.move_able if_blank = self.if_blank not_pass_river = self.not_pass_river return [(x + i[0], y + i[1]) for i in vector if move_able(map, x + i[0], y + i[1]) and if_blank(map, x + i[0] // 2, y + i[1] // 2) and not_pass_river(map, y + i[1])] def __repr__(self): return "相" class chess_shi(chess): vector = [(1, 1), (1, -1), (-1, 1), (-1, -1)] def get_all_moveable_position(self, map:map): x = self.x y = self.y vector = self.vector pos = map.handsome[self.color] if x == pos[0] and y == pos[1]: move_able = self.move_able return [(x + i[0], y + i[1]) for i in vector if move_able(map, x + i[0], y + i[1])] else: if(self.move_able(map, pos[0], pos[1])): return [pos] else: return [] def __repr__(self): return "仕" class chess_jiang(chess): vector = [(-1, 0), (0, -1), (1, 0), (0, 1)] def within_range(self, map:map, x1:int, y1:int)->bool: pos = map.handsome[self.color] x = pos[0] y = pos[1] return x - 1 <= x1 <= x + 1 and y - 1 <= y1 <= y + 1 def get_all_moveable_position(self, map:map): x = self.x y = self.y vector = self.vector move_able = self.move_able within_range = self.within_range return [(x + i[0], y + i[1]) for i in vector if move_able(map, x + i[0], y + i[1]) and within_range(map, x + i[0], y + i[1])] def __repr__(self): return "将" class chess_pao(chess): vector = [(1, 0), (0, 1), (-1, 0), (0, -1)] def get_all_moveable_position(self, map:map): x = self.x y = self.y vector = self.vector if_blank = self.if_blank if_enemy = self.if_enemy ans = [] for i in vector: delta_x = i[0] delta_y = i[1] x1 = x + delta_x y1 = y + delta_y while if_blank(map, x1, y1): ans.append((x1, y1)) x1 += delta_x y1 += delta_y x1 += delta_x y1 += delta_y while if_blank(map, x1, y1): x1 += delta_x y1 += delta_y if if_enemy(map, x1, y1): ans.append((x1, y1)) return ans def __repr__(self): return "炮" class chess_bing(chess): vector = [[[(0, 1)], [(1, 0), (-1, 0), (0, 1)]], [[(0, -1)], [(1, 0), [-1, 0], (0, -1)]]] def get_all_moveable_position(self, map:map): move_able = self.move_able color = self.color x = self.x y = self.y vector = self.vector[color][1 - self.not_pass_river(map, y)] return [(x + i[0], y + i[1]) for i in vector if move_able(map, x + i[0], y + i[1])] def __repr__(self): return "兵" class chess_blank(chess): def __init__(self): self.color = 2 def get_all_moveable_position(self, map:map): pass def __repr__(self): return " " class chess_block(chess): def __init__(self): self.color = 3 def get_all_moveable_position(self, map:map): pass def __repr__(self): return "**" class process: def __init__(self, start:tuple, end:tuple, eaten_chess:chess)->None: self.start = start self.end = end self.eaten_chess = eaten_chess class map: chess_map = [] col = 9 row = 10 edge = 2 river = [(edge, edge + row // 2 - 1), (edge + row // 2, edge + row)] handsome = [(edge + col // 2, edge + 1), (edge + col // 2, edge + row - 2)] exist_chess = [] score = 0 score_standard = [100, 80, 40, 30, 10000, 80, 20] level_score = [10000000 if i % 2 == 0 else -10000000 for i in range(100)] lock = [0, 0, 0] #0: 未锁定 1:已锁定 def __init__(self): col = self.col row = self.row edge = self.edge chess_map = [[chess_blank() if edge <= i < edge + col and edge <= j < row + edge else chess_block() for j in range(row + edge * 2)] for i in range(col + edge * 2)] with open("map_data.txt", "r") as fp: map_data = fp.readlines() for data in map_data: data_list = data.split() x = int(data_list[0]) + edge y = int(data_list[1]) + edge color = int(data_list[2]) type = int(data_list[3]) if type == 0: chess_map[x][y] = chess_che(x , y, color, type) chess_map[x][edge * 2 + row - 1 - y] = chess_che(x, edge * 2 + row - 1 - y, 1 - color, type) elif type == 1: chess_map[x][y] = chess_ma(x , y, color, type) chess_map[x][edge * 2 + row - 1 - y] = chess_ma(x, edge * 2 + row - 1 - y, 1 - color, type) elif type == 2: chess_map[x][y] = chess_xiang(x , y, color, type) chess_map[x][edge * 2 + row - 1 - y] = chess_xiang(x, edge * 2 + row - 1 - y, 1 - color, type) elif type == 3: chess_map[x][y] = chess_shi(x , y, color, type) chess_map[x][edge * 2 + row - 1 - y] = chess_shi(x, edge * 2 + row - 1 - y, 1 - color, type) elif type == 4: chess_map[x][y] = chess_jiang(x , y, color, type) chess_map[x][edge * 2 + row - 1 - y] = chess_jiang(x, edge * 2 + row - 1 - y, 1 - color, type) elif type == 5: chess_map[x][y] = chess_pao(x , y, color, type) chess_map[x][edge * 2 + row - 1 - y] = chess_pao(x, edge * 2 + row - 1 - y, 1 - color, type) elif type == 6: chess_map[x][y] = chess_bing(x , y, color, type) chess_map[x][edge * 2 + row - 1 - y] = chess_bing(x, edge * 2 + row - 1 - y, 1 - color, type) self.chess_map = chess_map def show(self)->None: row = self.row col = self.col edge = self.edge chess_map = self.chess_map for i in range(row + edge * 2): for j in range(col + edge * 2): print(chess_map[j][i], end = "") print() def draw(self, root, canvas): canvas.delete(tk.ALL) canvas.create_rectangle(50, 50, 50 + 50 * 8, 50 + 50 * 9) for i in range(100, 100 + 50 * 8, 50): #画横线 canvas.create_line(50, i, 50 + 50 * 8, i) for i in range(100, 100 + 50 * 8, 50): #画竖线 canvas.create_line(i, 50, i, 50 + 4 * 50) canvas.create_line(i, 50 + 50 * 5, i, 50 + 50 * 9) chess_map = self.chess_map for i in chess_map: for j in i: if j.color < 2: canvas.create_oval(50 * (j.x - 1) - 20, 50 * (j.y - 1) - 20, 50 * (j.x - 1) + 20, 50 * (j.y - 1) + 20, fill = "white") canvas.create_text(50 * (j.x - 1), 50 * (j.y - 1), text = j.__repr__(), fill = "black" if j.color == 0 else "red", font=('Old English Text MT',20)) def get_ans(self, pro:process, cur_depth:int, max_depth:int, color:bool, primer_color:bool, cur_score): global count count += 1 x2, y2 = pro.end chess_end = self.chess_map[x2][y2] level_score = self.level_score score_standard = self.score_standard if cur_depth % 2 == 1 and cur_depth > 1: #如果是奇数 if level_score[cur_depth - 1] < cur_score - 200: return cur_score + 100 elif cur_depth % 2 == 0 and cur_depth > 1: if level_score[cur_depth - 1] > cur_score + 200: return cur_score - 100 if cur_depth == max_depth: return cur_score get_ans = self.get_ans chess_map = self.chess_map x3, y3 = pro.start chess_start = chess_map[x3][y3] chess_map[x3][y3] = chess_blank() chess_map[x2][y2] = chess_start chess_start.x = x2 chess_start.y = y2 if cur_depth % 2 == 1: #奇数找最大值 score = -1000000 for i in chess_map: for j in i: if j.color == color: x1 = j.x y1 = j.y for x, y in j.get_all_moveable_position(self): pro = process((x1, y1), (x, y), chess_map[x][y]) if chess_map[x][y].color == 1 - primer_color: t = get_ans(pro, cur_depth + 1, max_depth, 1 - color, primer_color, cur_score + score_standard[chess_map[x][y].type]) elif chess_map[x][y].color == primer_color: #被吃加10点debuff t = get_ans(pro, cur_depth + 1, max_depth, 1 - color, primer_color, cur_score - score_standard[chess_map[x][y].type] - 10) else: t = get_ans(pro, cur_depth + 1, max_depth, 1 - color, primer_color, cur_score) if t > score: score = t if score > level_score[cur_depth]: level_score[cur_depth] = score else: score = 1000000 for i in chess_map: for j in i: if j.color == color: x1 = j.x y1 = j.y for x, y in j.get_all_moveable_position(self): pro = process((x1, y1), (x, y), chess_map[x][y]) if chess_map[x][y].color == 1 - primer_color: t = get_ans(pro, cur_depth + 1, max_depth, 1 - color, primer_color, cur_score + score_standard[chess_map[x][y].type]) elif chess_map[x][y].color == primer_color: #同理 t = get_ans(pro, cur_depth + 1, max_depth, 1 - color, primer_color, cur_score - score_standard[chess_map[x][y].type] - 10) else: t = get_ans(pro, cur_depth + 1, max_depth, 1 - color, primer_color, cur_score) if t < score: score = t if score < level_score[cur_depth]: level_score[cur_depth] = score chess_start.x = x3 chess_start.y = y3 chess_map[x3][y3] = chess_start chess_map[x2][y2] = chess_end return score def next(self, pro): chess_map = self.chess_map x1 = pro.start[0] y1 = pro.start[1] x2 = pro.end[0] y2 = pro.end[1] chess_start = chess_map[x1][y1] chess_start.x = x2 chess_start.y = y2 chess_map[x2][y2] = chess_start chess_map[x1][y1] = chess_blank() def get_pro(self, depth): score = -10000 get_ans = self.get_ans chess_map = self.chess_map score_standard = self.score_standard for i in chess_map: for j in i: if j.color == 1: for x, y in j.get_all_moveable_position(self): pro = process((j.x, j.y), (x, y), chess_map[x][y]) t = get_ans(pro, 2, depth, 0, 1, 0 if chess_map[x][y].color == 2 else score_standard[chess_map[x][y].type]) if t > score: score = t p = pro self.level_score = [10000000 if i % 2 == 0 else -10000000 for i in range(100)] return p def call_back(self, root, canvas, depth, event): print((self.lock[0], self.lock[1], self.lock[2])) chess_map = self.chess_map lock = self.lock for i in range(50, 50 + 50 * 9, 50): for j in range(50, 50 + 50 * 10, 50): if (event.x - i) ** 2 + (event.y - j) ** 2 < 20 ** 2: x = i // 50 + 1 y = j // 50 + 1 if chess_map[x][y].color < 3: if lock[2] == 0: #如果未锁定 if chess_map[x][y].color < 2: lock[2] = 1 lock[0] = x lock[1] = y elif lock[0] == x and lock[1] == y: #如果锁定的是一样的棋子 lock[2] = 0 else: if chess_map[lock[0]][lock[1]].color == 0: if chess_map[x][y].color == 1 or chess_map[x][y].color == 2: lock[2] = 0 #解锁 pro = process((lock[0], lock[1]), (x, y), chess_map[x][y]) self.next(pro) self.draw(root, canvas) root.update() pro = self.get_pro(depth) self.next(pro) self.draw(root, canvas) global count print(count) count = 0 elif chess_map[x][y].color == 0: #不用解锁 lock[0] = x lock[1] = y return return def run(self, depth)->None: chess_map = self.chess_map get_ans = self.get_ans root = Tk() canvas = Canvas(master = root, height = 550, width = 500) canvas.bind("", partial(self.call_back, root, canvas, depth)) canvas.pack() self.draw(root, canvas) root.mainloop() if __name__ == "__main__": test = map() test.run(6)