Working hard, decided that we need to commit to Git

This commit is contained in:
2025-10-02 14:57:16 -06:00
commit 72bd5fb9c0
11 changed files with 659 additions and 0 deletions
+284
View File
@@ -0,0 +1,284 @@
# Nathan Hinton 1 Oct 2025
require './planet'
# Universe class. Holds a universe and provides the api for it. Universes are
# created on a 2d grid. I would like it to be hexagonal movement type so that
# it feels less like a grid and more like a circle. This means that we will
# have some interesting point systems. For now I am thinking that we will have
# three directions, a, b, c which will corespond to moving along one of the
# lines to another system. Here is an ascii art:
#
#
# (0, 0, 1) (0, 1, 0)
# \ /
# \ /
# \ /
# (+c) (+b)
# \ /
# \ /
# \ /
# (-1, 0, 0) <--- (-a) --- (0, 0, 0) --- (+a) ---> (1, 0, 0)
# / \
# / \
# /
# (-b) (-c)
# / \
# / \
# / \
# (0, -1, 0) (0, 0, -1)
#
#
# This means that we are adding vector together. I do not think that this will
# work super well though with a system that is other than 2D. I think that will
# be fine.
#
# After thinking some more I will have the universe class hold everything in
# the universe. It will be in charge of holding all of the ships and
# planets. Then the Player class will be connected to the ships and planets
# that they own/control
#
# @param name [String] The name of the game
# @param universe_size [Integer] Controlls the size of the generated universe. This is a radius from the center point.
class Universe
def initialize(name, universe_size: 4, create_chances: {planet: 1}, seed: nil, verbose: true, debug: false)
@name = name
@universe_size = universe_size
@create_chances = create_chances
@verbose = verbose
@debug = debug
# Setup internal lists:
@player_list = []
@ship_list = []
# initizlize RNG
if seed.nil?
@random = Random.new()
@seed = @random.seed
else
@seed = seed
@random = Random.new(@seed)
end
# Set center of universe
@center = Position.new([@universe_size + 2, @universe_size ])
puts "Generating Universe '#{@name}' with seed #{@seed}" if @verbose
puts "Center is #{@center}"
@universe_map = []
# Generate the universe. First generate the x values:
(0 .. (@universe_size * 2)).each do |y_pos|
@universe_map[y_pos] = []
(0 .. (@universe_size * 2 + 2)).each do |x_pos|
# Make the grid work right, x is actually skipping every other.
x_pos *= 2
x_pos += 1 if y_pos.odd?
position = Position.new([x_pos, y_pos])
# Skip if the node is too far
if distance(@center, position) >= @universe_size
next
end
# Get what the planet should be:
spot = nil
if @random.rand < @create_chances[:planet]
spot = Planet.new(@random)
end
puts "Creating something at (#{position.x_pos} #{position.y_pos})" if @debug
@universe_map[position.y_pos][position.x_pos] = spot
end # Create y points
end # Create x points
end # Function initialize
# Returns the distance between points. This is returned as a number which
# indicates how far you have to go to get to a point. This is actually
# supurisingly hard...
#
# @param position_a [Position] A start point in the universe
# @param position_b [Position] Another point in the universe
# @return [Integer] The distance between points in the universe.
def distance(position_a, position_b)
result = 0 # We can just add the abs diff of each direction.
dist_x = (position_b.x_pos - position_a.x_pos).abs
dist_y = (position_b.y_pos - position_a.y_pos).abs
# Sanity check, our coordinates should add to be even:
if (dist_x + dist_y).odd?
raise RangeError.new('When calculating the distance we calculated a non even number. This is not allowed!')
end
res = (dist_x / 2) + dist_y
if dist_x >= dist_y
res = (dist_x + dist_y) / 2
end
puts "Distance: #{point_a} is #{point_b} #{res} units away" if @debug
return res
end # Function distance
# Prints the universe to the screen.
def print_universe(simple: false)
(0 .. (@universe_size * 2)).each do |y_pos|
# Print empty space before chart (for angles)
nextline = ''
if y_pos < @universe_size
nextline += ' ' * ((@universe_size - y_pos).abs - 1)
else
nextline += ' ' * ((@universe_size - y_pos).abs)
end
# Print more empty space for the odd places (provides offset)
if y_pos.odd?
print ' '
end
#Actually loop through everything
(0 .. (@universe_size * 2)).each do |x_pos|
# Make the grid work right, x is actually skipping every other.
x_pos *= 2
x_pos += 1 if y_pos.odd?
# Print empty space if we are outside the universe (For items)
if distance(@center, [x_pos, y_pos]) >= @universe_size
print ' '
next
end
# Print what we are:
position = @universe_map[y_pos][x_pos]
nextline += ' '
if [x_pos, y_pos] == @center
print 'O'
elsif position.class == Planet
print 'P'
else
print ' '
end
# Calculate what we should print on the next line and if we should print dashes
if y_pos < @universe_size
nextline += '/ \\'
end
if distance(@center, [x_pos + 2, y_pos]) < @universe_size
print '---'
if y_pos >= @universe_size
nextline += '\\ /'
end
end
end # For each col in row
puts ''
if (y_pos + 1) / 2 < @universe_size && !simple
puts nextline
end
end # For each row
end # Function print_universe
##################################################
################### UNIVERSE #####################
##################################################
# This is where API stuff for the universe should go
# Gets a position from the universe for a player. Eventually this will take
# into account that the player can not actually see the whole universe
#
# @param player [Player] The player who is asking for the position
# @param position [Position] The position that is being requested
def get_position(player, position)
end
# Sets a position as explored for a player. This should be called as ships
# move around and explore the universe.
#
# @param player [Player] The player who should be set
# @param position [Position] The position that is being modified
def explore_position(player, position)
end
##################################################
##################### SHIPS ######################
##################################################
# Create a ship in the universe. This ship is registered to a specific player
#
# @param player [Player] The player who owns the ship
# @param position [Position] The position that the ship should be created at
def create_ship(player, position)
end
# Move a player's ship to a given position
#
# @param player [Player] The player whose ship should be moved
# @param ship [Ship] The ship that should be moved
# @param position [Position] The position the ship should be moved to.
def move_ship(player, ship, position)
end
##################################################
##################### PLANETS ####################
##################################################
# As all planets are created when the galaxy is generated there are no create
# planet functions. It is possible that we want to remove them though
# Remove a planet from the universe
#
# @param planet [Planet] The planet that should be removed
# @param position [Position] The position that it should be removed from
def remove_planet(planet, position)
end
##################################################
##################### PLAYER #####################
##################################################
# Add a player to the player list in the universe
#
# @param player [Player] The player who should be added to the universe
def add_player(player)
@player_list.push(player)
return 'Added player to universe'
end
# Remove a player from the list in this universe
#
# @param player [Player] The player that should be removed from the player list.
def remove_player(player)
if @player_list.delete(player).nil?
return 'Failed to remove player! Does not exist in this universe!'
end
return 'Removed player from universe'
end
# Returns a list of ships owned by the player
#
# @param player [Player] The player who wants to get their ships.
def get_player_ships(player)
result = []
@ship_list.each do |ship|
if ship.owner == player
result.push(ship)
end
end
return result
end # Function get_player_ships
# Returns a list of planets owned by the player
#
# @param player [Player] The player who wants to get their planets.
def get_player_planets(player)
result = []
@planet_list.each do |planet|
if planet.owner == player
result.push(planet)
end
end
return result
end
end # Class Universe