import pygame
import random
import sys
from pygame.locals import *

# 初始化pygame
pygame.init()

# 游戏窗口设置
WINDOW_WIDTH = 1200
WINDOW_HEIGHT = 750  # 增加窗口高度以显示更多内容
GRID_SIZE = 80
GRID_WIDTH = 9
GRID_HEIGHT = 5
SIDEBAR_WIDTH = 220  # 增加侧边栏宽度

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREEN = (0, 150, 0)
LIGHT_GREEN = (100, 200, 100)
YELLOW = (255, 255, 0)
RED = (255, 0, 0)
BROWN = (139, 69, 19)
SKY_BLUE = (135, 206, 235)
DARK_GREEN = (0, 100, 0)
GRAY = (128, 128, 128)
LIGHT_BROWN = (181, 101, 29)
SUN_YELLOW = (255, 223, 0)
LAWNMOWER_RED = (200, 0, 0)
LAWNMOWER_BLUE = (0, 100, 200)
LAWNMOWER_GREEN = (0, 150, 0)
LAWNMOWER_YELLOW = (220, 200, 0)
LAWNMOWER_PURPLE = (150, 0, 200)
ICE_BLUE = (100, 200, 255)
PURPLE = (128, 0, 128)
ORANGE = (255, 165, 0)
SHOVEL_BROWN = (101, 67, 33)
DARK_GRAY = (50, 50, 50)
LIGHT_GRAY = (200, 200, 200)

# 创建游戏窗口
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("植物大战僵尸增强版 - 带铲子、关卡和新植物")
clock = pygame.time.Clock()

# 字体
try:
    font = pygame.font.SysFont("simhei", 20)  # 减小字体大小
    title_font = pygame.font.SysFont("simhei", 32, bold=True)  # 减小标题字体
    small_font = pygame.font.SysFont("simhei", 16)  # 更小的字体
except:
    # 如果上面的字体不可用，使用默认字体
    font = pygame.font.Font(None, 24)
    title_font = pygame.font.Font(None, 30)
    small_font = pygame.font.Font(None, 18)

class LawnMower:
    def __init__(self, row, color):
        self.row = row
        self.x = 0
        self.y = row * GRID_SIZE + 50
        self.color = color
        self.width = GRID_SIZE
        self.height = GRID_SIZE
        self.activated = False
        self.speed = 5
        self.rect = pygame.Rect(self.x, self.y, self.width, self.height)
        
    def draw(self, surface):
        if not self.activated:
            # 绘制静止的小推车
            pygame.draw.rect(surface, self.color, self.rect, 0, 5)
            pygame.draw.circle(surface, BLACK, (self.x + 20, self.y + 60), 10)
            pygame.draw.circle(surface, BLACK, (self.x + 60, self.y + 60), 10)
            pygame.draw.rect(surface, (100, 100, 100), (self.x + 70, self.y + 10, 10, 30), 0, 3)
            pygame.draw.rect(surface, (200, 200, 200), (self.x + 10, self.y + 30, 60, 10))
            label = small_font.render(str(self.row+1), True, WHITE)
            surface.blit(label, (self.x + 35, self.y + 10))
        else:
            # 绘制移动的小推车
            pygame.draw.rect(surface, self.color, self.rect, 0, 5)
            pygame.draw.circle(surface, BLACK, (self.x + 20, self.y + 60), 10)
            pygame.draw.circle(surface, BLACK, (self.x + 60, self.y + 60), 10)
            pygame.draw.rect(surface, (100, 100, 100), (self.x + 70, self.y + 10, 10, 30), 0, 3)
            pygame.draw.rect(surface, (200, 200, 200), (self.x + 10, self.y + 30, 60, 10))
            pygame.draw.rect(surface, (255, 255, 0, 150), 
                            (self.x - 20, self.y + 20, 20, 40), 0, 5)
    
    def update(self, game):
        if self.activated:
            self.x += self.speed
            self.rect.x = self.x
            
            for zombie in game.zombies[:]:
                if (abs(zombie.y - self.y) < GRID_SIZE//2 and 
                    self.x < zombie.x < self.x + self.width + 20):
                    zombie.health = 0
                    game.score += 10
            
            if self.x > WINDOW_WIDTH:
                self.reset()
    
    def reset(self):
        self.x = 0
        self.rect.x = self.x
        self.activated = False
    
    def activate(self):
        self.activated = True

class Plant:
    def __init__(self, x, y, plant_type):
        self.x = x
        self.y = y
        self.plant_type = plant_type
        self.health = 100
        self.attack_cooldown = 0
        self.rect = pygame.Rect(x, y, GRID_SIZE, GRID_SIZE)
        self.animation_timer = 0
        
        # 不同植物的属性
        if plant_type == "sunflower":
            self.cost = 50
            self.sun_production_time = 0
            self.color = YELLOW
        elif plant_type == "peashooter":
            self.cost = 100
            self.attack_power = 20
            self.color = GREEN
        elif plant_type == "wallnut":
            self.cost = 50
            self.health = 300
            self.color = BROWN
        elif plant_type == "cherry":
            self.cost = 150
            self.color = RED
        elif plant_type == "snowpea":
            self.cost = 175
            self.attack_power = 15
            self.color = ICE_BLUE
        elif plant_type == "repeater":
            self.cost = 200
            self.attack_power = 20
            self.color = DARK_GREEN
        elif plant_type == "potato_mine":
            self.cost = 25
            self.arming_time = 300  # 5秒准备时间
            self.armed = False
            self.color = BROWN
        elif plant_type == "gatling":
            self.cost = 250
            self.attack_power = 20
            self.color = PURPLE
    
    def draw(self, surface):
        # 绘制植物主体
        pygame.draw.rect(surface, self.color, self.rect, 0, 10)
        
        # 根据不同植物类型绘制不同图案
        if self.plant_type == "sunflower":
            # 向日葵动画
            self.animation_timer += 1
            angle_offset = (self.animation_timer % 60) * 0.5
            
            # 向日葵中心
            pygame.draw.circle(surface, SUN_YELLOW, 
                              (self.x + GRID_SIZE//2, self.y + GRID_SIZE//2), 
                              GRID_SIZE//4)
            # 向日葵花瓣
            for i in range(8):
                angle = i * 45 + angle_offset
                rad = angle * 3.14159 / 180
                px = self.x + GRID_SIZE//2 + int(25 * pygame.math.Vector2(1, 0).rotate(angle).x)
                py = self.y + GRID_SIZE//2 + int(25 * pygame.math.Vector2(1, 0).rotate(angle).y)
                pygame.draw.circle(surface, YELLOW, (px, py), 10)
                
        elif self.plant_type == "peashooter":
            # 豌豆射手头部
            pygame.draw.rect(surface, DARK_GREEN, 
                            (self.x + GRID_SIZE//2, self.y + GRID_SIZE//4, 
                             GRID_SIZE//2, GRID_SIZE//2), 0, 5)
            # 豌豆射手身体条纹
            for i in range(3):
                pygame.draw.rect(surface, DARK_GREEN,
                                (self.x + 10, self.y + 15 + i*15, GRID_SIZE-20, 5))
                
        elif self.plant_type == "wallnut":
            # 坚果墙纹理
            pygame.draw.circle(surface, LIGHT_BROWN, 
                              (self.x + GRID_SIZE//2, self.y + GRID_SIZE//2), 
                              GRID_SIZE//3)
            # 坚果墙细节
            for i in range(3):
                for j in range(3):
                    if (i+j) % 2 == 0:
                        pygame.draw.circle(surface, BROWN,
                                          (self.x + 20 + i*20, self.y + 20 + j*20), 5)
        
        elif self.plant_type == "cherry":
            # 樱桃炸弹
            pygame.draw.circle(surface, RED, 
                              (self.x + GRID_SIZE//2, self.y + GRID_SIZE//2), 
                              GRID_SIZE//3)
            pygame.draw.circle(surface, RED, 
                              (self.x + GRID_SIZE//3, self.y + GRID_SIZE//2), 
                              GRID_SIZE//3)
            # 樱桃茎
            pygame.draw.line(surface, GREEN, 
                            (self.x + GRID_SIZE//2, self.y + 10),
                            (self.x + GRID_SIZE//3, self.y + 10), 3)
        
        elif self.plant_type == "snowpea":
            # 寒冰射手头部
            pygame.draw.rect(surface, ICE_BLUE, 
                            (self.x + GRID_SIZE//2, self.y + GRID_SIZE//4, 
                             GRID_SIZE//2, GRID_SIZE//2), 0, 5)
            # 寒冰射手身体
            pygame.draw.rect(surface, ICE_BLUE,
                            (self.x + 10, self.y + 20, GRID_SIZE-20, GRID_SIZE-40), 0, 5)
            # 雪花图案
            for i in range(3):
                pygame.draw.circle(surface, (255, 255, 255),
                                  (self.x + 20 + i*20, self.y + 40), 5)
        
        elif self.plant_type == "repeater":
            # 双发射手 - 两个头部
            pygame.draw.rect(surface, DARK_GREEN, 
                            (self.x + GRID_SIZE//3, self.y + GRID_SIZE//4, 
                             GRID_SIZE//3, GRID_SIZE//2), 0, 5)
            pygame.draw.rect(surface, DARK_GREEN, 
                            (self.x + GRID_SIZE*2//3, self.y + GRID_SIZE//4, 
                             GRID_SIZE//3, GRID_SIZE//2), 0, 5)
            # 身体条纹
            for i in range(3):
                pygame.draw.rect(surface, DARK_GREEN,
                                (self.x + 10, self.y + 15 + i*15, GRID_SIZE-20, 5))
        
        elif self.plant_type == "potato_mine":
            # 土豆地雷
            if not self.armed:
                # 未准备就绪 - 绿色
                pygame.draw.circle(surface, (0, 150, 0), 
                                  (self.x + GRID_SIZE//2, self.y + GRID_SIZE//2), 
                                  GRID_SIZE//3)
                # 倒计时显示
                time_left = self.arming_time // 60
                if time_left > 0:
                    time_text = small_font.render(str(time_left), True, WHITE)
                    surface.blit(time_text, (self.x + GRID_SIZE//2 - 5, self.y + GRID_SIZE//2 - 8))
            else:
                # 准备就绪 - 棕色
                pygame.draw.circle(surface, BROWN, 
                                  (self.x + GRID_SIZE//2, self.y + GRID_SIZE//2), 
                                  GRID_SIZE//3)
                # 红色警示
                pygame.draw.circle(surface, RED, 
                                  (self.x + GRID_SIZE//2, self.y + GRID_SIZE//2), 
                                  5)
        
        elif self.plant_type == "gatling":
            # 机枪射手 - 四个枪管
            for i in range(4):
                pygame.draw.rect(surface, PURPLE, 
                                (self.x + 10 + i*15, self.y + 10, 
                                 10, GRID_SIZE-20), 0, 3)
            # 身体
            pygame.draw.rect(surface, PURPLE,
                            (self.x + 20, self.y + 30, GRID_SIZE-40, 20), 0, 5)
        
        # 绘制生命条
        health_width = int((self.health / (300 if self.plant_type == "wallnut" else 100)) * GRID_SIZE)
        health_color = GREEN if self.health > 50 else YELLOW if self.health > 20 else RED
        pygame.draw.rect(surface, health_color, (self.x, self.y - 5, health_width, 5))
    
    def update(self, game):
        if self.plant_type == "sunflower":
            self.sun_production_time += 1
            if self.sun_production_time >= 300:  # 每5秒产生一个阳光
                # 阳光停留在植物旁边
                game.suns.append(Sun(self.x + random.randint(0, GRID_SIZE//2), 
                                     self.y + random.randint(0, GRID_SIZE//2), 
                                     stays_in_place=True))
                self.sun_production_time = 0
                
        elif self.plant_type == "peashooter":
            self.attack_cooldown -= 1
            if self.attack_cooldown <= 0:
                for zombie in game.zombies:
                    plant_row = (self.y - 50) // GRID_SIZE
                    zombie_row = (zombie.y - 50) // GRID_SIZE
                    if plant_row == zombie_row and zombie.x > self.x:
                        game.peas.append(Pea(self.x + GRID_SIZE, self.y + GRID_SIZE//2, "normal"))
                        self.attack_cooldown = 30
                        break
                        
        elif self.plant_type == "snowpea":
            self.attack_cooldown -= 1
            if self.attack_cooldown <= 0:
                for zombie in game.zombies:
                    plant_row = (self.y - 50) // GRID_SIZE
                    zombie_row = (zombie.y - 50) // GRID_SIZE
                    if plant_row == zombie_row and zombie.x > self.x:
                        game.peas.append(Pea(self.x + GRID_SIZE, self.y + GRID_SIZE//2, "ice"))
                        self.attack_cooldown = 40
                        break
                        
        elif self.plant_type == "repeater":
            self.attack_cooldown -= 1
            if self.attack_cooldown <= 0:
                for zombie in game.zombies:
                    plant_row = (self.y - 50) // GRID_SIZE
                    zombie_row = (zombie.y - 50) // GRID_SIZE
                    if plant_row == zombie_row and zombie.x > self.x:
                        # 双发射手一次发射两发豌豆
                        game.peas.append(Pea(self.x + GRID_SIZE, self.y + GRID_SIZE//2, "normal"))
                        game.peas.append(Pea(self.x + GRID_SIZE + 20, self.y + GRID_SIZE//2, "normal"))
                        self.attack_cooldown = 25
                        break
        
        elif self.plant_type == "gatling":
            self.attack_cooldown -= 1
            if self.attack_cooldown <= 0:
                for zombie in game.zombies:
                    plant_row = (self.y - 50) // GRID_SIZE
                    zombie_row = (zombie.y - 50) // GRID_SIZE
                    if plant_row == zombie_row and zombie.x > self.x:
                        # 机枪射手一次发射四发豌豆
                        for i in range(4):
                            game.peas.append(Pea(self.x + GRID_SIZE + i*5, self.y + GRID_SIZE//2 + i*5, "normal"))
                        self.attack_cooldown = 20
                        break
                        
        elif self.plant_type == "potato_mine":
            if not self.armed:
                self.arming_time -= 1
                if self.arming_time <= 0:
                    self.armed = True
            else:
                # 检查周围是否有僵尸
                explosion_radius = GRID_SIZE
                for zombie in game.zombies[:]:
                    distance = ((zombie.x + GRID_SIZE//2 - (self.x + GRID_SIZE//2))**2 + 
                               (zombie.y + GRID_SIZE//2 - (self.y + GRID_SIZE//2))**2)**0.5
                    if distance < explosion_radius:
                        zombie.health = 0
                        self.health = 0
                        break
        
        elif self.plant_type == "cherry":
            explosion_radius = GRID_SIZE * 2
            for zombie in game.zombies[:]:
                distance = ((zombie.x + GRID_SIZE//2 - (self.x + GRID_SIZE//2))**2 + 
                           (zombie.y + GRID_SIZE//2 - (self.y + GRID_SIZE//2))**2)**0.5
                if distance < explosion_radius:
                    zombie.health = 0
            self.health = 0

class Zombie:
    def __init__(self, row, level=1, zombie_type="normal"):
        self.x = WINDOW_WIDTH
        self.y = row * GRID_SIZE + 50
        self.row = row
        self.zombie_type = zombie_type
        self.speed = 0.5
        self.health = 100
        self.attack_cooldown = 0
        self.rect = pygame.Rect(self.x, self.y, GRID_SIZE, GRID_SIZE)
        self.slow_timer = 0
        
        # 根据僵尸类型和关卡调整属性
        if zombie_type == "cone":
            self.health = 200
            self.speed = 0.4
        elif zombie_type == "bucket":
            self.health = 300
            self.speed = 0.3
        elif zombie_type == "fast":
            self.health = 80
            self.speed = 1.0
        
        # 随着关卡增加，僵尸属性增强
        self.health = int(self.health * (1 + (level-1) * 0.2))
        self.speed = self.speed * (1 + (level-1) * 0.1)
        
    def draw(self, surface):
        # 绘制僵尸身体
        if self.zombie_type == "normal":
            body_color = (50, 150, 50)
        elif self.zombie_type == "cone":
            body_color = (100, 100, 100)  # 锥头僵尸
        elif self.zombie_type == "bucket":
            body_color = (150, 150, 150)  # 铁桶僵尸
        elif self.zombie_type == "fast":
            body_color = (100, 200, 100)  # 快速僵尸
        
        pygame.draw.rect(surface, body_color, self.rect, 0, 5)
        
        # 绘制僵尸头部
        head_color = (100, 200, 100) if self.zombie_type == "normal" else (150, 150, 150)
        pygame.draw.circle(surface, head_color, 
                          (self.x + GRID_SIZE//2, self.y + GRID_SIZE//4), 
                          GRID_SIZE//4)
        
        # 特殊僵尸装备
        if self.zombie_type == "cone":
            # 锥头
            pygame.draw.polygon(surface, (200, 200, 0), 
                               [(self.x + GRID_SIZE//2, self.y - 5),
                                (self.x + GRID_SIZE//3, self.y + 20),
                                (self.x + GRID_SIZE*2//3, self.y + 20)])
        elif self.zombie_type == "bucket":
            # 铁桶
            pygame.draw.rect(surface, (100, 100, 100), 
                            (self.x + 15, self.y - 10, GRID_SIZE-30, 20), 0, 5)
        
        # 绘制僵尸眼睛
        eye_color = BLACK if self.slow_timer <= 0 else ICE_BLUE
        pygame.draw.circle(surface, eye_color, 
                          (self.x + GRID_SIZE//2 - 5, self.y + GRID_SIZE//4 - 5), 5)
        pygame.draw.circle(surface, eye_color, 
                          (self.x + GRID_SIZE//2 + 5, self.y + GRID_SIZE//4 - 5), 5)
        
        # 绘制僵尸嘴巴
        pygame.draw.arc(surface, RED, 
                       (self.x + GRID_SIZE//2 - 10, self.y + GRID_SIZE//4, 20, 10),
                       3.14, 6.28, 2)
        
        # 绘制生命条
        health_width = int((self.health / (300 if self.zombie_type == "bucket" else 200 if self.zombie_type == "cone" else 100)) * GRID_SIZE)
        health_color = (0, 200, 0) if self.health > 50 else (200, 200, 0) if self.health > 20 else (200, 0, 0)
        pygame.draw.rect(surface, health_color, (self.x, self.y - 5, health_width, 5))
        
        # 如果被寒冰豌豆击中，显示冰冻效果
        if self.slow_timer > 0:
            pygame.draw.circle(surface, (100, 200, 255, 100), 
                              (self.x + GRID_SIZE//2, self.y + GRID_SIZE//2), 
                              GRID_SIZE//2, 2)
    
    def update(self, game):
        # 减速效果
        if self.slow_timer > 0:
            self.slow_timer -= 1
            current_speed = self.speed * 0.5
        else:
            current_speed = self.speed
        
        # 检查前方是否有植物
        plant_in_front = None
        zombie_center_x = self.x + GRID_SIZE//2
        zombie_center_y = self.y + GRID_SIZE//2
        
        for plant in game.plants:
            plant_center_x = plant.x + GRID_SIZE//2
            plant_center_y = plant.y + GRID_SIZE//2
            
            if (abs(plant_center_y - zombie_center_y) < GRID_SIZE//2 and 
                plant.x < self.x and 
                self.x - plant.x < GRID_SIZE + 20):
                plant_in_front = plant
                break
        
        if plant_in_front:
            self.attack_cooldown -= 1
            if self.attack_cooldown <= 0:
                plant_in_front.health -= 20
                self.attack_cooldown = 30
        else:
            self.x -= current_speed
            
        self.rect.x = self.x
        
        # 检查是否触发小推车
        for lawnmower in game.lawnmowers:
            if (lawnmower.row == self.row and 
                not lawnmower.activated and 
                self.x <= lawnmower.x + lawnmower.width + 20):
                lawnmower.activate()
        
        # 如果僵尸到达最左边，游戏结束
        if self.x < 50:
            game.game_over = True
            
        if self.health <= 0:
            if self in game.zombies:
                game.zombies.remove(self)
                game.score += 20 if self.zombie_type == "cone" else 30 if self.zombie_type == "bucket" else 10
    
    def slow_down(self, duration=200):
        self.slow_timer = duration

class Pea:
    def __init__(self, x, y, pea_type="normal"):
        self.x = x
        self.y = y
        self.speed = 3
        self.radius = 5
        self.pea_type = pea_type
        self.color = GREEN if pea_type == "normal" else ICE_BLUE
        
    def draw(self, surface):
        pygame.draw.circle(surface, self.color, (int(self.x), int(self.y)), self.radius)
        
    def update(self, game):
        self.x += self.speed
        
        for zombie in game.zombies[:]:
            zombie_center_x = zombie.x + GRID_SIZE//2
            zombie_center_y = zombie.y + GRID_SIZE//2
            
            distance = ((zombie_center_x - self.x)**2 + (zombie_center_y - self.y)**2)**0.5
            
            if distance < GRID_SIZE//2:
                damage = 20
                if self.pea_type == "ice":
                    damage = 15
                    zombie.slow_down(200)
                
                zombie.health -= damage
                if zombie.health <= 0:
                    if zombie in game.zombies:
                        game.zombies.remove(zombie)
                        game.score += 20 if zombie.zombie_type == "cone" else 30 if zombie.zombie_type == "bucket" else 10
                if self in game.peas:
                    game.peas.remove(self)
                break
        
        if self.x > WINDOW_WIDTH:
            if self in game.peas:
                game.peas.remove(self)

class Sun:
    def __init__(self, x, y, stays_in_place=False):
        self.x = x
        self.y = y
        self.fall_speed = 1
        self.collected = False
        self.lifetime = 600
        self.radius = 15
        self.stays_in_place = stays_in_place
        self.fall_distance = 0
        self.max_fall_distance = 50
        
    def draw(self, surface):
        pygame.draw.circle(surface, SUN_YELLOW, (int(self.x), int(self.y)), self.radius)
        
        for i in range(8):
            angle = i * 45
            rad = angle * 3.14159 / 180
            start_x = self.x + self.radius * pygame.math.Vector2(1, 0).rotate(angle).x
            start_y = self.y + self.radius * pygame.math.Vector2(1, 0).rotate(angle).y
            end_x = self.x + (self.radius + 8) * pygame.math.Vector2(1, 0).rotate(angle).x
            end_y = self.y + (self.radius + 8) * pygame.math.Vector2(1, 0).rotate(angle).y
            pygame.draw.line(surface, SUN_YELLOW, (start_x, start_y), (end_x, end_y), 3)
        
    def update(self, game):
        if not self.stays_in_place or self.fall_distance < self.max_fall_distance:
            self.y += self.fall_speed
            self.fall_distance += self.fall_speed
        
        self.lifetime -= 1
        
        mouse_pos = pygame.mouse.get_pos()
        mouse_pressed = pygame.mouse.get_pressed()
        if mouse_pressed[0]:
            distance = ((self.x - mouse_pos[0])**2 + (self.y - mouse_pos[1])**2)**0.5
            if distance < self.radius:
                self.collected = True
                game.sun_count += 25
        
        if self.y > WINDOW_HEIGHT - 50 or self.lifetime <= 0 or self.collected:
            if self in game.suns:
                game.suns.remove(self)

class Game:
    def __init__(self):
        self.plants = []
        self.zombies = []
        self.peas = []
        self.suns = []
        self.sun_count = 150
        self.score = 0
        self.level = 1
        self.wave = 1
        self.waves_per_level = 5
        self.zombie_spawn_timer = 0
        self.selected_plant = None
        self.selected_shovel = False
        self.game_over = False
        self.win = False
        self.grid = [[None for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
        
        # 创建5个小推车
        self.lawnmowers = []
        lawnmower_colors = [LAWNMOWER_RED, LAWNMOWER_BLUE, LAWNMOWER_GREEN, 
                           LAWNMOWER_YELLOW, LAWNMOWER_PURPLE]
        for i in range(GRID_HEIGHT):
            self.lawnmowers.append(LawnMower(i, lawnmower_colors[i]))
        
    def draw_grid(self, surface):
        pygame.draw.rect(surface, LIGHT_GREEN, (0, 0, WINDOW_WIDTH - SIDEBAR_WIDTH, WINDOW_HEIGHT))
        
        for i in range(GRID_WIDTH):
            for j in range(GRID_HEIGHT):
                rect = pygame.Rect(i * GRID_SIZE, j * GRID_SIZE + 50, GRID_SIZE, GRID_SIZE)
                pygame.draw.rect(surface, GREEN, rect, 1)
                
                for _ in range(20):
                    x = random.randint(i * GRID_SIZE, i * GRID_SIZE + GRID_SIZE)
                    y = random.randint(j * GRID_SIZE + 50, j * GRID_SIZE + GRID_SIZE + 50)
                    pygame.draw.circle(surface, (0, 180, 0), (x, y), 1)
    
    def draw_sidebar(self, surface):
        # 绘制侧边栏背景
        pygame.draw.rect(surface, DARK_GRAY, (WINDOW_WIDTH - SIDEBAR_WIDTH, 0, SIDEBAR_WIDTH, WINDOW_HEIGHT))
        
        # 绘制标题
        title = title_font.render("植物大战僵尸", True, YELLOW)
        surface.blit(title, (WINDOW_WIDTH - SIDEBAR_WIDTH + 20, 20))
        
        # 游戏信息区域
        info_y = 70
        level_text = font.render(f"关卡: {self.level}", True, ORANGE)
        surface.blit(level_text, (WINDOW_WIDTH - SIDEBAR_WIDTH + 20, info_y))
        
        wave_text = font.render(f"波数: {self.wave}/{self.waves_per_level}", True, WHITE)
        surface.blit(wave_text, (WINDOW_WIDTH - SIDEBAR_WIDTH + 20, info_y + 25))
        
        sun_text = font.render(f"阳光: {self.sun_count}", True, YELLOW)
        surface.blit(sun_text, (WINDOW_WIDTH - SIDEBAR_WIDTH + 20, info_y + 50))
        
        score_text = font.render(f"分数: {self.score}", True, WHITE)
        surface.blit(score_text, (WINDOW_WIDTH - SIDEBAR_WIDTH + 20, info_y + 75))
        
        # 小推车状态
        lawnmower_y = info_y + 110
        lawnmower_text = font.render("小推车:", True, WHITE)
        surface.blit(lawnmower_text, (WINDOW_WIDTH - SIDEBAR_WIDTH + 20, lawnmower_y))
        
        for i, lawnmower in enumerate(self.lawnmowers):
            status = "就绪" if not lawnmower.activated else "使用中"
            status_color = GREEN if not lawnmower.activated else RED
            status_text = small_font.render(f"{i+1}: {status}", True, status_color)
            surface.blit(status_text, (WINDOW_WIDTH - SIDEBAR_WIDTH + 20 + i*40, lawnmower_y + 25))
        
        # 铲子按钮
        shovel_y = lawnmower_y + 60
        shovel_text = font.render("铲子:", True, WHITE)
        surface.blit(shovel_text, (WINDOW_WIDTH - SIDEBAR_WIDTH + 20, shovel_y))
        
        shovel_rect = pygame.Rect(WINDOW_WIDTH - SIDEBAR_WIDTH + 20, shovel_y + 25, 180, 50)
        shovel_color = SHOVEL_BROWN if not self.selected_shovel else (200, 150, 100)
        pygame.draw.rect(surface, shovel_color, shovel_rect, 0, 8)
        pygame.draw.rect(surface, LIGHT_GRAY, shovel_rect, 3, 8)
        
        # 绘制铲子图标
        pygame.draw.rect(surface, (150, 100, 50), 
                        (shovel_rect.x + 15, shovel_rect.y + 10, 30, 20), 0, 5)
        pygame.draw.rect(surface, (100, 100, 100), 
                        (shovel_rect.x + 20, shovel_rect.y + 30, 20, 8))
        
        shovel_label = font.render("铲子", True, WHITE)
        surface.blit(shovel_label, (shovel_rect.x + 60, shovel_rect.y + 15))
        
        # 植物选择区域
        plant_y = shovel_y + 90
        plant_text = font.render("选择植物:", True, WHITE)
        surface.blit(plant_text, (WINDOW_WIDTH - SIDEBAR_WIDTH + 20, plant_y))
        
        # 植物卡片 - 使用紧凑的布局
        plants = [
            ("sunflower", "向日葵", 50, YELLOW),
            ("peashooter", "豌豆射手", 100, GREEN),
            ("snowpea", "寒冰射手", 175, ICE_BLUE),
            ("repeater", "双发射手", 200, DARK_GREEN),
            ("gatling", "机枪射手", 250, PURPLE),
            ("wallnut", "坚果墙", 50, BROWN),
            ("potato_mine", "土豆地雷", 25, BROWN),
            ("cherry", "樱桃炸弹", 150, RED)
        ]
        
        # 使用2x4网格布局
        card_width = 85
        card_height = 70
        card_margin = 5
        
        for i, (plant_type, name, cost, color) in enumerate(plants):
            row = i // 2
            col = i % 2
            
            card_x = WINDOW_WIDTH - SIDEBAR_WIDTH + 20 + col * (card_width + card_margin)
            card_y = plant_y + 30 + row * (card_height + card_margin)
            
            card_rect = pygame.Rect(card_x, card_y, card_width, card_height)
            
            # 绘制卡片背景
            pygame.draw.rect(surface, (40, 40, 40), card_rect, 0, 8)
            pygame.draw.rect(surface, color, card_rect, 3, 8)
            
            # 绘制植物图标
            icon_size = 20
            icon_rect = pygame.Rect(card_rect.x + 5, card_rect.y + 5, icon_size, icon_size)
            pygame.draw.rect(surface, color, icon_rect, 0, 5)
            
            # 植物名称（缩短显示）
            short_name = name[:2] if len(name) > 2 else name
            name_text = small_font.render(short_name, True, WHITE)
            surface.blit(name_text, (card_rect.x + 30, card_rect.y + 5))
            
            # 植物花费
            cost_text = font.render(str(cost), True, YELLOW)
            surface.blit(cost_text, (card_rect.x + 30, card_rect.y + 30))
            
            # 如果阳光不足，灰色显示
            if self.sun_count < cost:
                pygame.draw.rect(surface, (100, 100, 100, 150), card_rect, 0, 8)
    
    def draw_selected_plant_preview(self, surface):
        if self.selected_plant or self.selected_shovel:
            mouse_pos = pygame.mouse.get_pos()
            
            grid_x = mouse_pos[0] // GRID_SIZE
            grid_y = (mouse_pos[1] - 50) // GRID_SIZE
            
            if 0 <= grid_x < GRID_WIDTH and 0 <= grid_y < GRID_HEIGHT:
                preview_rect = pygame.Rect(grid_x * GRID_SIZE, grid_y * GRID_SIZE + 50, GRID_SIZE, GRID_SIZE)
                
                if self.selected_shovel:
                    # 铲子预览
                    if self.grid[grid_y][grid_x] is not None:
                        pygame.draw.rect(surface, (255, 100, 100, 150), preview_rect)
                    else:
                        pygame.draw.rect(surface, (200, 150, 100, 150), preview_rect)
                elif self.grid[grid_y][grid_x] is not None:
                    pygame.draw.rect(surface, (255, 0, 0, 100), preview_rect)
                else:
                    if self.selected_plant == "sunflower":
                        pygame.draw.rect(surface, (255, 255, 0, 150), preview_rect, 0, 10)
                    elif self.selected_plant == "peashooter":
                        pygame.draw.rect(surface, (0, 255, 0, 150), preview_rect, 0, 10)
                    elif self.selected_plant == "snowpea":
                        pygame.draw.rect(surface, (100, 200, 255, 150), preview_rect, 0, 10)
                    elif self.selected_plant == "repeater":
                        pygame.draw.rect(surface, (0, 100, 0, 150), preview_rect, 0, 10)
                    elif self.selected_plant == "gatling":
                        pygame.draw.rect(surface, (128, 0, 128, 150), preview_rect, 0, 10)
                    elif self.selected_plant == "wallnut":
                        pygame.draw.rect(surface, (139, 69, 19, 150), preview_rect, 0, 10)
                    elif self.selected_plant == "potato_mine":
                        pygame.draw.rect(surface, (139, 69, 19, 150), preview_rect, 0, 10)
                    elif self.selected_plant == "cherry":
                        pygame.draw.rect(surface, (255, 0, 0, 150), preview_rect, 0, 10)
    
    def place_plant(self, x, y):
        if not self.selected_plant:
            return
            
        grid_x = x // GRID_SIZE
        grid_y = (y - 50) // GRID_SIZE
        
        if 0 <= grid_x < GRID_WIDTH and 0 <= grid_y < GRID_HEIGHT and self.grid[grid_y][grid_x] is None:
            plant_cost = 0
            if self.selected_plant == "sunflower":
                plant_cost = 50
            elif self.selected_plant == "peashooter":
                plant_cost = 100
            elif self.selected_plant == "snowpea":
                plant_cost = 175
            elif self.selected_plant == "repeater":
                plant_cost = 200
            elif self.selected_plant == "gatling":
                plant_cost = 250
            elif self.selected_plant == "wallnut":
                plant_cost = 50
            elif self.selected_plant == "potato_mine":
                plant_cost = 25
            elif self.selected_plant == "cherry":
                plant_cost = 150
                
            if self.sun_count >= plant_cost:
                new_plant = Plant(grid_x * GRID_SIZE, grid_y * GRID_SIZE + 50, self.selected_plant)
                self.plants.append(new_plant)
                self.grid[grid_y][grid_x] = new_plant
                self.sun_count -= plant_cost
                self.selected_plant = None
    
    def remove_plant(self, x, y):
        if not self.selected_shovel:
            return
            
        grid_x = x // GRID_SIZE
        grid_y = (y - 50) // GRID_SIZE
        
        if 0 <= grid_x < GRID_WIDTH and 0 <= grid_y < GRID_HEIGHT:
            plant = self.grid[grid_y][grid_x]
            if plant is not None:
                # 移除植物
                self.grid[grid_y][grid_x] = None
                if plant in self.plants:
                    self.plants.remove(plant)
                # 退还部分阳光
                refund = int(plant.cost * 0.5)
                self.sun_count += refund
                self.selected_shovel = False
    
    def spawn_zombie(self):
        row = random.randint(0, GRID_HEIGHT - 1)
        
        # 根据关卡和波数决定僵尸类型
        zombie_type = "normal"
        if self.level >= 2 and random.random() < 0.3:
            zombie_type = "cone"
        if self.level >= 3 and random.random() < 0.2:
            zombie_type = "bucket"
        if self.level >= 4 and random.random() < 0.2:
            zombie_type = "fast"
        
        # 随着波数增加，出现更强僵尸的几率增加
        if self.wave >= 3 and random.random() < 0.3:
            zombie_type = random.choice(["cone", "bucket", "fast"])
        
        self.zombies.append(Zombie(row, self.level, zombie_type))
    
    def update(self):
        if self.game_over or self.win:
            return
            
        for plant in self.plants[:]:
            plant.update(self)
            if plant.health <= 0:
                for i in range(GRID_HEIGHT):
                    for j in range(GRID_WIDTH):
                        if self.grid[i][j] == plant:
                            self.grid[i][j] = None
                if plant in self.plants:
                    self.plants.remove(plant)
        
        for zombie in self.zombies[:]:
            zombie.update(self)
        
        for pea in self.peas[:]:
            pea.update(self)
        
        for sun in self.suns[:]:
            sun.update(self)
        
        for lawnmower in self.lawnmowers:
            lawnmower.update(self)
        
        # 生成僵尸
        self.zombie_spawn_timer += 1
        spawn_rate = max(60, 180 - self.level * 10 - self.wave * 5)
        if self.zombie_spawn_timer > spawn_rate:
            max_zombies = 5 + self.level + self.wave
            if len(self.zombies) < max_zombies:
                self.spawn_zombie()
            self.zombie_spawn_timer = 0
        
        # 每波僵尸结束后进入下一波
        if len(self.zombies) == 0 and self.zombie_spawn_timer > 300:
            self.wave += 1
            self.zombie_spawn_timer = 0
            
            # 每波开始时产生一些阳光
            for _ in range(5):
                self.suns.append(Sun(random.randint(0, WINDOW_WIDTH - SIDEBAR_WIDTH - 50), 
                                     random.randint(50, 200)))
            
            # 如果完成当前关卡的所有波数，进入下一关
            if self.wave > self.waves_per_level:
                self.level += 1
                self.wave = 1
                
                # 重置小推车
                for lawnmower in self.lawnmowers:
                    lawnmower.reset()
                
                # 奖励阳光
                self.sun_count += 100 * self.level
        
        # 获胜条件：通过5关
        if self.level > 5:
            self.win = True
    
    def draw(self, surface):
        surface.fill(SKY_BLUE)
        self.draw_grid(surface)
        
        for lawnmower in self.lawnmowers:
            lawnmower.draw(surface)
        
        for plant in self.plants:
            plant.draw(surface)
        
        for zombie in self.zombies:
            zombie.draw(surface)
        
        for pea in self.peas:
            pea.draw(surface)
        
        for sun in self.suns:
            sun.draw(surface)
        
        self.draw_sidebar(surface)
        self.draw_selected_plant_preview(surface)
        
        if self.game_over:
            overlay = pygame.Surface((WINDOW_WIDTH, WINDOW_HEIGHT), pygame.SRCALPHA)
            overlay.fill((0, 0, 0, 200))
            surface.blit(overlay, (0, 0))
            
            game_over_text = title_font.render("游戏结束!", True, RED)
            surface.blit(game_over_text, (WINDOW_WIDTH//2 - game_over_text.get_width()//2, WINDOW_HEIGHT//2 - 50))
            
            score_text = font.render(f"最终分数: {self.score}", True, WHITE)
            surface.blit(score_text, (WINDOW_WIDTH//2 - score_text.get_width()//2, WINDOW_HEIGHT//2))
            
            level_text = font.render(f"到达关卡: {self.level}", True, ORANGE)
            surface.blit(level_text, (WINDOW_WIDTH//2 - level_text.get_width()//2, WINDOW_HEIGHT//2 + 30))
            
            restart_text = font.render("按R键重新开始", True, YELLOW)
            surface.blit(restart_text, (WINDOW_WIDTH//2 - restart_text.get_width()//2, WINDOW_HEIGHT//2 + 60))
        
        elif self.win:
            overlay = pygame.Surface((WINDOW_WIDTH, WINDOW_HEIGHT), pygame.SRCALPHA)
            overlay.fill((0, 0, 0, 200))
            surface.blit(overlay, (0, 0))
            
            win_text = title_font.render("恭喜获胜!", True, YELLOW)
            surface.blit(win_text, (WINDOW_WIDTH//2 - win_text.get_width()//2, WINDOW_HEIGHT//2 - 50))
            
            score_text = font.render(f"最终分数: {self.score}", True, WHITE)
            surface.blit(score_text, (WINDOW_WIDTH//2 - score_text.get_width()//2, WINDOW_HEIGHT//2))
            
            restart_text = font.render("按R键重新开始", True, YELLOW)
            surface.blit(restart_text, (WINDOW_WIDTH//2 - restart_text.get_width()//2, WINDOW_HEIGHT//2 + 30))
        
        hint_text = font.render("点击植物卡片选择植物，然后点击网格放置植物", True, WHITE)
        surface.blit(hint_text, (10, WINDOW_HEIGHT - 30))
        
        hint_text2 = font.render("点击铲子按钮选择铲子，然后点击植物移除", True, WHITE)
        surface.blit(hint_text2, (10, WINDOW_HEIGHT - 60))

def main():
    game = Game()
    running = True
    
    for _ in range(5):
        game.suns.append(Sun(random.randint(0, WINDOW_WIDTH - SIDEBAR_WIDTH - 50), 
                            random.randint(50, 200)))
    
    while running:
        for event in pygame.event.get():
            if event.type == QUIT:
                running = False
                
            elif event.type == MOUSEBUTTONDOWN:
                if event.button == 1:
                    mouse_pos = pygame.mouse.get_pos()
                    
                    # 检查是否点击了侧边栏
                    if mouse_pos[0] > WINDOW_WIDTH - SIDEBAR_WIDTH:
                        # 检查是否点击了铲子按钮
                        shovel_rect = pygame.Rect(WINDOW_WIDTH - SIDEBAR_WIDTH + 20, 235, 180, 50)
                        if shovel_rect.collidepoint(mouse_pos):
                            game.selected_shovel = not game.selected_shovel
                            game.selected_plant = None
                        else:
                            # 检查是否点击了植物卡片
                            # 植物卡片区域：从Y=325开始，2列布局
                            plant_start_y = 325
                            plant_start_x = WINDOW_WIDTH - SIDEBAR_WIDTH + 20
                            
                            # 计算点击位置相对于植物卡片区域的坐标
                            rel_x = mouse_pos[0] - plant_start_x
                            rel_y = mouse_pos[1] - plant_start_y
                            
                            # 如果点击在植物卡片区域内
                            if 0 <= rel_x < 180 and 0 <= rel_y < 320:
                                # 计算行和列
                                col = rel_x // 90  # 每列90像素宽
                                row = rel_y // 75  # 每行75像素高
                                
                                card_index = row * 2 + col
                                
                                if 0 <= card_index < 8:
                                    plants = ["sunflower", "peashooter", "snowpea", "repeater", 
                                             "gatling", "wallnut", "potato_mine", "cherry"]
                                    plant_costs = [50, 100, 175, 200, 250, 50, 25, 150]
                                    
                                    if game.sun_count >= plant_costs[card_index]:
                                        game.selected_plant = plants[card_index]
                                        game.selected_shovel = False
                    else:
                        # 在游戏区域点击
                        if game.selected_shovel:
                            game.remove_plant(mouse_pos[0], mouse_pos[1])
                        else:
                            game.place_plant(mouse_pos[0], mouse_pos[1])
            
            elif event.type == KEYDOWN:
                if event.key == K_r and (game.game_over or game.win):
                    game = Game()
                    for _ in range(5):
                        game.suns.append(Sun(random.randint(0, WINDOW_WIDTH - SIDEBAR_WIDTH - 50), 
                                            random.randint(50, 200)))
                elif event.key == K_ESCAPE:
                    game.selected_plant = None
                    game.selected_shovel = False
                elif event.key == K_SPACE:
                    for lawnmower in game.lawnmowers:
                        if not lawnmower.activated:
                            lawnmower.activate()
        
        game.update()
        game.draw(screen)
        pygame.display.flip()
        clock.tick(60)
    
    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()