diff --git a/spec/command_spec.cr b/spec/command_spec.cr index fc26b02..b0441e2 100644 --- a/spec/command_spec.cr +++ b/spec/command_spec.cr @@ -3,16 +3,36 @@ require "./spec_helper" module Game::TestCommand extend self - def create_map_2x2 : Map + def create_empty_map_2x2 : Map + Map.new 2, 2 + end + + def create_map_with_resource : Map map = Map.new 2, 2 - map.set(MainBaseTile.new(Point.new(0, 0))) - map.set(CrystalTile.new(Point.new(1, 1), 100)) + map.set BuildingTile.new( + Point.new(0, 0), + Building.new( + Building::Type::StartPoint, + storage: 200 + ) + ) + map.set DepositTile.new( + Point.new(1, 1), + Deposit.new(Resource::Type::Crystals, 100) + ) + map.set BuildingTile.new( + Point.new(0, 1), + Building.new( + Building::Type::CrystalMiner, + mining: Mining.new(20, Resource.new(Resource::Type::Crystals, 40)) + ) + ) map end describe Command do it "should complete build command" do - world = World.new create_map_2x2 + world = World.new create_empty_map_2x2 point = Point.new 1, 0 building = Building.new Building::Type::StartPoint, **{ construction: Construction.free 10, @@ -27,7 +47,7 @@ module Game::TestCommand end it "should restrict building if not enought resources" do - world = World.new create_map_2x2 + world = World.new create_empty_map_2x2 point = Point.new 1, 0 building = Building.new Building::Type::StartPoint, **{ construction: Construction.new( @@ -42,5 +62,13 @@ module Game::TestCommand world.push(command) end end + + it "should complete mining command" do + world = World.new create_map_with_resource + command = MineCommand.new Point.new(0, 1) + world.push command + world.run 20 + world.resources[Resource::Type::Crystals].should eq 40 + end end end diff --git a/spec/deposit_spec.cr b/spec/deposit_spec.cr index 0f3bf51..2b01da7 100644 --- a/spec/deposit_spec.cr +++ b/spec/deposit_spec.cr @@ -16,23 +16,26 @@ module Game::Test it "should be decreased with span" do dep = Deposit.new(Resource::Type::Crystals, 100) - dep.dec Resource.new(Resource::Type::Crystals, 20) + res = dep.dec Resource.new(Resource::Type::Crystals, 20) dep.cap.should eq 100 dep.cur.should eq 80 + res.amount.should eq 20 end it "should not be increased above capacity" do dep = Deposit.new(Resource::Type::Crystals, 100, 20) - dep.inc Resource.new(Resource::Type::Crystals, 100) + res = dep.inc Resource.new(Resource::Type::Crystals, 100) dep.cap.should eq 100 dep.cur.should eq 100 + res.amount.should eq 80 end it "should not be decreased below zero" do dep = Deposit.new(Resource::Type::Crystals, 100) - dep.dec Resource.new(Resource::Type::Crystals, 120) + res = dep.dec Resource.new(Resource::Type::Crystals, 120) dep.cap.should eq 100 dep.cur.should eq 0 + res.amount.should eq 100 end end end diff --git a/src/game/command.cr b/src/game/command.cr index 84c6f8c..bc2fefc 100644 --- a/src/game/command.cr +++ b/src/game/command.cr @@ -43,29 +43,34 @@ module Game tile = world.map.get(@point).as(BuildingTile) building = tile.building mining = building.mining.as(Mining) - # deposit_tile = nearest_deposit(world, mining.resource.type) - # if deposit_tile - # @holded = deposit_tile.dep.dec(mining.resource) - # end + deposit_tile = nearest_deposit(world, mining.resource.type) + if deposit_tile + @holded = deposit_tile.as(DepositTile).dep.dec(mining.resource) + end mining.ts end def finish(world : World) if @holded - # world.resources.inc(@holded) + holded = @holded.as(Resource) + world.resources.inc(holded.type, holded.amount) end world.push(MineCommand.new(@point)) end def desc : String - sprintf "Mine `smth` from %d,%d", @point.x, @point.y + if @holded + sprintf "Mine %s from %d,%d", @holded.as(Resource).type, @point.x, @point.y + else + sprintf "Wait for resources at %d,%d", @point.x, @point.y + end end - # private def nearest_deposit(world : World, res_type : Resource::Type) - # world.map.nearest_tile @point do |tile| - # tile.is_a?(DepositTile) && tile.dep.type == res_type && tile.dep.cur > 0 - # end - # end + private def nearest_deposit(world : World, res_type : Resource::Type) + world.map.nearest_tile @point do |tile| + tile.is_a?(DepositTile) && tile.dep.type == res_type && tile.dep.cur > 0 + end + end end # class BuildCrystalHarvesterCommand < Command diff --git a/src/game/deposit.cr b/src/game/deposit.cr index 622b165..05ce8e3 100644 --- a/src/game/deposit.cr +++ b/src/game/deposit.cr @@ -12,14 +12,28 @@ class Game::Deposit getter cap getter cur - def inc(resource : Resource) + def inc(resource : Resource) : Resource check_res resource.type - @cur = Math.min(@cap, @cur + resource.amount) + if @cur + resource.amount <= @cap + @cur += resource.amount + Resource.new(resource.type, resource.amount) + else + res = Resource.new(resource.type, @cap - @cur) + @cur = @cap + res + end end - def dec(resource : Resource) + def dec(resource : Resource) : Resource check_res resource.type - @cur = Math.max(0, @cur - resource.amount) + if @cur >= resource.amount + @cur -= resource.amount + resource + else + res = Resource.new(resource.type, @cur) + @cur = 0 + res + end end private def check_res(other_res_type : Resource::Type) diff --git a/src/game/resources.cr b/src/game/resources.cr index d2126dd..7dae9c3 100644 --- a/src/game/resources.cr +++ b/src/game/resources.cr @@ -11,6 +11,10 @@ struct Game::Resource getter type getter amount + + def with_amount(amount : Capacity) : self + self.new @type, amount + end end class Game::ResourceBag