2048作ってみた　#100日チャレンジ　に感化されて

（4/21）編集リクエストがあったので，一部修正しました！

2048ゲーム，大学生の時によくやったな
ほぼクリアしたことないんだけど，これの必勝法とかあるのかな？

chatGPTに頼らず，コード書けるようになりたい！

![2048.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668168/e1782aaa-3da3-48a5-b6e3-a5abf4e177c8.gif)

```python
import pygame
import random
import sys
```

```python
pygame.init()

# 画面サイズとマスの設定
SIZE = 4
TILE_SIZE = 100
WIDTH = HEIGHT = SIZE * TILE_SIZE
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("2048")

# 色・フォント
BG_COLOR = (187, 173, 160)
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)
}
FONT = pygame.font.SysFont("arial", 28)
board = [[0] * SIZE for _ in range(SIZE)]

def draw_board():
    screen.fill(BG_COLOR)
    for i in range(SIZE):
        for j in range(SIZE):
            value = board[i][j]
            color = TILE_COLORS.get(value, (60, 58, 50))
            rect = pygame.Rect(j * TILE_SIZE, i * TILE_SIZE, TILE_SIZE, TILE_SIZE)
            pygame.draw.rect(screen, color, rect)
            if value != 0:
                text = FONT.render(str(value), True, (0, 0, 0))
                text_rect = text.get_rect(center=rect.center)
                screen.blit(text, text_rect)

def add_random_tile():
    empty = [(i, j) for i in range(SIZE) for j in range(SIZE) if board[i][j] == 0]
    if empty:
        i, j = random.choice(empty)
        board[i][j] = random.choice([2] * 9 + [4])

def slide_and_merge(row):
    new_row = [num for num in row if num != 0]
    merged_row = []
    skip = False
    for i in range(len(new_row)):
        if skip:
            skip = False
            continue
        if i + 1 < len(new_row) and new_row[i] == new_row[i + 1]:
            merged_row.append(new_row[i] * 2)
            skip = True
        else:
            merged_row.append(new_row[i])
    merged_row += [0] * (SIZE - len(merged_row))
    return merged_row

def move_left():
    global board
    new_board = []
    for row in board:
        new_board.append(slide_and_merge(row))
    if new_board != board:
        board = new_board
        add_random_tile()

def move_right():
    global board
    new_board = []
    for row in board:
        reversed_row = row[::-1]
        merged = slide_and_merge(reversed_row)
        new_board.append(merged[::-1])
    if new_board != board:
        board = new_board
        add_random_tile()

def move_up():
    global board
    transposed = list(zip(*board))
    new_transposed = []
    for row in transposed:
        merged = slide_and_merge(list(row))
        new_transposed.append(merged)
    new_board = list(map(list, zip(*new_transposed)))
    if new_board != board:
        board = new_board
        add_random_tile()

def move_down():
    global board
    transposed = list(zip(*board))
    new_transposed = []
    for row in transposed:
        merged = slide_and_merge(list(row)[::-1])
        new_transposed.append(merged[::-1])
    new_board = list(map(list, zip(*new_transposed)))
    if new_board != board:
        board = new_board
        add_random_tile()

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

def check_game_over():
    for row in board:
        if 0 in row:
            return False
    for i in range(SIZE):
        for j in range(SIZE):
            if j < SIZE - 1 and board[i][j] == board[i][j + 1]:
                return False
            if i < SIZE - 1 and board[i][j] == board[i + 1][j]:
                return False
    return True

def show_message(text):
    font = pygame.font.SysFont("arial", 48)
    msg = font.render(text, True, (255, 0, 0))
    rect = msg.get_rect(center=(WIDTH // 2, HEIGHT // 2))
    screen.blit(msg, rect)
    pygame.display.flip()
    pygame.time.delay(2000)

def main():
    clock = pygame.time.Clock()
    add_random_tile()
    add_random_tile()
    won = False

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    move_left()
                elif event.key == pygame.K_RIGHT:
                    move_right()
                elif event.key == pygame.K_UP:
                    move_up()
                elif event.key == pygame.K_DOWN:
                    move_down()

        draw_board()

        if not won and check_win():
            show_message("You Win!")
            won = True

        if check_game_over():
            show_message("Game Over")
            pygame.quit()
            sys.exit()

        pygame.display.flip()
        clock.tick(60)

if __name__ == "__main__":
    main()
    
```

気に入った方はいいね👍お願いします