# 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