#mPythonType:0
from mpython import *
import random

# 初始化 OLED 对象
oled = OLED()

# 初始化游戏板
board = [[0] * 4 for _ in range(4)]

# 定义颜色映射
color_map = {
    2: (255, 255, 255),
    4: (255, 255, 0),
    8: (255, 165, 0),
    16: (255, 0, 0),
    32: (0, 255, 0),
    64: (0, 0, 255),
    128: (255, 255, 128),
    256: (255, 128, 255),
    512: (128, 255, 255),
    1024: (255, 128, 0),
    2048: (0, 255, 255)
}

# 初始化分数和最高分
score = 0
high_score = 0


def add_new_tile():
    """在空白位置添加新的数字 2 或 4"""
    empty_cells = []
    for i in range(4):
        for j in range(4):
            if board[i][j] == 0:
                empty_cells.append((i, j))
    if empty_cells:
        row, col = random.choice(empty_cells)
        board[row][col] = 2 if random.random() < 0.9 else 4


def draw_grid():
    """绘制游戏板网格"""
    # 绘制游戏区边框
    oled.rect(0, 0, 96, 64, 1)
    for i in range(1, 4):
        oled.hline(0, i * 16, 96, 1)
    for j in range(1, 4):
        oled.vline(j * 24, 0, 64, 1)


def draw_board():
    """在 OLED 上绘制游戏板"""
    oled.fill(0)
    draw_grid()
    # 假设字体宽度为 6，可根据实际情况调整
    font_width = 6
    # 绘制游戏区数字
    for i in range(4):
        for j in range(4):
            if board[i][j] != 0:
                num_str = str(board[i][j])
                x = j * 24 + (24 - font_width * len(num_str)) // 2
                y = i * 16 + (16 - font_width) // 2
                color = color_map.get(board[i][j], (255, 255, 255))
                # 假设使用 RGB565 颜色编码转换
                r, g, b = color
                rgb565 = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)
                oled.text(num_str, x, y, rgb565)
    # 绘制右侧得分区域
    oled.text("Score:", 100, 10)
    oled.text("%d" % score, 100, 20)
    oled.text("High Score:", 100, 35)
    oled.text("%d" % high_score, 100, 45)
    oled.show()


def merge_left():
    """向左合并数字"""
    global score
    for row in board:
        new_row = [num for num in row if num != 0]
        i = 0
        while i < len(new_row) - 1:
            if new_row[i] == new_row[i + 1]:
                # 更新分数
                score += new_row[i] * 2
                new_row[i] *= 2
                del new_row[i + 1]
            i += 1
        new_row.extend([0] * (4 - len(new_row)))
        for j in range(4):
            row[j] = new_row[j]


def rotate_board():
    """顺时针旋转游戏板"""
    global board
    board = list(map(list, zip(*board[::-1])))


def move(direction):
    """根据方向移动和合并数字"""
    if direction == 'left':
        merge_left()
    elif direction == 'up':
        rotate_board()
        merge_left()
        rotate_board()
        rotate_board()
        rotate_board()
    elif direction == 'right':
        rotate_board()
        rotate_board()
        merge_left()
        rotate_board()
        rotate_board()
    elif direction == 'down':
        rotate_board()
        rotate_board()
        rotate_board()
        merge_left()
        rotate_board()


def is_game_over():
    """检查游戏是否结束"""
    for i in range(4):
        for j in range(4):
            if board[i][j] == 0:
                return False
            if i > 0 and board[i][j] == board[i - 1][j]:
                return False
            if j > 0 and board[i][j] == board[i][j - 1]:
                return False
    return True


def reset_game():
    """重置游戏状态"""
    global board, score
    board = [[0] * 4 for _ in range(4)]
    score = 0
    add_new_tile()
    add_new_tile()
    draw_board()


# 初始化游戏
add_new_tile()
add_new_tile()
draw_board()

while True:
    if button_a.value() == 0:
        move('left')
        add_new_tile()
        draw_board()
    elif button_b.value() == 0:
        move('right')
        add_new_tile()
        draw_board()
    elif accelerometer.get_x() > 0.5:
        move('down')
        add_new_tile()
        draw_board()
    elif accelerometer.get_x() < -0.5:
        move('up')
        add_new_tile()
        draw_board()
    if is_game_over():
        # 检查是否打破最高分
        if score > high_score:
            high_score = score
        oled.fill(0)
        oled.text("Game Over!", 10, 20)
        oled.text("Final Score: %d" % score, 10, 30)
        oled.text("High Score: %d" % high_score, 10, 40)
        oled.show()
        # 等待按键按下以重置游戏
        while True:
            if button_a.value() == 0 or button_b.value() == 0:
                reset_game()
                break
    