강화학습을 사용하는 프로잭트를 하기 위해 공부 할 예정입니다.
강화학습은 학습하기 위한 가상환경을 필요로 하는데, 그래서 가상환경을 만들어 보았음
ping pong 게임은 모두가 알텐데, 양쪽의 두 paddle을 위 아래로 움직이며 중앙의 공을 튕겨내야합니다.
대략적인 순서도는 다음과 같다.
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 |