코딩 테스트/파이썬

[파이썬 게임] Chimp Memory Game

HHRR 2023. 5. 10. 05:39
  • chimp memory game
    • 격자 : 5 rows(행), 9 columns(열)
    • start 버튼
    • 6 numbers (순차 증가)
    • 격자에 숫자 랜덤 위치하기
    • Hide Numbers : 1. Display Time, 2. First Number
        1. 시간이 지난 후에 숫자 숨겨짐
        1. 1을 누르면 나머지 숫자 숨겨짐
    • Correct → Next Level
    • Wrong → Game Over
  • 프레임 : 1_frame
    • 가로 1280, 세로 720
import pygame

#초기화
pygame.init()
screen_width = 1280 #가로크기
screen_height = 720 #세로크기
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Memory Game")

#게임 루프
running = True #게임이 실행중인가?ㅇ
while running :
    #이벤트 루프
    for event in pygame.event.get(): #어떤 이벤트가 발생하였는가?
        if event.type == pygame.QUIT : #창이 닫히는 이벤트인가?
            running = False #게임이 더이상 실행중이 아님
            
#게임 종료
pygame.quit()
  • start screen
    • start_button (120*120, 중심 좌표 동일, 반지름 60, 두께 5)
    • pygame.draw.circle 이용하여 원 그리기
    import pygame
    
    #시작 화면 보여주기
    def display_start_screen() :
        pygame.draw.circle(screen, WHITE, start_button.center, 60, 5) #흰색 원, 중심좌표 start_button의 중심좌표, 반지름 60, 두꼐 5
    
    #초기화
    pygame.init()
    screen_width = 1280 #가로크기
    screen_height = 720 #세로크기
    screen = pygame.display.set_mode((screen_width, screen_height))
    pygame.display.set_caption("Memory Game")
    
    #시작 버튼
    start_button = pygame.Rect(0,0,120,120) #가로 세로 120
    start_button.center = (120, screen_height-120 ) #x좌표,y좌표 기준으로 중심값 설정
    
    #색깔
    BLACK = (0,0,0) #RGB 
    WHITE = (255,255,255)
    
    #게임 루프
    running = True #게임이 실행중인가?ㅇ
    while running :
        #이벤트 루프
        for event in pygame.event.get(): #어떤 이벤트가 발생하였는가?
            if event.type == pygame.QUIT : #창이 닫히는 이벤트인가?
                running = False #게임이 더이상 실행중이 아님
    
        #화면 전체를 까맣게 칠함
        screen.fill(BLACK)
    
        #시작 화면 표시
        display_start_screen()
    
        #화면 업데이트
        pygame.display.update()
    
                
    #게임 종료
    pygame.quit()
    
  • start button click
import pygame

#시작 화면 보여주기
def display_start_screen() :
    pygame.draw.circle(screen, WHITE, start_button.center, 60, 5) #흰색 원, 중심좌표 start_button의 중심좌표, 반지름 60, 두꼐 5

#게임 화면 보여주기
def display_game_screen():
    print("Game Start")

#pos에 해당하는 버튼 확인
def check_buttons(pos):
    global start #start 변수 전역변수로 선언
    if start_button.collidepoint : #사각형 정보 내에서 pos 위치하는지 확인하는 함수
        start = True #display_game_screen() 실행

#초기화
pygame.init()
screen_width = 1280 #가로크기
screen_height = 720 #세로크기
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Memory Game")

#시작 버튼
start_button = pygame.Rect(0,0,120,120) #가로 세로 120
start_button.center = (120, screen_height-120 ) #x좌표,y좌표 기준으로 중심값 설정

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

#게임 시작 여부
start = False

#게임 루프
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.quit()
  • game screen
    • number_count = (level//3)+5 #//:몫
    • number_count = min(number_count, 20) #숫자 최댓값 20level number_count
    • 5 row (5개의 리스트), 9 column → 2차원 배열
    • grid = [[0 for col in range(columns)] for row in range(rows)]
    • [[0,0,0,0,0,0,0,0,0],…,[0,0,0,0,0,0,0,0,0]]
import pygame
from random import *

#레벨에 맞게 설정
def setup(level) :
    #얼마나 많은 숫자를 보여줄 것인가?
    number_count = (level // 3) + 5 # //:몫
    number_count = min(number_count, 20) #만약 20을 초과하면 20으로 처리

    #실제 화면에 grid형태로 숫자를 랜덤으로 배치
    shuffle_grid(number_count)

#숫자 섞기(이 프로젝트에서 가장 중요)
def shuffle_grid(number_count) :
    rows = 5
    columns = 9

    # [[0, 0, 0, 0, 0, 0, 0, 0, 0],
    # [0, 0, 5, 0, 0, 0, 0, 3, 0],
    # [0, 0, 0, 1, 0, 0, 0, 0, 0],
    # [0, 4, 0, 0, 0, 2, 0, 0, 0],
    # [0, 0, 0, 0, 0, 0, 0, 0, 0]]
    grid = [[0 for col in range(columns)] for row in range(rows)] #5 x 9

    number = 1 #시작 숫자 1부터 number_count까지, 만약 5라면 5까지 숫자를 랜덤으로 배치
    while number <= number_count :
        row_idx = randrange(0, rows) #0~5 중에서 랜덤으로 뽑기
        col_idx = randrange(0, columns) #0~8 중에서 랜덤으로 뽑기

        if grid[row_idx][col_idx] == 0 :
            grid[row_idx][col_idx] = number #숫자 지정
            number += 1

    #배치된 랜덤 숫자 확인
    print(grid)
    

#시작 화면 보여주기
def display_start_screen() :
    pygame.draw.circle(screen, WHITE, start_button.center, 60, 5) #흰색 원, 중심좌표 start_button의 중심좌표, 반지름 60, 두꼐 5

#게임 화면 보여주기
def display_game_screen():
    print("Game Start")

#pos에 해당하는 버튼 확인
def check_buttons(pos):
    global start #start 변수 전역변수로 선언
    if start_button.collidepoint : #사각형 정보 내에서 pos 위치하는지 확인하는 함수
        start = True #display_game_screen() 실행

#초기화
pygame.init()
screen_width = 1280 #가로크기
screen_height = 720 #세로크기
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Memory Game")

#시작 버튼
start_button = pygame.Rect(0,0,120,120) #가로 세로 120
start_button.center = (120, screen_height-120 ) #x좌표,y좌표 기준으로 중심값 설정

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

#게임 시작 여부
start = False

#게임 시작 전에 게임 설정 함수 수행
setup(1)

#게임 루프
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.quit()
  • 격자
    • cell_size = 130
    • button_size = 110
    • screen_left_margin = 55
    • screen_top_margin = 20
    • 각 셀의 중간 좌표값 :
      • center_x = screen_left_margin + (col_indexcell_size) + (cell_size/2)
      • center_y = screen_top_margin + (row_idxcell_size) + (cell_size/2)
  • 숫자 숨기기
    1. 시간 초과
      - display_time = 5 - (level//3)
      - display_time = max(display_time, 1)level display_time
    2. 1 클릭
      [(x1,y1)…(x6,y6)] click→버튼 없애줌
      (x1,y1) 리스트에서 빼기 순서대로 클릭해야함. 그렇지 않으면 게임종료
  • setup
    • list 공백 → next level
    • 실수 → 당시 레벨 보여준 후 게임 종료
  • 최종 코드
import pygame
from random import *

#레벨에 맞게 설정
def setup(level) :
    #얼마동안 숫자를 보여줄 지
    global display_time
    display_time = 5 - (level//3)
    display_time = max(display_time, 1) #1초 미만이면 1초로 차이

    #얼마나 많은 숫자를 보여줄 것인가?
    number_count = (level // 3) + 5 # //:몫
    number_count = min(number_count, 20) #만약 20을 초과하면 20으로 처리

    #실제 화면에 grid형태로 숫자를 랜덤으로 배치
    shuffle_grid(number_count)

#숫자 섞기(이 프로젝트에서 가장 중요)
def shuffle_grid(number_count) :
    rows = 5
    columns = 9

    cell_size = 130 #각 grid cell 별 가로, 세로 크기
    button_size = 110 #grid cell 내에 실제로 그려질 버튼 크기
    screen_left_margin = 55 #전체 스크린 왼쪽 여백
    screen_top_margin = 20 #전체 스크린 위쪽 여백

    # [[0, 0, 0, 0, 0, 0, 0, 0, 0],
    # [0, 0, 5, 0, 0, 0, 0, 3, 0],
    # [0, 0, 0, 1, 0, 0, 0, 0, 0],
    # [0, 4, 0, 0, 0, 2, 0, 0, 0],
    # [0, 0, 0, 0, 0, 0, 0, 0, 0]]
    grid = [[0 for col in range(columns)] for row in range(rows)] #5 x 9

    number = 1 #시작 숫자 1부터 number_count까지, 만약 5라면 5까지 숫자를 랜덤으로 배치
    while number <= number_count :
        row_idx = randrange(0, rows) #0~5 중에서 랜덤으로 뽑기
        col_idx = randrange(0, columns) #0~8 중에서 랜덤으로 뽑기

        if grid[row_idx][col_idx] == 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) 
    #흰색 원, 중심좌표 start_button의 중심좌표, 반지름 60, 두꼐 5

    msg = game_font.render(f"{curr_level}", True, WHITE)
    msg_rect = msg.get_rect(center=start_button.center)
    screen.blit(msg, msg_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) : #리스트 값 가져오고 값을 rect에 집어넣고 인덱스 idx에 집어넣음
        if hidden: #숨김 처리
            #버튼 사각형 그리기
            pygame.draw.rect(screen, WHITE, 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)


#pos에 해당하는 버튼 확인
def check_buttons(pos):
    global start, start_ticks #start 변수 전역변수로 선언

    if start : #게임이 시작했으면?
        check_number_buttons(pos)
    elif start_button.collidepoint(pos) : #사각형 정보 내에서 pos 위치하는지 확인하는 함수
        start = True #display_game_screen() 실행
        start_ticks = pygame.time.get_ticks() #타이머 시작(현재 시간을 저장)

def check_number_buttons(pos) :
    global hidden, start, curr_level #hidden은 전역공간, hidden에 값 넣기 위해 global -> 전역공간에 있는 변수 쓸거라는 것 명시

    for button in number_buttons:
        if button.collidepoint(pos) :
            if button == number_buttons[0]: #올바른 숫자 클릭
                print("Correct")
                del number_buttons[0] #첫번째 위치 지우기
                if not hidden : 
                    hidden = True #숫자 숨김 처리
            else : #잘못된 숫자 클릭
                game_over()
                print("Wrong")
            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("Memory Game")
game_font = pygame.font.Font(None, 120) #폰트 정의

#시작 버튼
start_button = pygame.Rect(0,0,120,120) #가로 세로 120
start_button.center = (120, screen_height-120 ) #x좌표,y좌표 기준으로 중심값 설정

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

number_buttons = [] #플레이어가 눌러야 하는 버튼들
curr_level = 1 #현재 레벨
display_time = None #숫자를 보여주는 시간
start_ticks = None #시간 계산 (현재 시간 정보를 저장)

#게임 시작 여부
start = False

#숫자 숨김 여부(사용자가 1을 클릭 했거나, 보여주는 시간 초과했을 떄)
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()

#5초정도 보여주는 역할
pygame.time.delay(5000)       

#게임 종료
pygame.quit()

 

 

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