[Toy PJT] 지상 최강의 피카츄를 만들기 위한 gymnasium 강화 학습 환경

Park Yeongseo·2024년 5월 1일
1

Project

목록 보기
5/5

깃허브 리포지토리는 여기

어쩌다 보니 공을 튀기는 것만 세 번째 하게 됐다. 16년도, 학교 기숙사에 살 때 룸메이트랑 종종 내기 피카츄 배구를 하곤 했는데, 거의 이겨본 적이 없었다(지금도 마찬가지임). 이후 둘 다 전역하고 자율로봇지능 강의를 함께 들었는데, 그 학기가 끝나고 피카츄 배구 강화 학습을 해보자는 아이디어가 나왔다. 나는 이길 수 없지만 내가 학습시킨 지상 최강의 피카츄는 다르지 않을까?

피카츄 배구 원작 게임을 리버스 엔지니어링해 자바스크립트로 만든 이 리포지토리의 코드가 이미 있어 이를 파이썬으로 재작성(Pykachu ㅋㅋ)하기만 하면 됐지만, 파이썬으로 화면을 어떻게 그리는지를 몰라 만들다가 도중에 그만 뒀었다. 예전에 올린 포켓볼 시뮬레이터와 마찬가지로, 이번에 경험 정리 겸 깃허브에 방치해놨던 코드들을 정리하면서 다시 만들었다.


1. 개요

리포지토리 의 코드를 바탕으로, 강화 학습을 위한 gymnasium 라이브러리에 맞게 파이썬으로 재작성했습니다. 지금은 멀티-에이전트가 아니라, 원래 게임에 구현되어 있는 컴퓨터를 상대로 하는 싱글-에이전트 학습 환경입니다. 멀티-에이전트 학습 환경은 추후 pettingzoo를 사용해 추가될 예정입니다.

나타나는 화면은 pygame을 이용해 구현했습니다. 개발은 다음과 같은 환경에서 진행됐습니다.

envversion
Ubuntu22.04
Python3.10.12
gymnasium0.29.1
pygame2.5.2
numpy1.26.4

2. 설명

#this is in sample.py
import gymnasium as gym
import pykachu_env

env = gym.make('PykachuVolleyball-v0', 
               render_mode= "human", 
               is_player_2_computer=False)

리포지토리에 있는 sample.py를 참고합시다. 학습 환경은 패키지를 임포트한 후, gym.make('PykachuVolleyball-v0')를 통해 만듭니다. 추가적으로 render_mode, is_player_2_computer 옵션을 줄 수 있습니다. is_player_2_computer는 두 플레이어 중 어느 쪽이 상대편인 컴퓨터가 될지를 결정합니다.

Action SpaceMultiDiscrete([3, 3, 1])
Observation Space(432, 304, 3)
Observation High255
Observation Low0

Action Space

action space는 MultiDiscrete([3, 3, 1])로, 각각 순서대로 좌우 이동, 상하 이동, 강타?의 입력에 해당합니다.

action_space[0] (좌우 이동)

ValueMeaning
0input left movement
1NOOP
2input right movement

action_space[1] (상하 이동)

ValueMeaning
0input up movement
1NOOP
2input down movement

action_space[2] (강타)

ValueMeaning
0NOOP
1input power hit

Observation Space

observation space는 Box(low=0, high=255, shape=(432, 304, 3), dtype=np.uint8)로, 그려진 화면의 RGB값 배열에 해당합니다.

#this is in sample.py
for episode in range(5):
    env.reset()

    while True:
        env.render()
        action = env.action_space.sample()
        state, reward, terminated, info = env.step(action)
        if terminated:
            break

env.close()

step() 함수는 observation 뿐만 아니라, reward, terminated, info도 반환합니다.

reward

학습 중인 플레이어가 이기면 +1, 지면 -1의 보상을 받습니다.

terminated

공이 땅에 닿아 새 라운드가 시작되어야 하면 True, 그렇지 않으면 False가 됩니다.

info

info에는 아래와 같은 추가 정보들이 들어있습니다.

{
    "player1": {
        "x": player1.x,
        "y": player1.y,
        "dive_direction" : player1.dive_direction 
    },
    "player2":{
        "x": player2.x,
        "y": player2.y,
        "dive_direction" : player2.dive_direction 
    },
    "ball": {
        "x": ball.x,
        "x_velocity": ball.x_velocity,
        "y": ball.y,
        "y_velocity": ball.y_velocity,
    }
}

3. TODOs

코드가 gymnasium API와 완전히 호환되지는 않을 수 있기 때문에, 버그가 발생하거나 추가적인 구현이 필요한 경우는 알려주세요

profile
꾸준함, 기본기, 성찰, 공유

3개의 댓글

comment-user-thumbnail
2024년 5월 2일

Pykachu라.. 작명센스 좋네ㅛ

1개의 답글