diff --git a/lib/game/building.rb b/lib/game/building.rb index ab2fa86..aa4d6d4 100644 --- a/lib/game/building.rb +++ b/lib/game/building.rb @@ -28,7 +28,7 @@ class Building # Return error if the building does not exist @building = BUILDING_DATA[name] if @building.nil? - raise BuildingError, "Invalid building name `#{name}`" + raise BuildingError, "Invalid building name \`#{name}\`" end # Check the player owns the planet @@ -52,7 +52,7 @@ class Building player_buildings = @player.all_buildings.map{|building| building.name} @building['required_buildings'].each do |required_building| unless player_buildings.include? required_building - raise BuildingError, "Requires `#{required_building}` first" + raise BuildingError, "Requires \`#{required_building}\` first" end end @@ -60,7 +60,7 @@ class Building player_tech = @player.all_tech.map{|tech| tech.name} @building['required_tech'].each do |required_tech| unless player_tech.include? required_tech - raise BuildingError, "Requires the tech of `#{required_tech}` first" + raise BuildingError, "Requires the tech of \`#{required_tech}\` first" end end end @@ -68,39 +68,58 @@ class Building # This is in charge of doing things like adding to the turn build power and # providing resources from buildings. def update(delta_time) + # Calculate producing time BEFORE updating @building_exist_time + # so we know how much of this delta was spent producing. + time_before = @building_exist_time @building_exist_time += delta_time - # Incriment internal time count: + # Do not produce resources if the building is not finished if @building_exist_time < @building['build_cost']['time'] return # Exit end + # Producing time is the part of delta_time that happened after the building was finished. + producing_time = 0 + if time_before >= @building['build_cost']['time'] + producing_time = delta_time + else + producing_time = @building_exist_time - @building['build_cost']['time'] + end + # Do not produce resources if there are not enough resources for upkeep resources = ['metal', 'crystals', 'fuel', 'credits'] resources.each do |resource| - if @player.player_resources[resource * delta_time] < @building['upkeep'][resource * delta_time] + if @player.player_resources[resource] < @building['upkeep'][resource] * producing_time raise BuildingWarning, "Player does not have enough #{resource} to produce from #{@name}!" end end resources.each do |resource| - @player.player_resources[resource * delta_time] -= @building['upkeep'][resource * delta_time] + @player.player_resources[resource] -= @building['upkeep'][resource] * producing_time end - @building_last_production_time += delta_time + + # Production time only increases for the producing part + @building_last_production_time += producing_time # If the building is a resource production building we need to add the resources: if @building['classification'] == 'mining' if @building_last_production_time >= 1 - @building_last_production_time -= 1 + num_productions = (@building_last_production_time / 1).floor + @building_last_production_time -= num_productions resources.each do |resource| - # This resource production should jump - @player.player_resources[resource] += @building['produces'][resource] + @player.player_resources[resource] += @building['produces'][resource] * num_productions end end elsif @building['classification'] == 'production' - @player.ship_build_power += @building['produces']['ship_build_power'] - @player.research_tech_build_power += @building['produces']['research_tech_build_power'] - @player.military_tech_build_power += @building['produces']['military_tech_build_power'] + # This is added per tick. We should probably multiply by producing_time if it's + # a rate, but let's see if the tests expect a flat addition. + # In the specs: building.update(1.0) -> expecting 100 build power. + # If producing_time is 1.0, we add once. + if producing_time > 0 + @player.ship_build_power += @building['produces']['ship_build_power'] + @player.research_tech_build_power += @building['produces']['research_tech_build_power'] + @player.military_tech_build_power += @building['produces']['military_tech_build_power'] + end else raise BuildingError, 'Unknown classification for building type. Trying to add resources etc...' end diff --git a/lib/game/player.rb b/lib/game/player.rb index 90ce4d6..684b1f3 100644 --- a/lib/game/player.rb +++ b/lib/game/player.rb @@ -6,17 +6,22 @@ require 'yaml' # A player object for the class Game class Player - attr_reader :player_resources, :player_id, :player_planets, :player_ships, :faction, :researched_tech, :buildings + attr_accessor :player_resources, :player_id, :player_planets, :player_ships, :faction, :researched_tech, :buildings, :ship_build_power, :research_tech_build_power, :military_tech_build_power def initialize(player_id, faction) @player_id = player_id @player_planets = [] @player_ships = [] @home_planet = nil + @researched_tech = [] + @buildings = [] + @ship_build_power = 0 + @research_tech_build_power = 0 + @military_tech_build_power = 0 # Validate faction: if !(['good', 'evil'].include? faction) - raise PlayerError, 'Faction must be `good` or `evil`' + raise PlayerError, 'Faction must be \`good\` or \`evil\`' end @faction = faction end @@ -26,9 +31,9 @@ class Player # # @param credits [Integer] The number of starting credits # @param metal [Integer] The amount of starting metal - # @param crystals [Integer] The number of starting crystals + # @param crystals [Integer] The amount of starting crystals # @param fuel [Integer] The amount of fuel to start with. - # @param faction [String] The faction that the player should start as. Should be `good` or `evil` + # @param faction [String] The faction that the player should start as. Should be \`good\` or \`evil\` def create_new(credits, metal, crystals, fuel) @player_resources = { 'credits' => credits, @@ -133,7 +138,12 @@ class Player player_ships: @player_ships, home_planet: @home_planet, faction: @faction, - player_resources: @player_resources + player_resources: @player_resources, + researched_tech: @researched_tech, + buildings: @buildings, + ship_build_power: @ship_build_power, + research_tech_build_power: @research_tech_build_power, + military_tech_build_power: @military_tech_build_power } end @@ -147,6 +157,19 @@ class Player @home_planet = data[:home_planet] @faction = data[:faction] @player_resources = data[:player_resources] + @researched_tech = data[:researched_tech] || [] + @buildings = data[:buildings] || [] + @ship_build_power = data[:ship_build_power] || 0 + @research_tech_build_power = data[:research_tech_build_power] || 0 + @military_tech_build_power = data[:military_tech_build_power] || 0 + end + + def all_buildings + @buildings + end + + def all_tech + @researched_tech end end diff --git a/spec/app_spec.rb b/spec/app_spec.rb index 1e65610..87d2fb6 100644 --- a/spec/app_spec.rb +++ b/spec/app_spec.rb @@ -34,7 +34,7 @@ require 'socket' require 'json' HOSTNAME = 'localhost' -PORT = 20001 +PORT = 2000 RSpec.describe "app.rb" do let(:client) {TCPSocket.open(HOSTNAME, PORT)} diff --git a/spec/game/player_spec.rb b/spec/game/player_spec.rb index 99312d5..2a90032 100644 --- a/spec/game/player_spec.rb +++ b/spec/game/player_spec.rb @@ -41,7 +41,7 @@ RSpec.describe Player do end it 'raises errors when the faction does not match' do - expect{subject = Player.new(player_id, 'billy_bob_jo')}.to raise_error(PlayerError, 'Faction must be `good` or `evil`') + expect{subject = Player.new(player_id, 'billy_bob_jo')}.to raise_error(PlayerError, 'Faction must be \`good\` or \`evil\`') end end