Beispiel #1
0
def main():
    pygame.init()
    screen = pygame.display.set_mode((SCR_RECT.width, SCR_RECT.height))
    pygame.display.set_caption("Rappy-AI")

    font = pygame.font.Font(None, 48)
    clock = pygame.time.Clock()
    img_dict = {}  # 画像は辞書型で登録

    load_img(img_dict, os.path.join("img", "wall.png"), "wall")  # wallで画像を登録
    load_img(img_dict, os.path.join("img", "rappy.png"), "bird")  # birdで画像を登録

    game_scene = GameScene(img_dict=img_dict, font=font, SCR_RECT=SCR_RECT)

    # while True:
    while not game_scene.get_exit_flag():
        clock.tick(60)  # 60fps
        game_scene.step()
        game_scene.render(screen)
Beispiel #2
0
class RappyEnv(gym.Env):
    metadata = {
        'render.modes': ['human', 'rgb_array'],
        'video.frames_per_second' : 50
    }

    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((SCR_RECT.width, SCR_RECT.height))
        pygame.display.set_caption("Rappy-AI")
        
        self.font = pygame.font.Font(None, 48)
        self.clock = pygame.time.Clock()
        self.img_dict = {} # 画像は辞書型で登録

        load_img(self.img_dict, os.path.join("img", "wall.png"), "wall") # wallで画像を登録
        load_img(self.img_dict, os.path.join("img","rappy.png"), "bird") # birdで画像を登録

        self.game_scene = GameScene(img_dict=self.img_dict, font=self.font, SCR_RECT=SCR_RECT) 
        self.score = 0

        # 行動空間の定義(0, 1)
        self.action_space = spaces.Discrete(2)

        # 状態空間の最大と最小を定義
        # low = np.array([0, -WINDOW_HEIGHT])
        # high = np.array([WINDOW_WIDTH, WINDOW_HEIGHT])
        
        # ラッピーのy座標、y方向速度、壁の隙間の座標x,yの順番
        low = np.array([0, -GameScene.PLAYER_SPEED_MAX, 0, 0])
        high = np.array([DIVIDE_NUM_Y, GameScene.PLAYER_SPEED_MAX, DIVIDE_NUM_X, DIVIDE_NUM_Y])

        self.observation_space = spaces.Box(low=low, high=high)

        self._seed()
        self.screen = None
        self._reset()

    def _seed(self, seed=None):
        self.np_random, seed = seeding.np_random(seed)
        return [seed]

    def _step(self, action):
        assert self.action_space.contains(action), "%r (%s) invalid" %(action, type(action))

        # 無条件報酬(生存時間あたりの報酬)
        reward = 0.0 # y座標に比例して増やす報酬を下に追加したため一旦0に変更

        self.game_scene.step(action)

        # self.state = self.game_scene.get_nearest_gap_distance()
        # state計算(ラッピーのy座標、yスピード、隙間のx座標、y座標)
        self.state = np.array([simplify_pos(self.game_scene.get_rappy_pos()[1], SCR_RECT.height, DIVIDE_NUM_Y),
                      self.game_scene.get_rappy_speed(),
                      simplify_pos(self.game_scene.get_nearest_gap_pos()[0], SCR_RECT.width, DIVIDE_NUM_X),
                      simplify_pos(self.game_scene.get_nearest_gap_pos()[1], SCR_RECT.height, DIVIDE_NUM_Y)])

        # ジャンプした場合にマイナスの報酬(ジャンプしすぎるので)。
        # 連続でジャンプした場合に限定(2020/07/26)
        if action == 1 and self.game_scene.get_rappy_speed() <= -GameScene.PLAYER_SPEED_MAX + 1:
            #reward += -50.0
            reward += -1.0

        # 天井に接着しているときマイナスの報酬
        if self.game_scene.is_rappy_on_top():
            reward += 0.0

        # スコアを獲得したときの報酬
        if self.score < self.game_scene.get_score():
            reward += 3000.0
            self.score = self.game_scene.get_score()
        else:
            reward += 0.0

        # ラッピーのy座標と隙間のy座標が近ければ近いほど報酬が多くもらえる
        # reward += np.round((DIVIDE_NUM_Y - (abs(self.state[3] - self.state[0]))) / 10, decimals=2)
        reward += DIVIDE_NUM_Y - (abs(self.state[3] - self.state[0]))
        
        done = self.game_scene.is_rappy_dead() or self.game_scene.count > 1000

        if done:
            # 死んだときマイナスの報酬
            reward += -500.0

            # 死亡地点にて、隙間との距離に応じて追加報酬もあり→加点だと、壁にぶつかることで報酬が増えると勘違いされる可能性がある
            # reward += (DIVIDE_NUM_Y - (abs(self.state[3] - self.state[0]))) ** 2
            reward += -((self.state[3] - self.state[0]) ** 2)
            self.game_scene.exit()

        return np.array(self.state), reward, done, {}

    def _reset(self):
        # とりあえず画面右端の真ん中に隙間がある状態を初期状態とする
        self.game_scene.init()
        # self.state = np.array([SCR_RECT.width / 2, 0])
        self.state = np.array([DIVIDE_NUM_Y / 2, 0, DIVIDE_NUM_X / 2, DIVIDE_NUM_Y / 2])

        self.steps_beyond_done = None

        return np.array(self.state)

    def _render(self):
        if self.screen is None:
            self.screen = pygame.display.set_mode((SCR_RECT.width, SCR_RECT.height))
            pygame.display.set_caption("Rappy-AI")

        self.game_scene.render(self.screen)

        return