| | import pygame
|
| | import numpy as np
|
| | import Main2
|
| | import importlib
|
| | import time
|
| |
|
| |
|
| | importlib.reload(Main2)
|
| | class RocketLandingGameRunner:
|
| | def __init__(self, width=800, height=600, render=False):
|
| | """Initialize the game runner with screen dimensions and rendering option."""
|
| | self.width = width
|
| | self.height = height
|
| | self.step_duration = 0.1
|
| | self.frame_time = 1.0 / 60
|
| | self.white = (255, 255, 255)
|
| | self.render_enabled = render
|
| | self.game = Main2.RocketLandingGame(self.render_enabled)
|
| |
|
| |
|
| | self.state_space = {
|
| | 'x': (0, self.width),
|
| | 'y': (0, self.height),
|
| | 'velocity_x': (-50, 50),
|
| | 'velocity_y': (-50, 50),
|
| | 'angle': (-180, 180)
|
| | }
|
| | self.action_space = [0, 1, 2, 3]
|
| |
|
| | def reset(self):
|
| | """Reset the game to initial state and return initial state."""
|
| | self.game.rocket = Main2.Rocket()
|
| | self.game.game_over = False
|
| | self.game.win = False
|
| | self.game.running = True
|
| | self.game.action_log = []
|
| | return self._get_state()
|
| |
|
| | def _get_state(self):
|
| | """Return the current state as a numpy array without exponent format."""
|
| | state = np.array([
|
| | self.game.rocket.x,
|
| | self.game.rocket.y,
|
| | self.game.rocket.velocity_x,
|
| | self.game.rocket.velocity_y,
|
| | self.game.rocket.angle
|
| | ], dtype=np.float32)
|
| |
|
| | return np.round(state, 1)
|
| |
|
| |
|
| | def step(self, action):
|
| | """Take an action, update the game, and return (next_state, reward, done, info)."""
|
| |
|
| | thrusting = (action == 1)
|
| | rotate_left = (action == 2)
|
| | rotate_right = (action == 3)
|
| |
|
| |
|
| | if action == 1:
|
| | self.game.add_to_action_log("Thrust activated.")
|
| | elif action == 2:
|
| | self.game.add_to_action_log("Rotation left.")
|
| | elif action == 3:
|
| | self.game.add_to_action_log("Rotation right.")
|
| | else:
|
| | self.game.add_to_action_log("Doing nothing.")
|
| |
|
| |
|
| | reward, game_over, win = self.game.game_step(thrusting, rotate_left, rotate_right, time_step=self.step_duration)
|
| |
|
| |
|
| | next_state = self._get_state()
|
| |
|
| |
|
| | done=game_over
|
| |
|
| | info = {'win': win, 'action_log': self.game.action_log[-1]}
|
| |
|
| |
|
| | if self.render_enabled:
|
| | self._render()
|
| |
|
| | return next_state, reward, done
|
| |
|
| | def _render(self):
|
| | """Render the game state."""
|
| | self.game.screen.fill(self.white)
|
| |
|
| | self.game.draw_terrain()
|
| | self.game.rocket.draw(self.game.screen)
|
| |
|
| | self.game.draw_info()
|
| |
|
| | if self.game.game_over:
|
| | if self.game.win:
|
| | win_text = pygame.font.SysFont('Arial', 40).render(
|
| | "You Landed Safely!", True, (0, 128, 0)
|
| | )
|
| | self.game.screen.blit(
|
| | win_text, (self.width // 2 - win_text.get_width() // 2, self.height // 2 - 100)
|
| | )
|
| | else:
|
| | crash_text = pygame.font.SysFont('Arial', 40).render(
|
| | "Crash! Try Again.", True, (255, 0, 0)
|
| | )
|
| | self.game.screen.blit(
|
| | crash_text, (self.width // 2 - crash_text.get_width() // 2, self.height // 2 - 100)
|
| | )
|
| | self.game.draw_restart_button()
|
| | if self.render_enabled:
|
| | pygame.display.update()
|
| | self.game.clock.tick(30)
|
| | pygame.event.pump()
|
| |
|
| | def run(self, agent=None):
|
| | if agent is None:
|
| |
|
| | while self.game.running:
|
| | step_start_time = time.time()
|
| | thrusting = False
|
| | rotate_left = False
|
| | rotate_right = False
|
| | reset_game = False
|
| | action_logged = False
|
| |
|
| | for event in pygame.event.get():
|
| | if event.type == pygame.QUIT:
|
| | self.game.running = False
|
| | if event.type == pygame.MOUSEBUTTONDOWN and self.game.game_over:
|
| | mouse_pos = pygame.mouse.get_pos()
|
| | if self.game.draw_restart_button().collidepoint(mouse_pos):
|
| | reset_game = True
|
| | self.game.add_to_action_log("Game reset by user.")
|
| | action_logged = True
|
| |
|
| | if not self.game.game_over and not reset_game:
|
| | keys = pygame.key.get_pressed()
|
| | if keys[pygame.K_w] and not action_logged:
|
| | thrusting = True
|
| | self.game.add_to_action_log("Thrust activated.")
|
| | action_logged = True
|
| | elif keys[pygame.K_a] and not action_logged:
|
| | rotate_left = True
|
| | self.game.add_to_action_log("Rotation left.")
|
| | action_logged = True
|
| | elif keys[pygame.K_d] and not action_logged:
|
| | rotate_right = True
|
| | self.game.add_to_action_log("Rotation right.")
|
| | action_logged = True
|
| | elif keys[pygame.K_r] and not action_logged:
|
| | reset_game = True
|
| | self.game.add_to_action_log("Game reset by 'R' key.")
|
| | action_logged = True
|
| |
|
| | if not action_logged:
|
| | self.game.add_to_action_log("Doing nothing.")
|
| |
|
| | if reset_game:
|
| | self.reset()
|
| |
|
| | while time.time() - step_start_time < self.step_duration:
|
| | if not reset_game and not self.game.game_over:
|
| | reward, game_over, win = self.game.game_step(
|
| | thrusting, rotate_left, rotate_right, time_step=self.frame_time
|
| | )
|
| | print(reward)
|
| | else:
|
| | reward, game_over, win = 0, self.game.game_over, self.game.win
|
| | if self.render_enabled:
|
| | self._render()
|
| |
|
| | print("\nAction Log:")
|
| | for entry in self.game.action_log:
|
| | print(entry)
|
| | pygame.quit()
|
| |
|
| | else:
|
| |
|
| | state = self.reset()
|
| | total_reward = 0
|
| | np.set_printoptions(suppress=True)
|
| | while self.game.running:
|
| |
|
| | state_input = np.expand_dims(state, axis=0)
|
| | action_values = agent(state_input)
|
| | action = np.argmax(action_values.numpy()[0])
|
| |
|
| | next_state, reward, done = self.step(action)
|
| | total_reward += reward
|
| |
|
| | state = next_state
|
| | if done:
|
| | break
|
| | start_time = time.time()
|
| | button_rect = self.game.draw_restart_button()
|
| |
|
| |
|
| | while time.time() - start_time < 5:
|
| | for event in pygame.event.get():
|
| | if event.type == pygame.MOUSEBUTTONDOWN:
|
| | mouse_pos = event.pos
|
| | if button_rect.collidepoint(mouse_pos):
|
| |
|
| | game_runner2 = RocketLandingGameRunner(width=800, height=600, render=True)
|
| | game_runner2.run(agent)
|
| | return
|
| | elif event.type == pygame.QUIT:
|
| | pygame.quit()
|
| | return
|
| |
|
| | pygame.display.update()
|
| |
|
| |
|
| | pygame.quit()
|
| |
|
| | def get_action_log(self):
|
| | """Return the current action log."""
|
| | return self.game.action_log |