import pygame

pygame.init()
W, H = 640, 700
screen = pygame.display.set_mode((W, H))
pygame.display.set_caption("벽돌깨기")
clock = pygame.time.Clock()
font = pygame.font.SysFont("malgungothic", 22)
big_font = pygame.font.SysFont("malgungothic", 40, bold=True)

# ---------- 색과 크기 ----------
BG = (18, 20, 32)
PADDLE_COLOR = (90, 200, 255)
BALL_COLOR = (255, 230, 120)
TEXT = (235, 240, 250)
BRICK_COLORS = [
    (255, 110, 110), (255, 170, 90), (255, 230, 120),
    (130, 220, 150), (120, 180, 255),
]

PADDLE_W, PADDLE_H = 110, 14
PADDLE_SPEED = 8
BALL_R = 8
BALL_SPEED = 5

BRICK_COLS, BRICK_ROWS = 8, 5
BRICK_W, BRICK_H = 70, 26
BRICK_GAP = 6
BRICK_TOP = 70

# ---------- 패들 ----------
paddle = pygame.Rect(0, 0, PADDLE_W, PADDLE_H)
paddle.centerx = W // 2
paddle.y = H - 50

# ---------- 벽돌 만들기 ----------
def make_bricks():
    """벽돌을 행 x 열 격자로 만들어 리스트로 돌려준다."""
    bricks = []
    total_w = BRICK_COLS * BRICK_W + (BRICK_COLS - 1) * BRICK_GAP
    left = (W - total_w) // 2          # 벽돌 전체를 화면 가운데로
    for row in range(BRICK_ROWS):
        for col in range(BRICK_COLS):
            x = left + col * (BRICK_W + BRICK_GAP)
            y = BRICK_TOP + row * (BRICK_H + BRICK_GAP)
            bricks.append({
                "rect": pygame.Rect(x, y, BRICK_W, BRICK_H),
                "color": BRICK_COLORS[row % len(BRICK_COLORS)],
            })
    return bricks

# ---------- 공 / 게임 상태 ----------
ball_x = ball_y = ball_vx = ball_vy = 0.0
bricks = []
score = 0
lives = 3
state = "play"      # "play"(진행) / "over"(패배) / "clear"(승리)

def reset_ball():
    """공을 화면 가운데로 되돌리고 다시 위로 쏘아 올린다."""
    global ball_x, ball_y, ball_vx, ball_vy
    ball_x, ball_y = W / 2, H / 2
    ball_vx, ball_vy = BALL_SPEED * 0.7, -BALL_SPEED

def reset_game():
    """게임 전체를 처음 상태로 되돌린다."""
    global bricks, score, lives, state
    bricks = make_bricks()
    score = 0
    lives = 3
    state = "play"
    paddle.centerx = W // 2
    reset_ball()

reset_game()

# ---------- 메인 루프 ----------
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE and state != "play":
            reset_game()               # 게임이 끝난 상태에서 스페이스 -> 다시 시작

    # 패들 조작: 키를 꾹 누르고 있는 동안 계속 움직인다
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        paddle.x -= PADDLE_SPEED
    if keys[pygame.K_RIGHT]:
        paddle.x += PADDLE_SPEED
    if paddle.left < 0:
        paddle.left = 0
    if paddle.right > W:
        paddle.right = W

    if state == "play":
        # 속도만큼 공을 움직인다
        ball_x += ball_vx
        ball_y += ball_vy

        # 좌우 벽에 부딪히면 가로 방향을 뒤집는다
        if ball_x - BALL_R < 0:
            ball_x = BALL_R
            ball_vx = -ball_vx
        if ball_x + BALL_R > W:
            ball_x = W - BALL_R
            ball_vx = -ball_vx
        # 천장에 부딪히면 세로 방향을 뒤집는다
        if ball_y - BALL_R < 0:
            ball_y = BALL_R
            ball_vy = -ball_vy

        ball_rect = pygame.Rect(ball_x - BALL_R, ball_y - BALL_R, BALL_R * 2, BALL_R * 2)

        # 패들에 맞으면: 위로 튕기고, 맞은 위치에 따라 좌우 각도가 달라진다
        if ball_rect.colliderect(paddle) and ball_vy > 0:
            ball_vy = -abs(ball_vy)
            offset = (ball_x - paddle.centerx) / (PADDLE_W / 2)   # -1(왼쪽 끝) ~ +1(오른쪽 끝)
            ball_vx = BALL_SPEED * offset

        # 벽돌에 맞으면: 그 벽돌을 없애고 세로 방향을 뒤집는다
        for b in bricks:
            if ball_rect.colliderect(b["rect"]):
                bricks.remove(b)
                ball_vy = -ball_vy
                score += 10
                break                  # 리스트를 돌며 지우는 중이므로 한 프레임에 하나만

        # 바닥으로 빠지면 목숨 하나를 잃는다
        if ball_y - BALL_R > H:
            lives -= 1
            if lives <= 0:
                state = "over"
            else:
                reset_ball()

        # 벽돌을 모두 없애면 승리
        if not bricks:
            state = "clear"

    # ---------- 그리기 ----------
    screen.fill(BG)

    for b in bricks:
        pygame.draw.rect(screen, b["color"], b["rect"], border_radius=5)

    pygame.draw.rect(screen, PADDLE_COLOR, paddle, border_radius=7)
    pygame.draw.circle(screen, BALL_COLOR, (int(ball_x), int(ball_y)), BALL_R)

    screen.blit(font.render(f"점수 {score}", True, TEXT), (16, 20))
    lives_img = font.render(f"목숨 {lives}", True, TEXT)
    screen.blit(lives_img, (W - lives_img.get_width() - 16, 20))

    if state != "play":
        msg = "게임 오버" if state == "over" else "클리어!"
        msg_img = big_font.render(msg, True, TEXT)
        sub_img = font.render("스페이스를 누르면 다시 시작", True, TEXT)
        screen.blit(msg_img, msg_img.get_rect(center=(W // 2, H // 2 - 20)))
        screen.blit(sub_img, sub_img.get_rect(center=(W // 2, H // 2 + 30)))

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

pygame.quit()
