본문 바로가기

내일배움캠프/사전과제

[내일배움캠프] - 사전과제3 : 파이썬으로 게임 만들기2

침팬지가 하는 기억력 테스트 게임

 

[강의] - 파이썬 실전 프로젝트 | 기억력 테스트 게임, 침팬지를 이겨라 :: pygame | 나도코딩

https://www.youtube.com/watch?v=Qsk-xsi73YA&list=PLMsa_0kAjjrdqJ1rJba9MFWYv-GHluK4_&index=1

'파이썬으로 만든 기억력 게임'

 

import pygame
from random import *

# 레벨 설정
def setup(level):
    global display_time

    # 얼마나 오래 숫자 정보를 보여줄 것인가?
    display_time = 5 - (level // 3) # level별 시간 
    display_time = max(display_time, 1) # 최소 시간

    # 얼마나 많은 숫자를 테스트할 것인가?
    number_count = (level // 3) + 5 # level별 숫자 표시 개수
    number_count = min(number_count, 20) # 최대 숫자 표시 개수

    # grid 형태로 숫자를 랜덤으로 배치
    shuffle_grid(number_count)

# 숫자 섞기
def shuffle_grid(number_count):
    rows = 5
    columns = 9

    cell_size = 130 # 셀 크기
    button_size = 110 # 버튼 크기
    screen_left_margin = 55 # 화면 왼쪽 여백
    screen_top_margin = 20 # 화면 위쪽 여백

    grid = [[0 for col in range(columns)] for row in range(rows)] # 5 x 9

    number = 1 # 시작 숫자
    while number <= number_count:
        row_idx = randrange(0, rows) # 0 ~ 4 중 위치 랜덤 뽑기
        col_idx = randrange(0, columns) # 0 ~8 중 위치 랜덤 뽑기

        if grid[row_idx][col_idx] == 0: # 0으로만 이루어진 리스트 중 한 지점
            grid[row_idx][col_idx] = number # 랜덤 표시 위치를 순서대로 지정
            number += 1

            # 현재 grid cell 위치기준 x, y 좌표
            center_x = screen_left_margin + (col_idx * cell_size) + (cell_size / 2)
            center_y = screen_top_margin + (row_idx * cell_size) + (cell_size / 2)

            # 버튼 생성
            button = pygame.Rect(0, 0, button_size, button_size)
            button.center = (center_x, center_y)
            number_buttons.append(button)

    print(grid)

# 시작화면 보여주기
def display_start_screen():
    pygame.draw.circle(screen, WHITE, start_button.center, 60, 5)
    msg_start_button = game_font_start.render(f"start", True, WHITE)
    msg_start_button_rect = msg_start_button.get_rect(center=start_button.center)

    msg_start = game_font.render(f"level {curr_level}", True, WHITE)
    msg_start_rect = msg_start.get_rect(center=(screen_width / 2, screen_height / 2))

    screen.blit(msg_start_button, msg_start_button_rect)
    screen.blit(msg_start, msg_start_rect)

# 게임화면 보여주기
def display_game_screen():
    global hidden

    if not hidden:
        elapsed_time = (pygame.time.get_ticks() - start_ticks) / 1000 # ms -> sec
        if elapsed_time > display_time:
            hidden = True

    for idx, rect in enumerate(number_buttons, start=1):
        if hidden:
            # 버튼 숨김 처리
            pygame.draw.rect(screen, GRAY, rect)
        else:
            # 숫자 텍스트 표시
            cell_text = game_font.render(str(idx), True, WHITE)
            text_rect = cell_text.get_rect(center=rect.center)
            screen.blit(cell_text, text_rect)

# 클릭좌표-버튼좌표 비교
def check_buttons(pos): # pos: 마우스 클릭 좌표
    global start, start_ticks # 전역변수의 값을 바꾸기 위해선 명시주어야함

    if start:
        check_number_buttons(pos)
    elif start_button.collidepoint(pos): # start_button의 좌표들 안에 파라미터(pos)값이 있을 경우
        start = True
        start_ticks = pygame.time.get_ticks() # 타이머 시작(현재 시간을 저장)

def check_number_buttons(pos): # pos: 마우스 클릭 좌표
    global start, hidden, curr_level

    for button in number_buttons:
        if button.collidepoint(pos): # button의 좌표들 안에 파라미터(pos)값이 있을 경우
            if button == number_buttons[0]: # 올바른 숫자 클릭
                print("good")
                del number_buttons[0] # 맞춘 숫자를 지움
                if not hidden:
                    hidden = True # 숫자 숨김 처리(자동 숨김처리가 되지 않았어도 게임을 시작하면 바로 숨김처리하게 됨)
            else: # 잘못된 숫자 클릭
                print("wrong")
                game_over()
            break

    # 모든 숫자가 삭제되면 다음 레벨로 넘어감
    if len(number_buttons) == 0:
        start = False
        hidden = False
        curr_level += 1
        setup(curr_level) # 레벨 설정을 다시 해줌

# 게임 종료
def game_over():
    global running
    running = False

    msg = game_font.render(f"Your level is {curr_level}", True, WHITE)
    msg_rect = msg.get_rect(center=(screen_width / 2, screen_height / 2))

    screen.fill(BLACK)
    screen.blit(msg, msg_rect)

# 초기화
pygame.init()
screen_width = 1280 # 가로 길이
screen_height = 720 # 세로 길이
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("기억력 게임")
game_font = pygame.font.Font(None, 120) # 폰트 정의
game_font_start = pygame.font.Font(None, 50)



# 시작 버튼
start_button = pygame.Rect(0, 0, 120, 120)
start_button.center = (120, screen_height - 120)

# 색깔
BLACK = (0, 0, 0) # colors RGB
WHITE = (255, 255, 255)
GRAY = (220, 220, 220)

# 버튼 위치
number_buttons = [] # 버튼이 표시될 랜덤 위치

# 현재 레벨
curr_level = 1

# 시간 설정
display_time = None # 숫자 표시 시간
start_ticks = None # 시간 계산

# 게임 시작 여부
start = False

# 숫자 숨김 여부
hidden = False

# 게임 레벨 지정(레벨)
setup(curr_level)

# 게임 루프
running = True
while running:
    click_pos = None

    # 이벤트 루프
    for event in pygame.event.get(): # 어떤 이벤트가 발생하였는가?
        if event.type == pygame.QUIT: # 창이 닫히는 이벤트
            running = False
        elif event.type == pygame.MOUSEBUTTONUP: # 마우스가 클릭되는 이벤트
            click_pos = pygame.mouse.get_pos()
            print(click_pos)
            
    # 화면 표시
    screen.fill(BLACK) # 화면 색 지정

    if start:
        display_game_screen() # 게임 화면 표시
    else:
        display_start_screen() # 시작 화면 표시

    # 클릭 좌표값이 있을 경우
    if click_pos:
        check_buttons(click_pos)

    # 화면 업데이트
    pygame.display.update()

pygame.time.delay(5000)

# 게임 종료
pygame.quit()