# Nathan Hinton 19 Dec 2025 require 'securerandom' require './planet' # This class holds a game and should be the top level object. class Game attr_reader :players, :width, :height, :planets, :game_id # Create the game def initialize(width: 0, height: 0, planets: 0, game_id: nil, name: 'default name') @game_id = game_id || SecureRandom.hex @game_name = name @players = [] @planets = [] planets.times do |idx| planet = Planet.new() # Move to a random position position = [rand(width), rand(height), 0] # Ensure that the planets position is random while @planets.map{ |pl| pl.position}.include? position position = [rand(width), rand(height), 0] end planet.move(position) # Add to the list: @planets.append(planet) end @width = width @height = height end # Add a player to the game # # @param player [Player] The player to add to the game def add_player(player) # Check if there is a planet free for the player: avail_planets = [] @planets.each do |planet| avail_planets.append(planet) if planet.owner.nil? end if avail_planets == [] raise GameError, "No available planets to add player to" end planet = avail_planets.sample # Add the player to the game @players.append(player) planet.capture(player) player.home_planet = planet end # Remove a player from the game # # @param player [Player] The player to be removed def remove_player(player) idx = @players.index(player) if idx.nil? # Raise an error that the player could not be found raise GameError, 'Player not found to remove!' end @players.delete_at(idx) end # Finds if a player is in this game # # @return [Boolean] def find_player(player_name) @players.each do |player| if player.name == player_name return true end end return false end # Checks if the given id matches a player in the game. Returns the player if # so. otherwise raises an error. # # @param id [String] The id of a player # @return Player The player matching the id def check_id(id) @players.each do |player| if player.id == id return player end end raise GameError, 'Invalid player id!' end # Gets the planets for a player # # @param id [String] Players id # @return [Array] List of planets captured by that player def get_captured_planets(id) player = check_id(id) result = [] @planets.each do |planet| result.append(planet) if planet.owner == player end return result end # Returns a string representation of the map # Begin no coverage # :nocov: def to_s() # Create char map: game_map = [] @height.times do tmp = [] @width.times do tmp.append('') end game_map.append(tmp) end # Add planets to the map: @planets.each do |planet| pos_x, pos_y, pos_z = planet.position puts("x: #{pos_x}, y: #{pos_y}") game_map[pos_y][pos_x] += 'p' end require 'pp' pp(game_map) game_map.each do |row| row.each do |col| if col == '' print(' ') else print(col) end end print("\n") end end # :nocov: # End no coverage end # General game errors class GameError