ADD file via upload

master
hnu202210040322 2 years ago
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…
Cancel
Save