import pygame
import random
import sys

pygame.init()
WIDTH = 420
HEIGHT = 520
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("2048")
clock = pygame.time.Clock()

# 颜色配置（原版2048配色）
BG_COLOR = (187, 173, 160)
GRID_COLOR = (205, 193, 180)
TEXT_DARK = (119, 110, 101)
TEXT_WHITE = (255, 255, 255)

TILE_COLORS = {
    0: (205, 193, 180),
    2: (238, 228, 218),
    4: (237, 224, 200),
    8: (242, 177, 121),
    16: (245, 149, 99),
    32: (246, 124, 95),
    64: (246, 94, 59),
    128: (237, 207, 114),
    256: (237, 204, 97),
    512: (237, 200, 80),
    1024: (237, 197, 63),
    2048: (237, 194, 46)
}

# 【重点修复】不用SysFont，使用内置默认字体，兼容海龟编辑器
font_num = pygame.font.Font(None, 36)
font_info = pygame.font.Font(None, 28)

GRID_SIZE = 4
CELL_SIZE = 90
GAP = 10

def create_board():
    board = [[0]*4 for _ in range(4)]
    add_random_tile(board)
    add_random_tile(board)
    return board

def add_random_tile(board):
    empty = [(i,j) for i in range(4) for j in range(4) if board[i][j]==0]
    if empty:
        i,j = random.choice(empty)
        board[i][j] = 2 if random.random() < 0.9 else 4

def move_left(row):
    new = [v for v in row if v != 0]
    score_gain = 0
    i = 0
    while i < len(new)-1:
        if new[i] == new[i+1]:
            new[i] *= 2
            score_gain += new[i]
            new.pop(i+1)
        i += 1
    new += [0]*(4-len(new))
    return new, score_gain

def transpose(mat):
    return [list(col) for col in zip(*mat)]

def reverse(mat):
    return [r[::-1] for r in mat]

def move_board(board, direction):
    old = [r.copy() for r in board]
    gain = 0
    if direction == "left":
        for i in range(4):
            board[i], g = move_left(board[i])
            gain += g
    elif direction == "right":
        for i in range(4):
            row, g = move_left(board[i][::-1])
            board[i] = row[::-1]
            gain += g
    elif direction == "up":
        board = transpose(board)
        for i in range(4):
            board[i], g = move_left(board[i])
            gain += g
        board = transpose(board)
    elif direction == "down":
        board = transpose(board)
        for i in range(4):
            row, g = move_left(board[i][::-1])
            board[i] = row[::-1]
            gain += g
        board = transpose(board)
    changed = old != board
    return board, changed, gain

def is_game_over(board):
    for i in range(4):
        for j in range(4):
            if board[i][j]==0:
                return False
            if j<3 and board[i][j]==board[i][j+1]:
                return False
            if i<3 and board[i][j]==board[i+1][j]:
                return False
    return True

def has_win(board):
    for row in board:
        if 2048 in row:
            return True
    return False

def draw_board(board, score, win, gameover):
    screen.fill(BG_COLOR)
    # 分数文字
    txt_score = font_info.render(f"Score: {score}", True, TEXT_DARK)
    screen.blit(txt_score, (20,15))
    # 棋盘起点
    start_x = (WIDTH - (CELL_SIZE*4 + GAP*3)) // 2
    start_y = 80
    # 绘制格子
    for i in range(4):
        for j in range(4):
            val = board[i][j]
            x = start_x + j*(CELL_SIZE+GAP)
            y = start_y + i*(CELL_SIZE+GAP)
            color = TILE_COLORS.get(val, (60,60,60))
            pygame.draw.rect(screen, color, (x,y,CELL_SIZE,CELL_SIZE), border_radius=6)
            if val != 0:
                if val >= 128:
                    txt_color = TEXT_WHITE
                else:
                    txt_color = TEXT_DARK
                text = font_num.render(str(val), True, txt_color)
                rect = text.get_rect(center=(x+CELL_SIZE//2, y+CELL_SIZE//2))
                screen.blit(text, rect)
    # 提示文字
    if win:
        overlay = pygame.Surface((WIDTH,HEIGHT))
        overlay.set_alpha(160)
        overlay.fill((255,215,0))
        screen.blit(overlay,(0,0))
        msg = font_info.render("YOU WIN! R to restart", True, (0,0,0))
        screen.blit(msg, msg.get_rect(center=(WIDTH//2, HEIGHT//2)))
    elif gameover:
        overlay = pygame.Surface((WIDTH,HEIGHT))
        overlay.set_alpha(160)
        overlay.fill((40,40,40))
        screen.blit(overlay,(0,0))
        msg = font_info.render("Game Over! R to restart", True, WHITE)
        screen.blit(msg, msg.get_rect(center=(WIDTH//2, HEIGHT//2)))

def reset_game():
    return create_board(), 0, False, False

board, score, win_flag, gameover_flag = reset_game()

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_r:
                board, score, win_flag, gameover_flag = reset_game()
            if not win_flag and not gameover_flag:
                dirs = None
                if event.key == pygame.K_LEFT:
                    dirs = "left"
                elif event.key == pygame.K_RIGHT:
                    dirs = "right"
                elif event.key == pygame.K_UP:
                    dirs = "up"
                elif event.key == pygame.K_DOWN:
                    dirs = "down"
                if dirs:
                    board, changed, gain = move_board(board, dirs)
                    if changed:
                        score += gain
                        add_random_tile(board)
                        if has_win(board):
                            win_flag = True
                        if is_game_over(board):
                            gameover_flag = True

    draw_board(board, score, win_flag, gameover_flag)
    pygame.display.update()
    clock.tick(60)

pygame.quit()
sys.exit()