import tkinter as tk

# ===================== 全局配置 =====================
CELL_SIZE = 50
MAP_ROW = 12
MAP_COL = 16

# 地形配置
TERRAIN = {
    "plain": {"cost": 1, "def": 0, "color": "#D2B48C", "name": "平原"},
    "hill": {"cost": 2, "def": 2, "color": "#808080", "name": "山地"},
    "forest": {"cost": 2, "def": 1, "color": "#2E8B57", "name": "森林"},
    "water": {"cost": 999, "def": 0, "color": "#4682B4", "name": "水域"}
}

# 兵种属性
SOLDIER_TYPE = {
    "infantry": {"hp": 100, "atk": 25, "move": 3, "name": "步兵"},
    "tank": {"hp": 200, "atk": 50, "move": 2, "name": "坦克"},
    "artillery": {"hp": 80, "atk": 70, "move": 1, "name": "火炮"}
}

CAMP_COLOR = {"red": "#ff3333", "blue": "#3366ff"}

# 单位类
class Unit:
    def __init__(self, camp, unit_type, r, c):
        self.camp = camp
        self.unit_type = unit_type
        self.max_hp = SOLDIER_TYPE[unit_type]["hp"]
        self.hp = self.max_hp
        self.atk = SOLDIER_TYPE[unit_type]["atk"]
        self.move_range = SOLDIER_TYPE[unit_type]["move"]
        self.r = r
        self.c = c
        self.has_moved = False
        self.has_attacked = False

class WargameGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("超多兵力｜玩家红方 VS AI蓝方 兵棋推演")
        self.root.resizable(False, False)

        self.is_red_turn = True
        self.map_terrain = []
        self.unit_list = []
        self.selected_unit = None
        self.move_cells = set()
        self.attack_cells = set()
        self.battle_log = []

        self.build_widget()
        self.init_map_terrain()
        self.init_many_units()
        self.refresh_all()
        self.add_log("===== 满编军团对战开始！你操控红方 =====")

    def build_widget(self):
        main_frame = tk.Frame(self.root)
        main_frame.pack(padx=10, pady=10)

        self.canvas = tk.Canvas(
            main_frame, width=MAP_COL * CELL_SIZE, height=MAP_ROW * CELL_SIZE, bg="white"
        )
        self.canvas.grid(row=0, column=0, rowspan=2)
        self.canvas.bind("<Button-1>", self.canvas_click)

        right_frame = tk.Frame(main_frame)
        right_frame.grid(row=0, column=1, padx=10, sticky="n")

        self.turn_label = tk.Label(right_frame, text="当前回合：玩家（红方）行动", font=("黑体", 14, "bold"), fg="red")
        self.turn_label.pack(pady=5)

        tk.Label(right_frame, text="单位信息", font=("黑体", 12, "bold")).pack()
        self.info_text = tk.Text(right_frame, width=28, height=8)
        self.info_text.pack(pady=3)

        btn_frame = tk.Frame(right_frame)
        btn_frame.pack(pady=5)
        tk.Button(btn_frame, text="结束回合", command=self.next_turn, width=8).grid(row=0, column=0, padx=2)
        tk.Button(btn_frame, text="重置战场", command=self.reset_game, width=8).grid(row=0, column=1, padx=2)
        tk.Button(btn_frame, text="清空日志", command=self.clear_log, width=8).grid(row=1, column=0, padx=2, pady=2)
        tk.Button(btn_frame, text="取消选中", command=self.cancel_step, width=8).grid(row=1, column=1, padx=2, pady=2)

        tk.Label(right_frame, text="战斗日志", font=("黑体", 12, "bold")).pack()
        self.log_box = tk.Text(right_frame, width=28, height=12)
        self.log_box.pack()

    def init_map_terrain(self):
        self.map_terrain = [["plain" for _ in range(MAP_COL)] for _ in range(MAP_ROW)]
        for r in range(4, 8):
            self.map_terrain[r][7] = "water"
        for r in [2, 9]:
            for c in [3, 12]:
                self.map_terrain[r][c] = "hill"
        for r in [5, 6]:
            for c in [2, 13]:
                self.map_terrain[r][c] = "forest"

    # ===================== 大量兵力部署（重点修改）=====================
    def init_many_units(self):
        self.unit_list.clear()

        # ===== 红方大量军团（玩家部队）=====
        red_infantry = [
            (0,0), (0,2), (1,1), (2,0), (2,2),
            (3,0), (3,3), (4,1), (5,0), (5,2),
            (7,0), (7,2), (8,1), (9,0), (9,3)
        ]
        red_tank = [
            (1,3), (4,2), (8,2), (6,0)
        ]
        red_arty = [
            (0,4), (3,4), (9,4)
        ]

        for r,c in red_infantry:
            self.unit_list.append(Unit("red","infantry",r,c))
        for r,c in red_tank:
            self.unit_list.append(Unit("red","tank",r,c))
        for r,c in red_arty:
            self.unit_list.append(Unit("red","artillery",r,c))

        # ===== 蓝方大量军团（AI全自动部队）=====
        blue_infantry = [
            (0,15), (0,13), (1,14), (2,15), (2,12),
            (3,15), (3,11), (4,14), (5,15), (5,12),
            (7,15), (7,13), (8,14), (9,15), (9,12)
        ]
        blue_tank = [
            (1,11), (4,13), (8,13), (6,15)
        ]
        blue_arty = [
            (0,10), (3,10), (9,10)
        ]

        for r,c in blue_infantry:
            self.unit_list.append(Unit("blue","infantry",r,c))
        for r,c in blue_tank:
            self.unit_list.append(Unit("blue","tank",r,c))
        for r,c in blue_arty:
            self.unit_list.append(Unit("blue","artillery",r,c))

    def get_cell_rect(self, r, c):
        x1 = c * CELL_SIZE
        y1 = r * CELL_SIZE
        x2 = x1 + CELL_SIZE
        y2 = y1 + CELL_SIZE
        return x1, y1, x2, y2

    def draw_map(self):
        self.canvas.delete("map")
        for r in range(MAP_ROW):
            for c in range(MAP_COL):
                terr_key = self.map_terrain[r][c]
                x1, y1, x2, y2 = self.get_cell_rect(r, c)
                self.canvas.create_rectangle(x1, y1, x2, y2, fill=TERRAIN[terr_key]["color"], outline="black", tags="map")
                self.canvas.create_text((x1+x2)/2, (y1+y2)/2, text=TERRAIN[terr_key]["name"][0], font=("微软雅黑", 8), tags="map")

    def draw_units(self):
        self.canvas.delete("unit")
        for unit in self.unit_list:
            if unit.hp <= 0:
                continue
            x1, y1, x2, y2 = self.get_cell_rect(unit.r, unit.c)
            cx, cy = (x1+x2)/2, (y1+y2)/2
            self.canvas.create_oval(x1+6, y1+6, x2-6, y2-6, fill=CAMP_COLOR[unit.camp], outline="black", width=2, tags="unit")
            short_name = SOLDIER_TYPE[unit.unit_type]["name"][0]
            self.canvas.create_text(cx, cy, text=short_name, fill="white", font=("黑体", 12, "bold"), tags="unit")
            hp_percent = unit.hp / unit.max_hp
            bar_len = CELL_SIZE - 12
            bar_top = y1 + 4
            self.canvas.create_rectangle(x1+6, bar_top, x1+6 + bar_len*hp_percent, bar_top+4, fill="#00ee00", tags="unit")
            self.canvas.create_rectangle(x1+6 + bar_len*hp_percent, bar_top, x2-6, bar_top+4, fill="#ee2222", tags="unit")
            if self.selected_unit == unit:
                self.canvas.create_rectangle(x1+2, y1+2, x2-2, y2-2, outline="yellow", width=3, tags="unit")

    def draw_highlight(self):
        self.canvas.delete("hl")
        for (r, c) in self.move_cells:
            x1, y1, x2, y2 = self.get_cell_rect(r, c)
            self.canvas.create_rectangle(x1, y1, x2, y2, outline="#00cc00", width=3, dash=(5,2), tags="hl")
        for (r, c) in self.attack_cells:
            x1, y1, x2, y2 = self.get_cell_rect(r, c)
            self.canvas.create_rectangle(x1, y1, x2, y2, outline="#cc0000", width=3, dash=(5,2), tags="hl")

    def calc_move_range(self, unit):
        self.move_cells.clear()
        if unit.has_moved:
            return
        max_cost = unit.move_range
        for r in range(MAP_ROW):
            for c in range(MAP_COL):
                if r == unit.r and c == unit.c:
                    continue
                step_dist = abs(r - unit.r) + abs(c - unit.c)
                cell_cost = TERRAIN[self.map_terrain[r][c]]["cost"]
                total_cost = step_dist * cell_cost
                if total_cost <= max_cost and cell_cost != 999:
                    occupied = any(u.r == r and u.c == c and u.camp == unit.camp and u.hp>0 for u in self.unit_list)
                    if not occupied:
                        self.move_cells.add((r, c))

    def calc_attack_range(self, unit):
        self.attack_cells.clear()
        if unit.has_attacked:
            return
        dir_list = [(-1,0), (1,0), (0,-1), (0,1)]
        for dr, dc in dir_list:
            nr = unit.r + dr
            nc = unit.c + dc
            if 0 <= nr < MAP_ROW and 0 <= nc < MAP_COL:
                enemy_list = [u for u in self.unit_list if u.r == nr and u.c == nc and u.camp != unit.camp and u.hp > 0]
                if enemy_list:
                    self.attack_cells.add((nr, nc))

    def refresh_info(self):
        self.info_text.delete(1.0, tk.END)
        if not self.selected_unit:
            self.info_text.insert(tk.END, "未选中单位\n点击己方部队选中")
            return
        u = self.selected_unit
        camp_str = "红方" if u.camp == "red" else "蓝方"
        data = f"""阵营：{camp_str}
兵种：{SOLDIER_TYPE[u.unit_type]['name']}
生命值：{u.hp} / {u.max_hp}
攻击力：{u.atk}
移动点数：{u.move_range}
本回合已移动：{u.has_moved}
本回合已攻击：{u.has_attacked}
坐标位置：({u.r}, {u.c})"""
        self.info_text.insert(tk.END, data)

    def add_log(self, msg):
        self.battle_log.append(msg)
        self.log_box.insert(tk.END, msg + "\n")
        self.log_box.see(tk.END)
        self.root.update()

    def refresh_all(self):
        self.draw_map()
        self.draw_units()
        self.draw_highlight()
        self.refresh_info()
        self.root.update()

    def canvas_click(self, event):
        if not self.is_red_turn:
            return

        col = event.x // CELL_SIZE
        row = event.y // CELL_SIZE
        click_pos = (row, col)

        if click_pos in self.move_cells and self.selected_unit is not None:
            old_r, old_c = self.selected_unit.r, self.selected_unit.c
            self.selected_unit.r, self.selected_unit.c = row, col
            self.selected_unit.has_moved = True
            self.add_log(f"【我方移动】{SOLDIER_TYPE[self.selected_unit.unit_type]['name']} ({old_r},{old_c}) → ({row},{col})")
            self.selected_unit = None
            self.move_cells.clear()
            self.attack_cells.clear()
            self.refresh_all()
            return

        if click_pos in self.attack_cells and self.selected_unit is not None:
            target_enemy = None
            for u in self.unit_list:
                if u.r == row and u.c == col and u.camp != self.selected_unit.camp and u.hp > 0:
                    target_enemy = u
                    break
            if target_enemy:
                def_value = TERRAIN[self.map_terrain[target_enemy.r][target_enemy.c]]["def"]
                damage = max(5, self.selected_unit.atk - def_value * 8)
                target_enemy.hp -= damage
                self.selected_unit.has_attacked = True
                self.add_log(f"【我方攻击】造成 {damage} 伤害，敌方剩余HP：{target_enemy.hp}")
                if target_enemy.hp <= 0:
                    self.add_log(f"【击毁】敌方 {SOLDIER_TYPE[target_enemy.unit_type]['name']} 被消灭！")
            self.selected_unit = None
            self.move_cells.clear()
            self.attack_cells.clear()
            self.refresh_all()
            return

        select_target = None
        for unit in self.unit_list:
            if unit.r == row and unit.c == col and unit.hp > 0:
                select_target = unit
                break
        if select_target is not None and select_target.camp == "red":
            self.selected_unit = select_target
            self.calc_move_range(select_target)
            self.calc_attack_range(select_target)
        else:
            self.selected_unit = None
            self.move_cells.clear()
            self.attack_cells.clear()
        self.refresh_all()

    def ai_blue_action(self):
        self.add_log("-------- AI蓝方全军出击 --------")
        blue_units = [u for u in self.unit_list if u.camp == "blue" and u.hp > 0]
        red_units = [u for u in self.unit_list if u.camp == "red" and u.hp > 0]
        if not red_units:
            self.add_log("【游戏结束】AI蓝方全歼红方，你输了！")
            return

        for blue_unit in blue_units:
            if blue_unit.hp <= 0:
                continue

            # 优先攻击
            self.calc_attack_range(blue_unit)
            if len(self.attack_cells) > 0:
                tr, tc = list(self.attack_cells)[0]
                target = [x for x in red_units if x.r == tr and x.c == tc][0]
                def_val = TERRAIN[self.map_terrain[target.r][target.c]]["def"]
                dmg = max(5, blue_unit.atk - def_val * 8)
                target.hp -= dmg
                blue_unit.has_attacked = True
                self.add_log(f"【AI攻击】敌方{SOLDIER_TYPE[blue_unit.unit_type]['name']} 造成{dmg}伤害")
                if target.hp <= 0:
                    self.add_log(f"【我方阵亡】我方{SOLDIER_TYPE[target.unit_type]['name']}被歼灭")
                self.refresh_all()

            # 靠近敌人
            if not blue_unit.has_moved:
                self.calc_move_range(blue_unit)
                if len(self.move_cells) == 0:
                    continue
                nearest_dist = 9999
                best_pos = None
                for (mr, mc) in self.move_cells:
                    min_d = min(abs(mr - ru.r) + abs(mc - ru.c) for ru in red_units)
                    if min_d < nearest_dist:
                        nearest_dist = min_d
                        best_pos = (mr, mc)
                if best_pos:
                    old_r, old_c = blue_unit.r, blue_unit.c
                    blue_unit.r, blue_unit.c = best_pos
                    blue_unit.has_moved = True
                    self.add_log(f"【AI移动】敌方单位向前推进")
                    self.refresh_all()
        self.add_log("-------- AI蓝方行动结束 --------")

    def next_turn(self):
        for u in self.unit_list:
            u.has_moved = False
            u.has_attacked = False
        self.selected_unit = None
        self.move_cells.clear()
        self.attack_cells.clear()
        self.refresh_all()

        if self.is_red_turn:
            self.is_red_turn = False
            self.turn_label.config(text="当前回合：AI（蓝方）行动", fg="blue")
            self.refresh_all()
            self.ai_blue_action()
            self.is_red_turn = True
            self.turn_label.config(text="当前回合：玩家（红方）行动", fg="red")
            self.add_log("===== 你的回合！指挥红方大军 =====")
        self.refresh_all()

    def reset_game(self):
        self.is_red_turn = True
        self.turn_label.config(text="当前回合：玩家（红方）行动", fg="red")
        self.selected_unit = None
        self.move_cells.clear()
        self.attack_cells.clear()
        self.battle_log.clear()
        self.log_box.delete(1.0, tk.END)
        self.init_many_units()
        self.add_log("战场重置，大规模军团对战开始！")
        self.refresh_all()

    def clear_log(self):
        self.log_box.delete(1.0, tk.END)
        self.battle_log.clear()

    def cancel_step(self):
        self.selected_unit = None
        self.move_cells.clear()
        self.attack_cells.clear()
        self.refresh_all()

if __name__ == "__main__":
    root = tk.Tk()
    app = WargameGUI(root)
    root.mainloop()
