parent
68ad6916ce
commit
6a33fbe9be
@ -0,0 +1,454 @@
|
||||
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("<Button-1>", partial(self.call_back, root, canvas, depth))
|
||||
canvas.pack()
|
||||
self.draw(root, canvas)
|
||||
root.mainloop()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test = map()
|
||||
test.run(6)
|
Loading…
Reference in new issue