diff --git a/__pycache__/asteroid.cpython-313.pyc b/__pycache__/asteroid.cpython-313.pyc new file mode 100644 index 0000000..4201d65 Binary files /dev/null and b/__pycache__/asteroid.cpython-313.pyc differ diff --git a/__pycache__/asteroid_spawner.cpython-313.pyc b/__pycache__/asteroid_spawner.cpython-313.pyc new file mode 100644 index 0000000..82e635f Binary files /dev/null and b/__pycache__/asteroid_spawner.cpython-313.pyc differ diff --git a/__pycache__/bullet.cpython-313.pyc b/__pycache__/bullet.cpython-313.pyc new file mode 100644 index 0000000..10edb57 Binary files /dev/null and b/__pycache__/bullet.cpython-313.pyc differ diff --git a/__pycache__/spaceship.cpython-313.pyc b/__pycache__/spaceship.cpython-313.pyc new file mode 100644 index 0000000..7b31af5 Binary files /dev/null and b/__pycache__/spaceship.cpython-313.pyc differ diff --git a/asteroid.py b/asteroid.py new file mode 100644 index 0000000..299a38f --- /dev/null +++ b/asteroid.py @@ -0,0 +1,36 @@ +# asteroid.py +# ------------ +# By MWC Contributors +# This module defines an asteroid agent class. + +class Asteroid: + character = 'O' + + def __init__(self, position, speed=2): + # speed = how often it moves (1 = every turn, 2 = every 2 turns, etc.) + self.position = position + self.speed = speed + + def play_turn(self, game): + width, height = game.board_size + + # Only move on some turns (for variable speed) + if game.turn_number % self.speed != 0: + return + + x, y = self.position + + # If at bottom, remove asteroid + if y == height - 1: + game.remove_agent(self) + else: + ship = game.get_agent_by_name('ship') + new_position = (x, y + 1) + + # If we hit the ship, damage it and remove this asteroid + if new_position == ship.position: + if hasattr(ship, "take_damage"): + ship.take_damage(game) + game.remove_agent(self) + else: + self.position = new_position \ No newline at end of file diff --git a/asteroid_spawner.py b/asteroid_spawner.py new file mode 100644 index 0000000..0439af8 --- /dev/null +++ b/asteroid_spawner.py @@ -0,0 +1,30 @@ +# asteroid_spawner.py +# ------------------- +# By MWC Contributors +# This module defines an AsteroidSpawner agent class. + +from random import randint +from asteroid import Asteroid + +class AsteroidSpawner: + display = False + + def play_turn(self, game): + width, height = game.board_size + + # Increase score each turn survived + game.state['score'] += 1 + + if self.should_spawn_asteroid(game.turn_number): + # Random x position at the top + x = randint(0, width - 1) + # Random speed: 1 = fast, 2–3 = slower + speed = randint(1, 3) + asteroid = Asteroid((x, 0), speed) + game.add_agent(asteroid) + + def should_spawn_asteroid(self, turn_number): + # More asteroids as the game goes on + return randint(0, 1000) < turn_number + + \ No newline at end of file diff --git a/bullet.py b/bullet.py new file mode 100644 index 0000000..56ad548 --- /dev/null +++ b/bullet.py @@ -0,0 +1,31 @@ +from asteroid import Asteroid + +class Bullet: + """A bullet fired by the spaceship that moves upward and destroys asteroids.""" + character = '|' + + def __init__(self, position): + self.position = position + + def play_turn(self, game): + # Move bullet up one row each turn + x, y = self.position + y -= 1 + + # If the bullet goes off the top, remove it + if y < 0: + game.remove_agent(self) + return + + self.position = (x, y) + + # Check if we hit an asteroid + # We loop over a copy of the agents list because we may remove agents + for agent in list(game.agents): + if isinstance(agent, Asteroid) and agent.position == self.position: + # Destroy the asteroid and the bullet + game.remove_agent(agent) + game.remove_agent(self) + # Reward points for hitting an asteroid + game.state["score"] += 10 + return \ No newline at end of file diff --git a/nav_game.py b/nav_game.py new file mode 100644 index 0000000..8931b3e --- /dev/null +++ b/nav_game.py @@ -0,0 +1,23 @@ +# nav_game.py +# ------------ +# By MWC Contributors +# This class implements a simple game where a spaceship avoids asteroids. + +from spaceship import Spaceship +from asteroid import Asteroid + +from retro.game import Game +from spaceship import Spaceship +from asteroid_spawner import AsteroidSpawner + +board_size = (25, 25) +ship = Spaceship(board_size) +spawner = AsteroidSpawner() + +#adds health to the game +state = { + "score":0, + "health":3 #3 lives +} +game = Game([ship, spawner], state, board_size=board_size) +game.play() \ No newline at end of file diff --git a/spaceship.py b/spaceship.py new file mode 100644 index 0000000..3b34c83 --- /dev/null +++ b/spaceship.py @@ -0,0 +1,59 @@ +# spaceship.py +# ------------ +# By MWC Contributors +# This module defines a spaceship agent class. + +from bullet import Bullet + +class Spaceship: + name = "ship" + character = '^' + + def __init__(self, board_size): + board_width, board_height = board_size + self.position = (board_width // 2, board_height - 1) + + def handle_keystroke(self, keystroke, game): + x, y = self.position + new_position = None + + # Move LEFT + if keystroke.name in ("KEY_LEFT", "a", "A"): + new_position = (x - 1, y) + + # Move RIGHT + elif keystroke.name in ("KEY_RIGHT", "d", "D"): + new_position = (x + 1, y) + + # Move UP + elif keystroke.name in ("KEY_UP", "w", "W"): + new_position = (x, y - 1) + + # Move DOWN + elif keystroke.name in ("KEY_DOWN", "s", "S"): + new_position = (x, y + 1) + + # SHOOT (m or M) + elif keystroke.name in ("m", "M"): + bx, by = x, y - 1 + if game.on_board((bx, by)): + bullet = Bullet((bx, by)) + game.add_agent(bullet) + return # don’t move on shoot + + else: + return # ignore other keys + + # If we are trying to move: + if new_position is not None and game.on_board(new_position): + if game.is_empty(new_position): + self.position = new_position + else: + # We bumped into something (probably an asteroid) + self.take_damage(game) + + def take_damage(self, game): + """Reduce health; end game if health reaches 0.""" + game.state["health"] -= 1 + if game.state["health"] <= 0: + game.end() \ No newline at end of file