import pygame
import random
import math

pygame.init()

# --- 配置 ---
WIDTH, HEIGHT = 800, 600
TILE_SIZE = 40
FPS = 60

# 颜色
COLORS = {
    "water": (30, 100, 200),
    "sand": (230, 210, 150),
    "grass": (80, 160, 80),
    "tree": (20, 100, 20),
    "berry": (180, 30, 30),
    "player": (220, 50, 50),
    "shelter": (139, 90, 43),
    "ui_bg": (0, 0, 0, 180),
}

# 资源类型
RESOURCES = {
    "tree": {"color": COLORS["tree"], "action": "wood", "amount": 2},
    "berry": {"color": COLORS["berry"], "action": "food", "amount": 1},
    "water_source": {"color": COLORS["water"], "action": "water", "amount": 1},
}


class Player:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.speed = 3
        self.hunger = 100
        self.thirst = 100
        self.energy = 100
        self.inventory = {"wood": 0, "food": 0, "water": 0}
        self.shelter_built = False

    def move(self, dx, dy, game_map):
        new_x = self.x + dx * self.speed
        new_y = self.y + dy * self.speed

        # 边界和水面检测
        tile_x = int(new_x // TILE_SIZE)
        tile_y = int(new_y // TILE_SIZE)
        if 0 <= tile_x < WIDTH // TILE_SIZE and 0 <= tile_y < HEIGHT // TILE_SIZE:
            if game_map[tile_y][tile_x] != "water":
                self.x = new_x
                self.y = new_y
                self.energy = max(0, self.energy - 0.02)

    def update_stats(self):
        self.hunger = max(0, self.hunger - 0.03)
        self.thirst = max(0, self.thirst - 0.04)
        if self.hunger <= 0 or self.thirst <= 0:
            self.energy = max(0, self.energy - 0.1)

    def is_alive(self):
        return self.energy > 0


class GameMap:
    def __init__(self):
        self.cols = WIDTH // TILE_SIZE
        self.rows = HEIGHT // TILE_SIZE
        self.grid = []
        self.resources = {}
        self._generate()

    def _generate(self):
        # 简单岛屿生成：中心是陆地，边缘是水
        center_x, center_y = self.cols // 2, self.rows // 2
        max_radius = min(self.cols, self.rows) // 2 - 2

        for y in range(self.rows):
            row = []
            for x in range(self.cols):
                dist = math.sqrt((x - center_x) ** 2 + (y - center_y) ** 2)
                noise = random.uniform(-1.5, 1.5)
                if dist + noise < max_radius:
                    row.append("grass")
                elif dist + noise < max_radius + 1.5:
                    row.append("sand")
                else:
                    row.append("water")
            self.grid.append(row)

        # 在陆地上随机放置资源
        for y in range(self.rows):
            for x in range(self.cols):
                if self.grid[y][x] == "grass":
                    r = random.random()
                    if r < 0.08:
                        self.resources[(x, y)] = "tree"
                    elif r < 0.12:
                        self.resources[(x, y)] = "berry"
                elif self.grid[y][x] == "sand":
                    if random.random() < 0.05:
                        self.resources[(x, y)] = "water_source"

    def get_tile(self, px, py):
        tx = int(px // TILE_SIZE)
        ty = int(py // TILE_SIZE)
        if 0 <= tx < self.cols and 0 <= ty < self.rows:
            return self.grid[ty][tx]
        return "water"


class Game:
    def __init__(self):
        self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
        pygame.display.set_caption("荒岛求生 - WASD移动 | 空格采集 | 1吃 2喝 3搭庇护所")
        self.clock = pygame.time.Clock()
        self.font = pygame.font.SysFont("microsoftyahei", 20)
        self.big_font = pygame.font.SysFont("microsoftyahei", 48)

        self.game_map = GameMap()
        # 把玩家放在岛屿中心
        cx = (self.game_map.cols // 2) * TILE_SIZE + TILE_SIZE // 2
        cy = (self.game_map.rows // 2) * TILE_SIZE + TILE_SIZE // 2
        self.player = Player(cx, cy)

        self.running = True
        self.game_over = False
        self.message = ""
        self.msg_timer = 0

    def show_msg(self, text):
        self.message = text
        self.msg_timer = 90  # 1.5秒

    def interact(self):
        """空格交互：采集附近资源"""
        px, py = int(self.player.x // TILE_SIZE), int(self.player.y // TILE_SIZE)
        # 检查周围3x3
        for dy in range(-1, 2):
            for dx in range(-1, 2):
                tx, ty = px + dx, py + dy
                if (tx, ty) in self.game_map.resources:
                    res_type = self.game_map.resources[(tx, ty)]
                    info = RESOURCES[res_type]
                    self.player.inventory[info["action"]] += info["amount"]
                    del self.game_map.resources[(tx, ty)]
                    self.show_msg(f"+{info['amount']} {info['action']}")
                    return
        self.show_msg("附近没有可采集的资源")

    def use_item(self, item):
        if item == "food" and self.player.inventory["food"] > 0:
            self.player.inventory["food"] -= 1
            self.player.hunger = min(100, self.player.hunger + 25)
            self.show_msg("吃了食物 +25饱食度")
        elif item == "water" and self.player.inventory["water"] > 0:
            self.player.inventory["water"] -= 1
            self.player.thirst = min(100, self.player.thirst + 30)
            self.show_msg("喝了水 +30口渴度")
        elif item == "shelter":
            if self.player.inventory["wood"] >= 5 and not self.player.shelter_built:
                self.player.inventory["wood"] -= 5
                self.player.shelter_built = True
                self.show_msg("搭建了庇护所！夜晚不再消耗额外体力")
            elif self.player.shelter_built:
                self.show_msg("庇护所已经建好了")
            else:
                self.show_msg(f"需要5木材 (当前:{self.player.inventory['wood']})")
        else:
            self.show_msg("没有足够的物品")

    def draw_map(self):
        for y in range(self.game_map.rows):
            for x in range(self.game_map.cols):
                tile = self.game_map.grid[y][x]
                color = COLORS.get(tile, (0, 0, 0))
                pygame.draw.rect(self.screen, color,
                                 (x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE))

        # 画资源
        for (tx, ty), res_type in self.game_map.resources.items():
            color = RESOURCES[res_type]["color"]
            cx = tx * TILE_SIZE + TILE_SIZE // 2
            cy = ty * TILE_SIZE + TILE_SIZE // 2
            pygame.draw.circle(self.screen, color, (cx, cy), TILE_SIZE // 3)

        # 画庇护所
        if self.player.shelter_built:
            sx = int(self.player.x // TILE_SIZE) * TILE_SIZE
            sy = int(self.player.y // TILE_SIZE) * TILE_SIZE
            pygame.draw.rect(self.screen, COLORS["shelter"],
                             (sx - 5, sy - 5, TILE_SIZE + 10, TILE_SIZE + 10), 3)

    def draw_player(self):
        pygame.draw.circle(self.screen, COLORS["player"],
                           (int(self.player.x), int(self.player.y)), TILE_SIZE // 3)

    def draw_ui(self):
        # 状态条
        bars = [
            ("饱食度", self.player.hunger, (200, 150, 50)),
            ("口渴度", self.player.thirst, (50, 150, 200)),
            ("体力", self.player.energy, (50, 200, 50)),
        ]
        for i, (label, val, color) in enumerate(bars):
            y = 10 + i * 28
            text = self.font.render(f"{label}: {int(val)}", True, (255, 255, 255))
            self.screen.blit(text, (10, y))
            # 进度条背景
            pygame.draw.rect(self.screen, (60, 60, 60), (140, y + 2, 150, 18))
            # 进度条前景
            bar_w = int(val / 100 * 150)
            pygame.draw.rect(self.screen, color, (140, y + 2, bar_w, 18))

        # 背包
        inv_text = f"木材:{self.player.inventory['wood']}  食物:{self.player.inventory['food']}  水:{self.player.inventory['water']}"
        inv_surf = self.font.render(inv_text, True, (255, 255, 200))
        self.screen.blit(inv_surf, (10, HEIGHT - 35))

        # 提示
        hint = self.font.render("WASD移动 | 空格采集 | 1吃 2喝 3搭庇护所", True, (200, 200, 200))
        self.screen.blit(hint, (WIDTH - hint.get_width() - 10, HEIGHT - 35))

        # 消息
        if self.msg_timer > 0:
            self.msg_timer -= 1
            msg_surf = self.font.render(self.message, True, (255, 255, 100))
            self.screen.blit(msg_surf, (WIDTH // 2 - msg_surf.get_width() // 2, HEIGHT // 2 - 60))

    def draw_game_over(self):
        overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 180))
        self.screen.blit(overlay, (0, 0))

        go_text = self.big_font.render("你没能活下来...", True, (220, 50, 50))
        self.screen.blit(go_text, (WIDTH // 2 - go_text.get_width() // 2, HEIGHT // 2 - 40))

        restart = self.font.render("按 R 重新开始 | 按 ESC 退出", True, (200, 200, 200))
        self.screen.blit(restart, (WIDTH // 2 - restart.get_width() // 2, HEIGHT // 2 + 30))

    def restart(self):
        self.__init__()

    def run(self):
        while self.running:
            dt = self.clock.tick(FPS)

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False
                if event.type == pygame.KEYDOWN:
                    if self.game_over:
                        if event.key == pygame.K_r:
                            self.restart()
                        elif event.key == pygame.K_ESCAPE:
                            self.running = False
                    else:
                        if event.key == pygame.K_SPACE:
                            self.interact()
                        elif event.key == pygame.K_1:
                            self.use_item("food")
                        elif event.key == pygame.K_2:
                            self.use_item("water")
                        elif event.key == pygame.K_3:
                            self.use_item("shelter")
                        elif event.key == pygame.K_ESCAPE:
                            self.running = False

            if not self.game_over:
                # 移动
                keys = pygame.key.get_pressed()
                dx = dy = 0
                if keys[pygame.K_w] or keys[pygame.K_UP]: dy = -1
                if keys[pygame.K_s] or keys[pygame.K_DOWN]: dy = 1
                if keys[pygame.K_a] or keys[pygame.K_LEFT]: dx = -1
                if keys[pygame.K_d] or keys[pygame.K_RIGHT]: dx = 1
                if dx != 0 or dy != 0:
                    length = math.sqrt(dx * dx + dy * dy)
                    dx /= length
                    dy /= length
                    self.player.move(dx, dy, self.game_map.grid)

                self.player.update_stats()

                if not self.player.is_alive():
                    self.game_over = True

            # 渲染
            self.screen.fill((0, 0, 0))
            self.draw_map()
            self.draw_player()
            self.draw_ui()
            if self.game_over:
                self.draw_game_over()

            pygame.display.flip()

        pygame.quit()


if __name__ == "__main__":
    game = Game()
    game.run()