def line_intersects_rect(self, x1, y1, x2, y2, rx1, ry1, rx2, ry2):
        # 检查线段是否与矩形相交
        def ccw(A, B, C):
            return (C[1]-A[1]) * (B[0]-A[0]) > (B[1]-A[1]) * (C[0]-A[0])
        
        def intersect(A, B, C, D):
            return ccw(A, C, D) != ccw(B, C, D) and ccw(A, B, C) != ccw(A, B, D)
        
        # 矩形的四条边
        edges = [
            ((rx1, ry1), (rx2, ry1)),  # 上边
            ((rx2, ry1), (rx2, ry2)),  # 右边
            ((rx2, ry2), (rx1, ry2)),  # 下边
            ((rx1, ry2), (rx1, ry1))   # 左边
        ]
        
        for edge in edges:
            if intersect((x1, y1), (x2, y2), edge[0], edge[1]):
                return True
        
        # 检查线段是否完全在矩形内
        if rx1 <= x1 <= rx2 and ry1 <= y1 <= ry2 and rx1 <= x2 <= rx2 and ry1 <= y2 <= ry2:
            return True
            
        return False
    
    def line_rect_intersection(self, x1, y1, x2, y2, rx1, ry1, rx2, ry2):
        # 计算线段与矩形的交点
        def line_intersection(line1, line2):
            xdiff = (line1[0][0] - line1[1][0], line2[0][0] - line2[1][0])
            ydiff = (line1[0][1] - line1[1][1], line2[0][1] - line2[1][1])
            
            def det(a, b):
                return a[0] * b[1] - a[1] * b[0]
            
            div = det(xdiff, ydiff)
            if div == 0:
                return None
            
            d = (det(*line1), det(*line2))
            x = det(d, xdiff) / div
            y = det(d, ydiff) / div
            return x, y
        
        # 矩形的四条边
        edges = [
            ((rx1, ry1), (rx2, ry1)),  # 上边
            ((rx2, ry1), (rx2, ry2)),  # 右边
            ((rx2, ry2), (rx1, ry2)),  # 下边
            ((rx1, ry2), (rx1, ry1))   # 左边
        ]
        
        intersections = []
        line = ((x1, y1), (x2, y2))
        
        for edge in edges:
            intersection = line_intersection(line, edge)
            if intersection:
                # 检查交点是否在线段上
                if min(x1, x2) <= intersection[0] <= max(x1, x2) and \
                   min(y1, y2) <= intersection[1] <= max(y1, y2):
                    intersections.append(intersection)
        
        # 返回最近的交点
        if intersections:
            return min(intersections, key=lambda p: ((p[0] - x1)**2 + (p[1] - y1)**2))
        
        return None
    
    def find_nearest_enemy(self, unit, enemies):
        # 查找最近的敌人
        nearest = None
        min_dist = float('inf')
        
        for enemy in enemies:
            if enemy["health"] > 0:
                dist = self.distance(unit, enemy)
                if dist < min_dist:
                    min_dist = dist
                    nearest = enemy
        
        return nearest
    
    def find_best_cover(self, unit, enemy):
        # 寻找最佳掩体
        best_cover = None
        best_distance = float('inf')
        
        # 计算敌人方向
        angle = math.atan2(enemy["y"] - unit["y"], enemy["x"] - unit["x"])
        
        # 寻找距离敌人最远的掩体
        for cover in unit["cover_points"]:
            # 计算掩体到敌人的距离
            cover_to_enemy = math.sqrt((cover[0] - enemy["x"])**2 + (cover[1] - enemy["y"])**2)
            
            # 计算掩体到单位的距离
            cover_to_unit = math.sqrt((cover[0] - unit["x"])**2 + (cover[1] - unit["y"])**2)
            
            # 检查掩体是否在敌人视线范围内
            if cover_to_unit < 150 and cover_to_enemy > 100:
                # 检查掩体是否提供遮挡
                if not self.has_line_of_sight({"x": cover[0], "y": cover[1]}, enemy):
                    if cover_to_enemy > best_distance:
                        best_distance = cover_to_enemy
                        best_cover = cover
        
        return best_cover
    
    def astar(self, start, goal):
        # A*寻路算法
        def heuristic(a, b):
            # 曼哈顿距离
            return abs(a[0] - b[0]) + abs(a[1] - b[1])
        
        # 网格大小
        grid_size = 10
        
        # 起点和终点的网格坐标
        start_grid = (int(start[0] / grid_size), int(start[1] / grid_size))
        goal_grid = (int(goal[0] / grid_size), int(goal[1] / grid_size))
        
        # 定义网格边界
        grid_width = 1024 // grid_size
        grid_height = 668 // grid_size
        
        # 初始化开放列表和关闭列表
        open_set = {start_grid}
        closed_set = set()
        
        # 记录从起点到当前点的实际代价
        g_score = {start_grid: 0}
        
        # 记录从起点到终点的估计代价
        f_score = {start_grid: heuristic(start_grid, goal_grid)}
        
        # 记录路径
        came_from = {}
        
        # 八个方向的移动
        directions = [(0, 1), (1, 0), (0, -1), (-1, 0), (1, 1), (-1, 1), (1, -1), (-1, -1)]
        
        while open_set:
            # 找到f值最小的节点
            current = min(open_set, key=lambda node: f_score.get(node, float('inf')))
            
            # 如果到达终点,构建路径
            if current == goal_grid:
                path = []
                while current in came_from:
                    path.append((current[0] * grid_size, current[1] * grid_size))
                    current = came_from[current]
                path.append(start)
                path.reverse()
                return path
            
            # 将当前节点从开放列表移到关闭列表
            open_set.remove(current)
            closed_set.add(current)
            
            # 检查所有相邻节点
            for dx, dy in directions:
                neighbor = (current[0] + dx, current[1] + dy)
                
                # 检查边界
                if not (0 <= neighbor[0] < grid_width and 0 <= neighbor[1] < grid_height):
                    continue
                
                # 检查障碍物
                real_pos = (neighbor[0] * grid_size, neighbor[1] * grid_size)
                if self.is_in_obstacle(real_pos[0], real_pos[1]):
                    continue
                
                # 如果在关闭列表中,跳过
                if neighbor in closed_set:
                    continue
                
                # 计算从起点到相邻节点的代价
                tentative_g_score = g_score[current] + (14 if dx != 0 and dy != 0 else 10)
                
                # 如果是新节点或找到了更好的路径
                if neighbor not in open_set or tentative_g_score < g_score.get(neighbor, float('inf')):
                    # 记录路径
                    came_from[neighbor] = current
                    
                    # 更新代价
                    g_score[neighbor] = tentative_g_score
                    f_score[neighbor] = tentative_g_score + heuristic(neighbor, goal_grid)
                    
                    # 将相邻节点加入开放列表
                    open_set.add(neighbor)
        
        # 如果没有找到路径,返回直接前往目标的路径
        return [start, goal]
    
    def follow_path(self, unit):
        if unit["path"] and len(unit["path"]) > 1:
            # 获取下一个路径点
            next_point = unit["path"][1]
            
            # 计算移动方向
            dx = next_point[0] - unit["x"]
            dy = next_point[1] - unit["y"]
            distance = math.sqrt(dx*dx + dy*dy)
            
            if distance > 5:  # 如果距离大于5,移动
                # 归一化方向向量
                dx /= distance
                dy /= distance
                
                # 移动速度
                speed = 3
                
                # 移动单位
                unit["x"] += dx * speed
                unit["y"] += dy * speed
                
                # 更新画布位置
                self.canvas.coords(unit["canvas_obj"], 
                                  unit["x"] - 10, unit["y"] - 10, 
                                  unit["x"] + 10, unit["y"] + 10)
                self.canvas.coords(unit["canvas_text"], unit["x"], unit["y"])
                
                if not unit["is_player"]:
                    self.canvas.coords(unit["state_indicator"], unit["x"], unit["y"] - 20)
                    self.canvas.coords(unit["behavior_indicator"], unit["x"], unit["y"])
                else:
                    # 更新玩家朝向指示器
                    self.canvas.coords(
                        unit["direction_line"],
                        unit["x"], unit["y"],
                        unit["x"] + math.cos(unit["direction"]) * 20,
                        unit["y"] + math.sin(unit["direction"]) * 20
                    )
            else:
                # 已到达下一个路径点,移除它
                unit["path"].pop(1)
    
    def update_player_position(self):
        if not self.game_active:
            return
            
        # 获取玩家
        player = self.defenders[0] if self.defender_turn else self.attackers[0]
        
        # 计算移动方向
        dx = 0
        dy = 0
        
        if self.key_pressed["w"]:
            dy -= self.player_speed
        if self.key_pressed["s"]:
            dy += self.player_speed
        if self.key_pressed["a"]:
            dx -= self.player_speed
        if self.key_pressed["d"]:
            dx += self.player_speed
        
        # 检查移动是否会碰到障碍物
        new_x = player["x"] + dx
        new_y = player["y"] + dy
        
        if not self.is_in_obstacle(new_x, new_y):
            # 更新玩家位置
            player["x"] = new_x
            player["y"] = new_y
            
            # 更新画布位置
            self.canvas.coords(player["canvas_obj"], 
                              player["x"] - 15, player["y"] - 15, 
                              player["x"] + 15, player["y"] + 15)
            self.canvas.coords(player["canvas_text"], player["x"], player["y"])
            
            # 更新玩家朝向指示器
            self.canvas.coords(
                player["direction_line"],
                player["x"], player["y"],
                player["x"] + math.cos(player["direction"]) * 20,
                player["y"] + math.sin(player["direction"]) * 20
            )
            
            # 更新玩家记忆中的位置
            if (player["x"], player["y"]) not in player["memory"]["visited_positions"]:
                player["memory"]["visited_positions"].append((player["x"], player["y"]))
                
                # 限制记忆大小
                if len(player["memory"]["visited_positions"]) > 20:
                    player["memory"]["visited_positions"].pop(0)
        
        # 检查是否触发陷阱
        for trap in self.defense_objects[:]:
            if trap["type"] == "trap" and not trap["triggered"]:
                if self.distance(player, trap) < trap["trigger_radius"]:
                    self.trigger_trap(trap, player)
        
        # 检查是否可以拆除拆弹器(防守方)
        if self.defender_turn and self.bomb_planted and self.distance(player, self.defuser) < 30:
            self.defend_defuser()
        
        # 检查是否可以放置炸弹(进攻方)
        if not self.defender_turn and not self.bomb_planted:
            if self.distance(player, self.bomb_site) < self.bomb_site["radius"]:
                # 显示放置炸弹提示
                pass
        
        # 每帧更新
        self.root.after(16, self.update_player_position)
    
    def update_ai_memory(self, unit):
        # 更新AI记忆中的位置
        if (unit["x"], unit["y"]) not in unit["memory"]["visited_positions"]:
            unit["memory"]["visited_positions"].append((unit["x"], unit["y"]))
            
            # 限制记忆大小
            if len(unit["memory"]["visited_positions"]) > 20:
                unit["memory"]["visited_positions"].pop(0)
        
        # 更新记忆中的陷阱位置
        for trap in self.defense_objects:
            if trap["type"] == "trap":
                trap_pos = (trap["x"], trap["y"])
                if trap_pos not in unit["memory"]["trap_positions"]:
                    unit["memory"]["trap_positions"].append(trap_pos)
                    
                    # 限制记忆大小
                    if len(unit["memory"]["trap_positions"]) > 15:
                        unit["memory"]["trap_positions"].pop(0)
        
        # 更新记忆中的敌人位置
        enemies = self.attackers if unit["role"] == "defender" else self.defenders
        for enemy in enemies:
            if enemy["health"] > 0:
                enemy_pos = (enemy["x"], enemy["y"])
                if enemy_pos not in unit["memory"]["enemy_positions"]:
                    unit["memory"]["enemy_positions"].append(enemy_pos)
                    
                    # 限制记忆大小
                    if len(unit["memory"]["enemy_positions"]) > 15:
                        unit["memory"]["enemy_positions"].pop(0)
    
    def avoid_traps(self, unit):
        # 检查记忆中的陷阱位置并避开
        if unit["memory"]["trap_positions"] and random.random() < 0.7:
            # 检查是否靠近陷阱
            for trap_pos in unit["memory"]["trap_positions"]:
                trap = {"x": trap_pos[0], "y": trap_pos[1]}
                if self.distance(unit, trap) < 50:
                    # 避开陷阱
                    avoid_dir_x = unit["x"] - trap["x"]
                    avoid_dir_y = unit["y"] - trap["y"]
                    distance = math.sqrt(avoid_dir_x*avoid_dir_x + avoid_dir_y*avoid_dir_y)
                    
                    if distance > 0:
                        # 归一化方向向量
                        avoid_dir_x /= distance
                        avoid_dir_y /= distance
                        
                        # 寻找避开陷阱的位置
                        safe_x = unit["x"] + avoid_dir_x * 100
                        safe_y = unit["y"] + avoid_dir_y * 100
                        
                        # 确保安全位置不在障碍物内
                        if not self.is_in_obstacle(safe_x, safe_y):
                            # 生成新路径
                            unit["path"] = self.astar((unit["x"], unit["y"]), (safe_x, safe_y))
                            break
    
    def check_trap_trigger(self, defender):
        # 检查是否可以主动触发陷阱
        for trap in self.defense_objects:
            if trap["type"] == "trap" and not trap["triggered"]:
                # 检查是否有敌人靠近陷阱
                for attacker in self.attackers:
                    if attacker["health"] > 0 and self.distance(attacker, trap) < trap["trigger_radius"]:
                        # 有敌人靠近,触发陷阱
                        self.trigger_trap(trap, attacker)
                        break
    
    def trigger_trap(self, trap, target):
        # 触发陷阱
        trap["triggered"] = True
        
        # 造成伤害
        target["health"] -= trap["damage"]
        
        # 显示爆炸效果
        explosion = self.canvas.create_oval(
            trap["x"] - trap["trigger_radius"], trap["y"] - trap["trigger_radius"],
            trap["x"] + trap["trigger_radius"], trap["y"] + trap["trigger_radius"],
            fill="orange", outline="red"
        )
        
        # 显示伤害数字
        damage_text = self.canvas.create_text(
            target["x"], target["y"] - 20,
            text=f"-{trap['damage']}",
            fill="red",
            font=(self.font_family, 12, "bold")
        )
        
        # 短暂显示爆炸效果后删除
        self.root.after(500, lambda: self.canvas.delete(explosion))
        self.root.after(1000, lambda: self.canvas.delete(damage_text))
        
        # 检查目标是否死亡
        if target["health"] <= 0:
            # 从画布上删除目标
            self.canvas.delete(target["canvas_obj"])
            self.canvas.delete(target["canvas_text"])
            
            if not target["is_player"]:
                self.canvas.delete(target["state_indicator"])
                self.canvas.delete(target["behavior_indicator"])
            else:
                self.canvas.delete(target["direction_line"])
        
        # 从防御设施列表中删除陷阱
        self.defense_objects.remove(trap)
    
    def ai_behavior_pattern(self, unit):
        # 根据AI行为模式调整行动
        unit["behavior_timer"] += 1
        
        # 每100帧(约1.6秒)随机改变行为
        if unit["behavior_timer"] > 100:
            unit["behavior_timer"] = 0
            
            # 随机行为
            if random.random() < 0.3:  # 30%的概率改变当前行为
                if unit["role"] == "defender":
                    # 防守方行为模式
                    patterns = ["aggressive", "defensive", "ambush", "support"]
                    unit["behavior_pattern"] = random.choice(patterns)
                else:
                    # 进攻方行为模式
                    patterns = ["aggressive", "cautious", "flank", "support"]
                    unit["behavior_pattern"] = random.choice(patterns)
        
        # 根据行为模式调整行为
        if unit["role"] == "defender":
            if unit["behavior_pattern"] == "aggressive":
                # 激进型:主动寻找敌人并攻击
                if unit["state"] == "patrol" and random.random() < 0.5:
                    # 随机选择一个可能的敌人位置
                    if unit["memory"]["enemy_positions"]:
                        target_pos = random.choice(unit["memory"]["enemy_positions"])
                        unit["path"] = self.astar((unit["x"], unit["y"]), target_pos)
            elif unit["behavior_pattern"] == "defensive":
                # 防御型:坚守炸弹点
                if unit["state"] == "patrol" and random.random() < 0.5:
                    unit["path"] = self.astar((unit["x"], unit["y"]), 
                                           (self.bomb_site["x"], self.bomb_site["y"]))
            elif unit["behavior_pattern"] == "ambush":
                # 埋伏型:寻找好的埋伏点
                if unit["state"] == "patrol" and random.random() < 0.5:
                    # 寻找可能的埋伏点
                    ambush_points = []
                    for cover in unit["cover_points"]:
                        # 检查是否是好的埋伏点
                        ambush_point = {"x": cover[0], "y": cover[1]}
                        if self.distance(ambush_point, self.bomb_site) < 200:
                            ambush_points.append(cover)
                    
                    if ambush_points:
                        target_pos = random.choice(ambush_points)
                        unit["path"] = self.astar((unit["x"], unit["y"]), target_pos)
            elif unit["behavior_pattern"] == "support":
                # 支援型:跟随队友
                if unit["state"] == "patrol" and random.random() < 0.5:
                    # 寻找最近的队友
                    nearest_teammate = None
                    min_dist = float('inf')
                    
                    for teammate in self.defenders:
                        if teammate != unit and teammate["health"] > 0:
                            dist = self.distance(unit, teammate)
                            if dist < min_dist:
                                min_dist = dist
                                nearest_teammate = teammate
                    
                    if nearest_teammate and min_dist > 100:
                        unit["path"] = self.astar((unit["x"], unit["y"]), 
                                               (nearest_teammate["x"], nearest_teammate["y"]))
        else:  # 进攻方
            if unit["behavior_pattern"] == "aggressive":
                # 激进型:直接冲向炸弹点
                if unit["state"] == "patrol" and random.random() < 0.5:
                    unit["path"] = self.astar((unit["x"], unit["y"]), 
                                           (self.bomb_site["x"], self.bomb_site["y"]))
            elif unit["behavior_pattern"] == "cautious":
                # 谨慎型:缓慢推进,寻找掩体
                if unit["state"] == "patrol" and random.random() < 0.5:
                    # 寻找靠近炸弹点的掩体
                    cover_points = []
                    for cover in unit["cover_points"]:
                        cover_pos = {"x": cover[0], "y": cover[1]}
                        if self.distance(cover_pos, self.bomb_site) < 300:
                            cover_points.append(cover)
                    
                    if cover_points:
                        target_pos = random.choice(cover_points)
                        unit["path"] = self.astar((unit["x"], unit["y"]), target_pos)
            elif unit["behavior_pattern"] == "flank":
                # 包抄型:从侧面接近炸弹点
                if unit["state"] == "patrol" and random.random() < 0.5:
                    # 计算从侧面接近的位置
                    bomb_x, bomb_y = self.bomb_site["x"], self.bomb_site["y"]
                    side_offset = random.choice([-150, 150])
                    
                    # 随机选择左侧或右侧
                    if random.choice([True, False]):
                        target_x = bomb_x + side_offset
                        target_y = bomb_y
                    else:
                        target_x = bomb_x
                        target_y = bomb_y + side_offset
                    
                    unit["path"] = self.astar((unit["x"], unit["y"]), (target_x, target_y))
            elif unit["behavior_pattern"] == "support":
                # 支援型:跟随携带炸弹的队友
                if unit["state"] == "patrol" and random.random() < 0.5:
                    # 寻找最近的队友
                    nearest_teammate = None
                    min_dist = float('inf')
                    
                    for teammate in self.attackers:
                        if teammate != unit and teammate["health"] > 0:
                            dist = self.distance(unit, teammate)
                            if dist < min_dist:
                                min_dist = dist
                                nearest_teammate = teammate
                    
                    if nearest_teammate and min_dist > 100:
                        unit["path"] = self.astar((unit["x"], unit["y"]), 
                                               (nearest_teammate["x"], nearest_teammate["y"]))

    def start_game(self):
        # 开始游戏
        self.create_game_screen()
        self.initialize_defenders()
        self.initialize_attackers()
        self.start_attack_phase()
        self.setup_player_controls()
        self.update_player_position()

if __name__ == "__main__":
    root = tk.Tk()
    game = Game(root)
    root.mainloop()