상세 컨텐츠

본문 제목

PingPongGame

정보과학융합탐구

by yalu 2023. 5. 16. 20:04

본문

강화학습을 사용하는 프로잭트를 하기 위해 공부 할 예정입니다.

강화학습은 학습하기 위한 가상환경을 필요로 하는데, 그래서 가상환경을 만들어 보았음

 

ping pong 게임은 모두가 알텐데, 양쪽의 두 paddle을 위 아래로 움직이며 중앙의 공을 튕겨내야합니다.

 

대략적인 순서도는 다음과 같다.


  1. pygame 초기화
  2. 게임 창 크기 설정
  3. 색상 설정
  4. 게임 창 생성
  5. 게임 창 제목 설정
  6. 폰트 설정
  7. 플레이어 점수 초기화
  8. Paddle 클래스 정의
    • Paddle 초기화
    • Paddle 그리기
    • Paddle 이동 (위로/아래로)
  9. Ball 클래스 정의
    • Ball 초기화
    • Ball 그리기
    • Ball 이동
    • Ball 튕김 처리
  10. Paddle과 Ball 인스턴스 생성
  11. 게임 루프
    11.1. 이벤트 처리
    11.2. 키 입력 처리하여 paddle 이동
    11.3. 공과 paddle의 충돌 처리
    11.4. 공의 점수 계산과 새로운 공 생성
    11.5. 공의 이동 및 튕김 처리
    11.6. 게임 화면 업데이트
    11.7. 점수 표시
    11.8. 화면 업데이트

import pygame
import sys
from pygame.locals import *
import random

clock = pygame.time.Clock()

# pygame 초기화
pygame.init()

# 게임 창 크기 설정
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600

# 색상 설정
BLACK = (0, 0, 0)  # 검은색
WHITE = (255, 255, 255)  # 흰색

# 공과 paddle의 속도 설정
BALL_SPEED_X = 5
BALL_SPEED_Y = 5
PADDLE_SPEED = 7

# 게임 창 생성
WINDOW = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))

# 게임 창 제목 설정
pygame.display.set_caption("Ping Pong 게임")

# 폰트 설정
FONT = pygame.font.SysFont(None, 40)

# 플레이어 점수 초기화
player1_score = 0
player2_score = 0

# Paddle 클래스 정의

class Paddle:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 10
        self.height = 100
        self.rect = pygame.Rect(self.x, self.y, self.width, self.height)

    def draw(self):
        pygame.draw.rect(WINDOW, WHITE, self.rect)

    def move_up(self):
        self.y -= PADDLE_SPEED
        self.rect.y = self.y

    def move_down(self):
        self.y += PADDLE_SPEED
        self.rect.y = self.y

# Ball 클래스 정의

class Ball:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 10
        self.height = 10
        self.rect = pygame.Rect(self.x, self.y, self.width, self.height)
        self.speed_x = BALL_SPEED_X
        self.speed_y = BALL_SPEED_Y

    def draw(self):
        pygame.draw.rect(WINDOW, WHITE, self.rect)

    def move(self):
        self.x += self.speed_x
        self.y += self.speed_y
        self.rect.x = self.x
        self.rect.y = self.y

    def bounce(self):
        if self.y <= 0 or self.y >= WINDOW_HEIGHT - self.height:
            self.speed_y *= -1
        if self.x <= 0 or self.x >= WINDOW_WIDTH - self.width:
            self.speed_x *= -1

# Paddle과 Ball 인스턴스 생성
player1_paddle = Paddle(20, WINDOW_HEIGHT/2 - 50)  # 왼쪽 paddle
player2_paddle = Paddle(WINDOW_WIDTH - 30, WINDOW_HEIGHT/2 - 50)  # 오른쪽 paddle
ball = Ball(WINDOW_WIDTH/2 - 5, WINDOW_HEIGHT/2 - 5)  # 공

# 게임 루프
while True:
    clock.tick(60)  # FPS 설정

    # 이벤트 처리
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                pygame.quit()
                sys.exit()

    # 키 입력 처리하여 paddle 이동
    keys = pygame.key.get_pressed()
    if keys[K_w] and player1_paddle.y > 0:  # W 키를 누르면 왼쪽 paddle을 위로 이동
        player1_paddle.move_up()
    if keys[K_s] and player1_paddle.y < WINDOW_HEIGHT - player1_paddle.height:  # S 키를 누르면 왼쪽 paddle을 아래로 이동
    player1_paddle.move_down()
    if keys[K_UP] and player2_paddle.y > 0:  # 위쪽 화살표 키를 누르면 오른쪽 paddle을 위로 이동
    player2_paddle.move_up()
    # 아래쪽 화살표 키를 누르면 오른쪽 paddle을 아래로 이동
    if keys[K_DOWN] and player2_paddle.y < WINDOW_HEIGHT - player2_paddle.height:
    player2_paddle.move_down()
    # 공과 paddle의 충돌 처리
    if ball.rect.colliderect(player1_paddle.rect):
        ball.speed_x *= -1
    if ball.rect.colliderect(player2_paddle.rect):
        ball.speed_x *= -1

    # 공의 점수 계산과 새로운 공 생성
    if ball.x <= ball.width:
        player2_score += 1
        ball = Ball(WINDOW_WIDTH/2 - 5, WINDOW_HEIGHT/2 - 5)
        ball.speed_x *= random.choice([1, -1])
    if ball.x >= WINDOW_WIDTH - ball.width:
        player1_score += 1
        ball = Ball(WINDOW_WIDTH/2 - 5, WINDOW_HEIGHT/2 - 5)
        ball.speed_x *= random.choice([1, -1])

    # 공의 이동 및 튕김 처리
    ball.bounce()
    ball.move()

    # 게임 화면 업데이트
    WINDOW.fill(BLACK)  # 검은색으로 화면 채우기
    player1_paddle.draw()  # 왼쪽 paddle 그리기
    player2_paddle.draw()  # 오른쪽 paddle 그리기
    ball.draw()  # 공 그리기

    # 점수 표시
    player1_score_text = FONT.render(str(player1_score), True, WHITE)
    player2_score_text = FONT.render(str(player2_score), True, WHITE)
    WINDOW.blit(player1_score_text, (WINDOW_WIDTH/4, 20))
    WINDOW.blit(player2_score_text, (3*WINDOW_WIDTH/4, 20))

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

 

ping pong 게임을 구현한 코드


실행화면


오류 해결과정 : 공이 처음 만들어질 때 초기 속도를 설정하는데에 어려움을 겪음, random.choice 메소드를 사용하여 초기 방향이 한쪽으로만 치우치치 않게했습니다.

 

 

'정보과학융합탐구' 카테고리의 다른 글

웹 개발의 백엔드와 프론트엔드에 대해 알아보자  (0) 2023.07.03
소수 판별 알고리즘  (0) 2023.05.31
Deep Learning Framework란?  (0) 2023.05.31
DQNAgent  (1) 2023.05.16
ANN과 ForwardPass의 구현  (0) 2023.03.30

관련글 더보기