import tkinter as tk
from tkinter import messagebox
import random

class WarGame:
    def __init__(self):
        self.window = tk.Tk()
        self.window.title("战争兵棋推演")
        self.window.geometry("1400x800")
        self.window.configure(bg='#2c3e50')
        
        # 游戏状态
        self.current_turn = "player"
        self.player_gold = 500
        self.enemy_gold = 500
        self.player_units = []
        self.enemy_units = []
        self.selected_unit = None
        self.game_over = False
        
        # 地图大小
        self.map_width = 8
        self.map_height = 6
        self.cell_size = 80
        
        # 单位类型
        self.unit_types = {
            "步兵": {"health": 100, "attack": 25, "defense": 15, "range": 1, "cost": 100, "icon": "⚔️"},
            "坦克": {"health": 150, "attack": 40, "defense": 30, "range": 2, "cost": 200, "icon": "🚀"},
            "炮兵": {"health": 80, "attack": 35, "defense": 10, "range": 3, "cost": 150, "icon": "💣"},
            "侦察兵": {"health": 60, "attack": 15, "defense": 20, "range": 2, "cost": 80, "icon": "🔭"}
        }
        
        self.setup_ui()
        self.init_game()
        self.window.mainloop()
    
    def setup_ui(self):
        # 主框架
        main_frame = tk.Frame(self.window, bg='#2c3e50')
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 左侧游戏区域
        left_frame = tk.Frame(main_frame, bg='#34495e')
        left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        
        # 地图画布
        self.map_canvas = tk.Canvas(
            left_frame,
            width=self.map_width * self.cell_size,
            height=self.map_height * self.cell_size,
            bg='#27ae60',
            highlightthickness=2
        )
        self.map_canvas.pack(pady=20, padx=20)
        self.map_canvas.bind("<Button-1>", self.on_map_click)
        
        # 右侧信息面板
        right_frame = tk.Frame(main_frame, bg='#34495e', width=350)
        right_frame.pack(side=tk.RIGHT, fill=tk.Y, padx=(10, 0))
        right_frame.pack_propagate(False)
        
        # 标题
        title = tk.Label(
            right_frame,
            text="⚔️ 战争兵棋推演 ⚔️",
            font=('Arial', 22, 'bold'),
            bg='#34495e',
            fg='#f39c12'
        )
        title.pack(pady=20)
        
        # 回合信息
        self.turn_label = tk.Label(
            right_frame,
            text="回合：玩家",
            font=('Arial', 18, 'bold'),
            bg='#34495e',
            fg='#2ecc71'
        )
        self.turn_label.pack(pady=10)
        
        # 资源信息
        resource_frame = tk.Frame(right_frame, bg='#34495e')
        resource_frame.pack(pady=10)
        
        tk.Label(
            resource_frame,
            text="💰 玩家资金:",
            font=('Arial', 14),
            bg='#34495e',
            fg='white'
        ).grid(row=0, column=0, sticky='w', pady=5)
        
        self.player_gold_label = tk.Label(
            resource_frame,
            text=f"{self.player_gold}",
            font=('Arial', 16, 'bold'),
            bg='#34495e',
            fg='#f1c40f'
        )
        self.player_gold_label.grid(row=0, column=1, padx=10)
        
        tk.Label(
            resource_frame,
            text="💰 敌军资金:",
            font=('Arial', 14),
            bg='#34495e',
            fg='white'
        ).grid(row=1, column=0, sticky='w', pady=5)
        
        self.enemy_gold_label = tk.Label(
            resource_frame,
            text=f"{self.enemy_gold}",
            font=('Arial', 16, 'bold'),
            bg='#34495e',
            fg='#f1c40f'
        )
        self.enemy_gold_label.grid(row=1, column=1, padx=10)
        
        # 单位统计
        stats_frame = tk.LabelFrame(right_frame, text="单位统计", bg='#34495e', fg='white', font=('Arial', 12))
        stats_frame.pack(fill=tk.X, pady=10, padx=10)
        
        self.player_units_label = tk.Label(
            stats_frame,
            text="我军单位: 0",
            font=('Arial', 12),
            bg='#34495e',
            fg='#3498db'
        )
        self.player_units_label.pack(pady=5)
        
        self.enemy_units_label = tk.Label(
            stats_frame,
            text="敌军单位: 0",
            font=('Arial', 12),
            bg='#34495e',
            fg='#e74c3c'
        )
        self.enemy_units_label.pack(pady=5)
        
        # 招募单位区域
        recruit_frame = tk.LabelFrame(right_frame, text="招募单位 (玩家)", bg='#34495e', fg='white', font=('Arial', 12))
        recruit_frame.pack(fill=tk.X, pady=10, padx=10)
        
        for unit_type, stats in self.unit_types.items():
            btn = tk.Button(
                recruit_frame,
                text=f"{stats['icon']} {unit_type} (${stats['cost']})\n❤️{stats['health']} ⚔️{stats['attack']}",
                font=('Arial', 10),
                bg='#27ae60',
                fg='white',
                command=lambda u=unit_type: self.recruit_unit(u)
            )
            btn.pack(fill=tk.X, pady=3)
        
        # 行动按钮
        action_frame = tk.Frame(right_frame, bg='#34495e')
        action_frame.pack(pady=20)
        
        self.end_turn_btn = tk.Button(
            action_frame,
            text="结束回合",
            font=('Arial', 14, 'bold'),
            bg='#e74c3c',
            fg='white',
            padx=30,
            pady=10,
            command=self.end_turn
        )
        self.end_turn_btn.pack(pady=5)
        
        reset_btn = tk.Button(
            action_frame,
            text="重新开始",
            font=('Arial', 12, 'bold'),
            bg='#95a5a6',
            fg='white',
            padx=30,
            pady=8,
            command=self.reset_game
        )
        reset_btn.pack(pady=5)
        
        # 信息显示
        info_frame = tk.LabelFrame(right_frame, text="战斗日志", bg='#34495e', fg='white', font=('Arial', 12))
        info_frame.pack(fill=tk.BOTH, expand=True, pady=10, padx=10)
        
        self.info_text = tk.Text(
            info_frame,
            height=12,
            width=35,
            bg='#2c3e50',
            fg='#ecf0f1',
            font=('Arial', 10)
        )
        self.info_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        self.add_info("🎮 游戏开始！玩家先行动")
        self.add_info("💡 点击单位选中，再点击格子移动或攻击")
    
    def init_game(self):
        """初始化游戏"""
        self.player_units.clear()
        self.enemy_units.clear()
        
        # 玩家初始单位
        self.player_units.append(Unit("步兵", 1, 1, "player", self.unit_types))
        self.player_units.append(Unit("坦克", 2, 2, "player", self.unit_types))
        self.player_units.append(Unit("步兵", 1, 2, "player", self.unit_types))
        
        # 敌军初始单位
        self.enemy_units.append(Unit("步兵", 6, 4, "enemy", self.unit_types))
        self.enemy_units.append(Unit("步兵", 5, 3, "enemy", self.unit_types))
        self.enemy_units.append(Unit("侦察兵", 6, 3, "enemy", self.unit_types))
        
        self.draw_map()
        self.update_stats()
    
    def draw_map(self):
        """绘制地图"""
        self.map_canvas.delete("all")
        
        # 绘制网格
        for i in range(self.map_height):
            for j in range(self.map_width):
                x1 = j * self.cell_size
                y1 = i * self.cell_size
                x2 = x1 + self.cell_size
                y2 = y1 + self.cell_size
                color = '#87CEEB' if (i + j) % 2 == 0 else '#6CA6CD'
                self.map_canvas.create_rectangle(x1, y1, x2, y2, fill=color, outline='black', width=2)
        
        # 绘制玩家单位
        for unit in self.player_units:
            if unit.health > 0:
                self.draw_unit(unit, '#3498db')
        
        # 绘制敌军单位
        for unit in self.enemy_units:
            if unit.health > 0:
                self.draw_unit(unit, '#e74c3c')
        
        # 高亮选中的单位
        if self.selected_unit and self.selected_unit.health > 0:
            x = self.selected_unit.x * self.cell_size
            y = self.selected_unit.y * self.cell_size
            self.map_canvas.create_rectangle(
                x, y, x + self.cell_size, y + self.cell_size,
                outline='yellow', width=3
            )
            # 显示可移动/攻击范围
            for dx in range(-self.selected_unit.range, self.selected_unit.range + 1):
                for dy in range(-self.selected_unit.range, self.selected_unit.range + 1):
                    nx = self.selected_unit.x + dx
                    ny = self.selected_unit.y + dy
                    if 0 <= nx < self.map_width and 0 <= ny < self.map_height:
                        if abs(dx) + abs(dy) <= self.selected_unit.range:
                            self.map_canvas.create_rectangle(
                                nx * self.cell_size, ny * self.cell_size,
                                (nx + 1) * self.cell_size, (ny + 1) * self.cell_size,
                                outline='#f39c12', width=2
                            )
    
    def draw_unit(self, unit, color):
        x = unit.x * self.cell_size
        y = unit.y * self.cell_size
        self.map_canvas.create_oval(
            x + 5, y + 5, x + self.cell_size - 5, y + self.cell_size - 5,
            fill=color, outline='white', width=2
        )
        self.map_canvas.create_text(
            x + self.cell_size // 2, y + self.cell_size // 2 - 8,
            text=unit.icon, font=('Arial', 28)
        )
        # 血量条
        health_percent = unit.health / unit.max_health
        bar_width = self.cell_size - 20
        bar_height = 8
        bar_x = x + 10
        bar_y = y + self.cell_size - 15
        self.map_canvas.create_rectangle(bar_x, bar_y, bar_x + bar_width, bar_y + bar_height, fill='#e74c3c', outline='black')
        self.map_canvas.create_rectangle(bar_x, bar_y, bar_x + bar_width * health_percent, bar_y + bar_height, fill='#2ecc71', outline='black')
        self.map_canvas.create_text(
            x + self.cell_size // 2, y + self.cell_size - 8,
            text=f"{unit.name} {unit.health}/{unit.max_health}",
            font=('Arial', 8, 'bold'), fill='white'
        )
    
    def on_map_click(self, event):
        if self.game_over:
            return
        x = event.x // self.cell_size
        y = event.y // self.cell_size
        if not (0 <= x < self.map_width and 0 <= y < self.map_height):
            return
        
        my_units = self.player_units if self.current_turn == "player" else self.enemy_units
        clicked_unit = None
        for unit in my_units:
            if unit.health > 0 and unit.x == x and unit.y == y:
                clicked_unit = unit
                break
        
        if clicked_unit:
            self.selected_unit = clicked_unit
            self.draw_map()
            self.add_info(f"选中 {clicked_unit.name} (❤️{clicked_unit.health}/{clicked_unit.max_health})")
        elif self.selected_unit and self.selected_unit.health > 0:
            self.move_or_attack(x, y)
        else:
            self.selected_unit = None
            self.draw_map()
    
    def move_or_attack(self, target_x, target_y):
        if not self.selected_unit or self.selected_unit.health <= 0:
            return
        distance = abs(self.selected_unit.x - target_x) + abs(self.selected_unit.y - target_y)
        if distance == 0:
            self.selected_unit = None
            self.draw_map()
            return
        
        enemies = self.enemy_units if self.current_turn == "player" else self.player_units
        target_unit = None
        for unit in enemies:
            if unit.health > 0 and unit.x == target_x and unit.y == target_y:
                target_unit = unit
                break
        
        if target_unit:
            if distance <= self.selected_unit.range:
                self.attack(self.selected_unit, target_unit)
                self.selected_unit = None
                self.draw_map()
                self.check_game_over()
                # 如果是敌方攻击后没有结束游戏，继续敌方回合（但注意AI是一次性行动多个单位，不需要额外调用）
                # 为防止重复调用，这里不做额外操作，因为AI是在end_turn后统一执行的。
                # 但为了响应式，玩家攻击后正常。
            else:
                self.add_info(f"距离太远！需要{self.selected_unit.range}格以内")
        elif distance <= self.selected_unit.range:
            # 检查目标位置是否空闲
            occupied = False
            all_units = self.player_units + self.enemy_units
            for unit in all_units:
                if unit.health > 0 and unit.x == target_x and unit.y == target_y:
                    occupied = True
                    break
            if not occupied:
                self.selected_unit.x = target_x
                self.selected_unit.y = target_y
                self.add_info(f"{self.selected_unit.name} 移动到 ({target_x}, {target_y})")
                self.selected_unit = None
                self.draw_map()
            else:
                self.add_info("目标位置被占据！")
        else:
            self.add_info(f"超出范围！最大{self.selected_unit.range}格")
    
    def attack(self, attacker, defender):
        damage = max(5, attacker.attack + random.randint(-5, 15) - defender.defense // 2)
        defender.health -= damage
        self.add_info(f"⚔️ {attacker.name} 攻击 {defender.name} 造成 {damage} 伤害!")
        if defender.health <= 0:
            defender.health = 0
            self.add_info(f"💀 {defender.name} 被消灭！")
            reward = self.unit_types[defender.name]["cost"] // 2
            if self.current_turn == "player":
                self.player_gold += reward
                self.add_info(f"💰 获得 {reward} 金币奖励！")
            else:
                self.enemy_gold += reward
            self.update_stats()
    
    def recruit_unit(self, unit_type):
        if self.game_over or self.current_turn != "player":
            self.add_info("只能在你的回合招募单位！")
            return
        cost = self.unit_types[unit_type]["cost"]
        if self.player_gold >= cost:
            for y in range(self.map_height):
                for x in range(self.map_width):
                    if x < 4:
                        occupied = False
                        for unit in self.player_units + self.enemy_units:
                            if unit.health > 0 and unit.x == x and unit.y == y:
                                occupied = True
                                break
                        if not occupied:
                            new_unit = Unit(unit_type, x, y, "player", self.unit_types)
                            self.player_units.append(new_unit)
                            self.player_gold -= cost
                            self.add_info(f"🎖️ 招募 {unit_type} 在 ({x}, {y}) 花费 {cost}金币")
                            self.update_stats()
                            self.draw_map()
                            return
            self.add_info("没有空闲位置招募新单位！")
        else:
            self.add_info(f"资金不足！需要{cost}金币，当前{self.player_gold}")
    
    def end_turn(self):
        if self.game_over:
            return
        if self.current_turn == "player":
            self.current_turn = "enemy"
            self.turn_label.config(text="回合：敌军", fg='#e74c3c')
            self.add_info("🤖 敌军回合")
            self.selected_unit = None
            self.draw_map()
            self.window.after(500, self.enemy_turn)
        else:
            self.current_turn = "player"
            self.turn_label.config(text="回合：玩家", fg='#2ecc71')
            self.add_info("👤 玩家回合")
            self.player_gold += 50
            self.update_stats()
            self.selected_unit = None
            self.draw_map()
    
    def enemy_turn(self):
        """AI回合 - 增强招募逻辑"""
        if self.current_turn != "enemy" or self.game_over:
            return
        
        # 1. 敌军尝试招募（只要有钱就招募，尽量保持单位数量）
        # 统计当前幸存敌军数量
        alive_enemies = [u for u in self.enemy_units if u.health > 0]
        # 如果单位少于6个且资金充足，尝试招募
        if len(alive_enemies) < 6 and self.enemy_gold >= 80:
            # 按成本排序，优先招募便宜的
            affordable = [(name, stats) for name, stats in self.unit_types.items() if self.enemy_gold >= stats["cost"]]
            if affordable:
                # 随机选择一种可招募单位
                unit_name, stats = random.choice(affordable)
                # 寻找空闲位置（右侧区域 x>3）
                placed = False
                for y in range(self.map_height):
                    for x in range(self.map_width-1, -1, -1):
                        if x > 3:
                            occupied = False
                            for u in self.player_units + self.enemy_units:
                                if u.health > 0 and u.x == x and u.y == y:
                                    occupied = True
                                    break
                            if not occupied:
                                new_unit = Unit(unit_name, x, y, "enemy", self.unit_types)
                                self.enemy_units.append(new_unit)
                                self.enemy_gold -= stats["cost"]
                                self.add_info(f"敌军招募了 {unit_name} 在 ({x},{y})")
                                self.draw_map()
                                placed = True
                                break
                    if placed:
                        break
                if not placed:
                    self.add_info("敌军尝试招募但没有空位")
        
        # 2. AI移动和攻击
        for unit in self.enemy_units[:]:
            if unit.health <= 0:
                continue
            # 找最近的玩家单位
            closest = None
            min_dist = float('inf')
            for target in self.player_units:
                if target.health > 0:
                    dist = abs(unit.x - target.x) + abs(unit.y - target.y)
                    if dist < min_dist:
                        min_dist = dist
                        closest = target
            if closest:
                if min_dist <= unit.range:
                    self.attack(unit, closest)
                    self.draw_map()
                    self.window.update()
                    self.window.after(300)
                    if self.check_game_over():
                        return
                elif min_dist > 1:
                    # 移动向敌人
                    dx = 0
                    dy = 0
                    if closest.x > unit.x:
                        dx = 1
                    elif closest.x < unit.x:
                        dx = -1
                    elif closest.y > unit.y:
                        dy = 1
                    elif closest.y < unit.y:
                        dy = -1
                    if dx != 0:
                        new_x = unit.x + dx
                        if 0 <= new_x < self.map_width:
                            occupied = False
                            for u in self.player_units + self.enemy_units:
                                if u.health > 0 and u.x == new_x and u.y == unit.y:
                                    occupied = True
                                    break
                            if not occupied:
                                unit.x = new_x
                    elif dy != 0:
                        new_y = unit.y + dy
                        if 0 <= new_y < self.map_height:
                            occupied = False
                            for u in self.player_units + self.enemy_units:
                                if u.health > 0 and u.x == unit.x and u.y == new_y:
                                    occupied = True
                                    break
                            if not occupied:
                                unit.y = new_y
                    self.draw_map()
                    self.window.update()
                    self.window.after(200)
        
        # 3. 敌军获得资金
        self.enemy_gold += 50
        self.update_stats()
        # 结束AI回合
        self.end_turn()
    
    def check_game_over(self):
        player_alive = any(u.health > 0 for u in self.player_units)
        enemy_alive = any(u.health > 0 for u in self.enemy_units)
        if not player_alive:
            self.game_over = True
            messagebox.showinfo("游戏结束", "💀 游戏结束！敌军胜利！ 💀")
            self.add_info("💀 游戏结束！玩家失败 💀")
            return True
        elif not enemy_alive:
            self.game_over = True
            messagebox.showinfo("游戏胜利", "🎉 恭喜！你赢得了战争！ 🎉")
            self.add_info("🎉 胜利！敌方全军覆没 🎉")
            return True
        return False
    
    def update_stats(self):
        self.player_gold_label.config(text=f"{self.player_gold}")
        self.enemy_gold_label.config(text=f"{self.enemy_gold}")
        player_count = sum(1 for u in self.player_units if u.health > 0)
        enemy_count = sum(1 for u in self.enemy_units if u.health > 0)
        self.player_units_label.config(text=f"我军单位: {player_count}")
        self.enemy_units_label.config(text=f"敌军单位: {enemy_count}")
    
    def add_info(self, message):
        self.info_text.insert(1.0, f"{message}\n")
        if float(self.info_text.index('end')) > 20.0:
            self.info_text.delete('20.0', 'end')
    
    def reset_game(self):
        self.current_turn = "player"
        self.player_gold = 500
        self.enemy_gold = 500
        self.selected_unit = None
        self.game_over = False
        self.turn_label.config(text="回合：玩家", fg='#2ecc71')
        self.init_game()
        self.update_stats()
        self.add_info("\n" + "="*30)
        self.add_info("🎮 游戏重新开始！")
        self.draw_map()

class Unit:
    def __init__(self, unit_type, x, y, owner, unit_types):
        self.name = unit_type
        self.x = x
        self.y = y
        self.owner = owner
        self.max_health = unit_types[unit_type]["health"]
        self.health = self.max_health
        self.attack = unit_types[unit_type]["attack"]
        self.defense = unit_types[unit_type]["defense"]
        self.range = unit_types[unit_type]["range"]
        self.icon = unit_types[unit_type]["icon"]

if __name__ == "__main__":
    print("战争兵棋推演启动 - 敌人现在会主动招募单位了！")
    game = WarGame()