Files
space_game_server/game/spec/universe_spec.rb
T
2025-12-19 09:16:48 -07:00

164 lines
4.6 KiB
Ruby

# frozen_string_literal: true
require './universe'
require './planet'
require './position'
require './universe_array'
require './spec/stdout_helper'
RSpec.describe Universe do
let(:name) { 'Test Universe' }
let(:universe_size) { 3 }
let(:seed) { 12345 }
subject(:universe) do
Universe.new(
name,
universe_size: universe_size,
seed: seed,
create_chances: { planet: 1 } # force a planet at every valid spot
)
end
describe '#initialize' do
it 'stores all expected instance variables' do
expect(universe.name).to eq name
expect(universe.instance_variable_get(:@universe_size)).to eq universe_size
expect(universe.instance_variable_get(:@seed)).to eq seed
end
it 'creates a deterministic Random object when a seed is given' do
rng = universe.instance_variable_get(:@random)
expect(rng).to be_a(Random)
expect(rng.rand(100)).to eq Random.new(seed).rand(100)
end
it 'initializes the random if no seed is passed in' do
uni = Universe.new(name)
rng = uni.instance_variable_get(:@random)
expect(rng).to be_a(Random)
end
end
describe '#create_universe' do
end
describe '#distance' do
it 'is symmetric' do
a = Position.new(0, 0)
b = Position.new(4, 2)
expect(universe.distance(a, b)).to eq universe.distance(b, a)
end
it 'returns 0 when both points are identical' do
p = Position.new(1, 1)
expect(universe.distance(p, p)).to eq 0
end
it 'correctly computes known hex distances' do
p0 = Position.new(0, 0)
p1 = Position.new(2, 0)
p2 = Position.new(4, 2)
p3 = Position.new(2, 2)
# (0,0) to (2,0) → 1
expect(universe.distance(p0, p1)).to eq 1
# (0,0) to (4,2) → 3
expect(universe.distance(p0, p2)).to eq 3
# (0,0) to (2,2) → 2
expect(universe.distance(p0, p3)).to eq 2
end
end # describe '#distance'
describe '#map generation' do
it 'creates the expected dimensions' do
universe.create_universe
map = universe.instance_variable_get(:@universe_map)
# Each valid (x,y) pair inside the radius contains a Planet
# (our stub) and every other entry is nil.
expect(map).to be_a(UniverseArray)
# Check how may nodes were created:
expect(map.flatten.compact.length).to eq 19 # 1 + 1*6 + 2*6
end
it 'contains a planet at every valid point when create_chances is 1' do
universe.create_universe
map = universe.instance_variable_get(:@universe_map)
map.each do |row|
row.each do |idx|
# The indexes are allowed to be nil
if idx.nil?
next # Is allowed to be nil
end
if idx.is_a? Star
next # Is allowed to be star
end
expect(idx).to be_a(Planet)
end
end
end # describe '#map generation'
it 'is deterministic when the same seed is used' do
first_universe = Universe.new(
name,
universe_size: universe_size,
seed: seed,
create_chances: { planet: 0.1 }
)
first_map = first_universe.instance_variable_get(:@universe_map)
second_universe = Universe.new(
name,
universe_size: universe_size,
seed: seed,
create_chances: { planet: 0.1 }
)
second_map = second_universe.instance_variable_get(:@universe_map)
expect(first_map).to eq second_map
end
end
describe '#print_universe' do
it 'prints the center point as “O”' do
out = capture_stdout do
universe.create_universe
universe.print_universe
end
expect(out).to include('O')
end
it 'can print blank spaces for nothing' do
out = capture_stdout do
uni = Universe.new(name, create_chances: {planet: 0.0})
uni.create_universe
uni.print_universe
end
expect(out).to include('O')
expect(out).to include('- -')
end
end
describe '#planets' do
it 'lists all of the generated planets' do
universe.create_universe
expect(universe.planets.length).to eq 18
end
end
describe '#tick' do
it 'runs a tick of the game' do
universe.create_universe
player_1 = Player.new('test player 01')
universe.add_player(player_1)
universe.add_ship(player_1, Position.new(3, 5))
ships = universe.get_player_ships(player_1)
universe.move_ship(player_1, ships[0], Position.new(2, 4))
# Now we tick the universe and the ship should move a little and the player should gain resources.
expect{universe.tick}.to_not raise_error()
end
end
end