# ===== CodeLab: Python 小游戏⑦:打地鼠(pygame) =====
# 来源: https://aoerliang.dpdns.org/articles/game-python-whack
# 以下代码片段按文章出现顺序拼接, 共 4 段

# ----- 片段 1 (python) -----
import random, pygame

HOLES = 9            # 3x3 个洞
up_until = [0] * HOLES          # 每个洞的"缩回时间"
next_up = 0                     # 下一次冒头时间

def update(now):
    global next_up
    if now >= next_up:                       # 到点冒头
        i = random.randrange(HOLES)
        up_until[i] = now + random.randint(800, 1400)
        next_up = now + random.randint(400, 900)
    for i in range(HOLES):                   # 到点缩回
        if now >= up_until[i]:
            up_until[i] = 0

# ----- 片段 2 (python) -----
def on_click(pos, now):
    global score
    i = hole_at(pos)          # 像素坐标 -> 洞编号
    if i is None or now >= up_until[i] or up_until[i] == 0:
        return
    score += 1
    up_until[i] = 0           # 打中就缩回

# ----- 片段 3 (python) -----
START = 30000          # 30 秒(毫秒)
start_time = pygame.time.get_ticks()
game_over = False

while not game_over:
    now = pygame.time.get_ticks()
    if now - start_time >= START:
        game_over = True
        print('时间到!得分:', score)
        break

# ----- 片段 4 (python) -----
import random, pygame

W, H = 480, 520
pygame.init()
screen = pygame.display.set_mode((W, H))
clock = pygame.time.Clock()
font = pygame.font.SysFont('simhei', 30)

HOLES = 9
CELL = 120
OX, OY = 60, 60           # 第一行洞的左上角
up_until = [0] * HOLES
next_up = 0
score = 0
START = 30000
start_time = pygame.time.get_ticks()
game_over = False

def hole_rect(i):
    r, c = divmod(i, 3)
    return (OX + c * CELL, OY + r * CELL, CELL - 10, CELL - 10)

def hole_at(pos):
    mx, my = pos
    for i in range(HOLES):
        x, y, w, h = hole_rect(i)
        if x <= mx <= x + w and y <= my <= y + h:
            return i
    return None

def update(now):
    global next_up
    if now >= next_up:
        i = random.randrange(HOLES)
        up_until[i] = now + random.randint(800, 1400)
        next_up = now + random.randint(400, 900)
    for i in range(HOLES):
        if now >= up_until[i]:
            up_until[i] = 0

def draw(now):
    screen.fill((60, 120, 60))
    for i in range(HOLES):
        x, y, w, h = hole_rect(i)
        pygame.draw.ellipse(screen, (90, 70, 40), (x, y + h // 2, w, h // 2))
        if up_until[i] > now:
            pygame.draw.circle(screen, (160, 110, 70), (x + w // 2, y + h // 2 - 10), 26)
            pygame.draw.circle(screen, (20, 20, 20), (x + w // 2 - 10, y + h // 2 - 14), 4)
            pygame.draw.circle(screen, (20, 20, 20), (x + w // 2 + 10, y + h // 2 - 14), 4)
    left = max(0, (START - (now - start_time)) // 1000)
    screen.blit(font.render('时间: %ds  得分: %d' % (left, score), True, (255, 255, 255)), (20, 470))
    pygame.display.flip()

while not game_over:
    now = pygame.time.get_ticks()
    if now - start_time >= START:
        game_over = True
        break
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            pygame.quit(); raise SystemExit
        if e.type == pygame.MOUSEBUTTONDOWN and e.button == 1:
            i = hole_at(e.pos)
            if i is not None and up_until[i] > now:
                score += 1
                up_until[i] = 0
    update(now)
    draw(now)
    clock.tick(30)
print('时间到!得分:', score)
