Add restore command
This commit is contained in:
parent
6cf4759e5e
commit
45d0042a29
@ -18,13 +18,26 @@ module Game::TestCommand
|
||||
)
|
||||
map.set DepositTile.new(
|
||||
Point.new(1, 1),
|
||||
Deposit.new(Resource::Type::Crystals, 100)
|
||||
Deposit.new(Resource::Type::Crystals, 1000, 500)
|
||||
)
|
||||
map.set DepositTile.new(
|
||||
Point.new(1, 0),
|
||||
Deposit.new(Resource::Type::Crystals, 1000, 0)
|
||||
)
|
||||
map.set BuildingTile.new(
|
||||
Point.new(0, 1),
|
||||
Building.new(
|
||||
Building::Type::CrystalMiner,
|
||||
mining: Mining.new(20, Resource.new(Resource::Type::Crystals, 40))
|
||||
mining: Mining.new(
|
||||
ts: 20,
|
||||
resource: Resource.new(Resource::Type::Crystals, 40),
|
||||
input: ResourceBag.new
|
||||
),
|
||||
restoration: Mining.new(
|
||||
ts: 20,
|
||||
resource: Resource.new(Resource::Type::Crystals, 40),
|
||||
input: ResourceBag.new({Resource::Type::Crystals => 5})
|
||||
)
|
||||
)
|
||||
)
|
||||
map
|
||||
@ -65,10 +78,27 @@ module Game::TestCommand
|
||||
|
||||
it "should complete mining command" do
|
||||
world = World.new create_map_with_resource
|
||||
command = MineCommand.new Point.new(0, 1)
|
||||
command = MineCommand.new Point.new(0, 1), once: true
|
||||
world.push command
|
||||
world.run 20
|
||||
# Check world resources
|
||||
world.resources[Resource::Type::Crystals].should eq 40
|
||||
# Check tile deposit
|
||||
tile = world.map.get(1, 1).as(DepositTile)
|
||||
tile.dep.cur.should eq 460
|
||||
end
|
||||
|
||||
it "should complete restore command" do
|
||||
world = World.new create_map_with_resource
|
||||
world.resources.inc(Resource::Type::Crystals, 20)
|
||||
command = RestoreCommand.new Point.new(0, 1), once: true
|
||||
world.push command
|
||||
world.run 20
|
||||
# Check world resources
|
||||
world.resources[Resource::Type::Crystals].should eq 15
|
||||
# Check tile deposit
|
||||
tile = world.map.get(1, 0).as(DepositTile)
|
||||
tile.dep.cur.should eq 40
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -25,5 +25,29 @@ module Game::TestResourceBag
|
||||
res = Res.new
|
||||
res.has({ResType::Crystals => 50}).should be_false
|
||||
end
|
||||
|
||||
it "should inc single value" do
|
||||
res = Res.new ({ResType::Crystals => 10})
|
||||
res.inc ResType::Crystals, 5
|
||||
res[ResType::Crystals].should eq 15
|
||||
end
|
||||
|
||||
it "should inc resource" do
|
||||
res = Res.new ({ResType::Crystals => 10})
|
||||
res.inc Resource.new(ResType::Crystals, 5)
|
||||
res[ResType::Crystals].should eq 15
|
||||
end
|
||||
|
||||
it "should inc hash" do
|
||||
res = Res.new ({ResType::Crystals => 10})
|
||||
res.inc ({ResType::Crystals => 5})
|
||||
res[ResType::Crystals].should eq 15
|
||||
end
|
||||
|
||||
it "should inc other bag" do
|
||||
res = Res.new ({ResType::Crystals => 10})
|
||||
res.inc Res.new({ResType::Crystals => 5})
|
||||
res[ResType::Crystals].should eq 15
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -9,11 +9,12 @@ module Game
|
||||
end
|
||||
|
||||
class Mining
|
||||
def initialize(@ts : TimeSpan, @resource : Resource)
|
||||
def initialize(@ts : TimeSpan, @resource : Resource, @input : ResourceBag)
|
||||
end
|
||||
|
||||
getter ts
|
||||
getter resource
|
||||
getter input
|
||||
end
|
||||
|
||||
class Construction
|
||||
|
@ -11,7 +11,8 @@ module Game
|
||||
Building.new Building::Type::CrystalMiner, **{
|
||||
mining: Mining.new(
|
||||
ts: 20,
|
||||
resource: Resource.new(Resource::Type::Crystals, 40)
|
||||
resource: Resource.new(Resource::Type::Crystals, 40),
|
||||
input: ResourceBag.new
|
||||
),
|
||||
}
|
||||
)
|
||||
@ -27,7 +28,8 @@ module Game
|
||||
),
|
||||
restoration: Mining.new(
|
||||
ts: 30,
|
||||
resource: Resource.new(Resource::Type::Crystals, 20)
|
||||
resource: Resource.new(Resource::Type::Crystals, 20),
|
||||
input: ResourceBag.new
|
||||
),
|
||||
}
|
||||
)
|
||||
|
@ -36,7 +36,7 @@ module Game
|
||||
class MineCommand < Command
|
||||
@holded : Resource? = nil
|
||||
|
||||
def initialize(@point : Point)
|
||||
def initialize(@point : Point, *, @once = false)
|
||||
end
|
||||
|
||||
def desc : String
|
||||
@ -63,8 +63,10 @@ module Game
|
||||
holded = @holded.as(Resource)
|
||||
world.resources.inc(holded)
|
||||
end
|
||||
if !@once
|
||||
world.push(MineCommand.new(@point))
|
||||
end
|
||||
end
|
||||
|
||||
private def nearest_deposit(world : World, res_type : Resource::Type) : DepositTile?
|
||||
tile = world.map.nearest_tile @point do |tile|
|
||||
@ -74,6 +76,53 @@ module Game
|
||||
end
|
||||
end
|
||||
|
||||
class RestoreCommand < Command
|
||||
@holded : Resource? = nil
|
||||
@deposit_tile : DepositTile? = nil
|
||||
|
||||
def initialize(@point : Point, *, @once = false)
|
||||
end
|
||||
|
||||
def desc : String
|
||||
if @holded
|
||||
sprintf "Restore %s from %d,%d", @holded.type, @point.x, @point.y
|
||||
else
|
||||
sprintf "Wait for resources at %d,%d", @point.x, @point.y
|
||||
end
|
||||
end
|
||||
|
||||
def start(world : World) : TimeSpan
|
||||
tile = world.map.get(@point).as(BuildingTile)
|
||||
building = tile.building
|
||||
restoration = building.restoration.as(Mining)
|
||||
if !world.resources.has(restoration.input)
|
||||
return restoration.ts
|
||||
end
|
||||
@deposit_tile = nearest_deposit(world, restoration.resource.type)
|
||||
if @deposit_tile
|
||||
world.resources.dec restoration.input
|
||||
@holded = restoration.resource
|
||||
end
|
||||
restoration.ts
|
||||
end
|
||||
|
||||
def finish(world : World)
|
||||
if @deposit_tile && @holded
|
||||
@deposit_tile.as(DepositTile).dep.inc(@holded.as(Resource))
|
||||
end
|
||||
if !@once
|
||||
world.push(RestoreCommand.new(@point))
|
||||
end
|
||||
end
|
||||
|
||||
private def nearest_deposit(world : World, res_type : Resource::Type) : DepositTile?
|
||||
tile = world.map.nearest_tile @point do |tile|
|
||||
tile.is_a?(DepositTile) && tile.dep.type == res_type && tile.dep.cur == 0
|
||||
end
|
||||
tile.as?(DepositTile)
|
||||
end
|
||||
end
|
||||
|
||||
# class BuildCrystalHarvesterCommand < Command
|
||||
# BUILD_TIME = 30
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
class Game::Deposit
|
||||
@cap : Capacity = 0
|
||||
@cur : Capacity = 0
|
||||
|
||||
def initialize(@type : Resource::Type, @cap : Capacity)
|
||||
|
@ -26,15 +26,12 @@ class Game::ResourceBag
|
||||
@values = ResourceHash.new
|
||||
Resource::Type.each { |t, v| @values[t] = 0 }
|
||||
if vals.is_a?(ResourceHash)
|
||||
vals.each do |i|
|
||||
t, v = i
|
||||
@values[t] = v
|
||||
end
|
||||
add_amounts vals
|
||||
end
|
||||
end
|
||||
|
||||
def [](res_type : Resource::Type)
|
||||
@values.fetch(res_type, 0)
|
||||
@values[res_type]
|
||||
end
|
||||
|
||||
def has(res_type : Resource::Type, value : Capacity) : Bool
|
||||
@ -42,38 +39,68 @@ class Game::ResourceBag
|
||||
end
|
||||
|
||||
def has(res : Resource) : Bool
|
||||
has(res.type, res.amount)
|
||||
has res.type, res.amount
|
||||
end
|
||||
|
||||
def has(vs : ResourceHash) : Bool
|
||||
vs.reduce true do |acc, entry|
|
||||
t = entry[0]
|
||||
v = entry[1]
|
||||
acc && @values[t] >= v
|
||||
end
|
||||
has_amounts vs
|
||||
end
|
||||
|
||||
def has(vs : self) : Bool
|
||||
has vs.to_hash
|
||||
has_amounts vs.@values
|
||||
end
|
||||
|
||||
def inc(res_type : Resource::Type, value : Capacity)
|
||||
new_value = @values[res_type] + value
|
||||
if new_value < 0
|
||||
raise NotEnoughtResources.new
|
||||
end
|
||||
@values[res_type] = new_value
|
||||
validate_add_amounts ({res_type => value})
|
||||
@values[res_type] += value
|
||||
end
|
||||
|
||||
def inc(res : Resource)
|
||||
inc(res.type, res.amount)
|
||||
inc res.type, res.amount
|
||||
end
|
||||
|
||||
def inc(vs : ResourceHash)
|
||||
validate_add_amounts vs
|
||||
add_amounts vs
|
||||
end
|
||||
|
||||
def inc(other : self)
|
||||
inc other.@values
|
||||
end
|
||||
|
||||
def dec(res_type : Resource::Type, value : Capacity)
|
||||
inc(res_type, -value)
|
||||
inc res_type, -value
|
||||
end
|
||||
|
||||
def to_hash : ResourceHash
|
||||
@values.clone
|
||||
def dec(other : self)
|
||||
inverted = other.@values.transform_values { |v| -v }
|
||||
inc inverted
|
||||
end
|
||||
|
||||
private def can_add_amounts(vs : ResourceHash)
|
||||
vs.reduce true do |acc, entry|
|
||||
res_type, amount = entry
|
||||
acc && @values[res_type] + amount >= 0
|
||||
end
|
||||
end
|
||||
|
||||
private def validate_add_amounts(vs : ResourceHash)
|
||||
if !can_add_amounts(vs)
|
||||
raise NotEnoughtResources.new
|
||||
end
|
||||
end
|
||||
|
||||
private def add_amounts(vs : ResourceHash)
|
||||
vs.each do |entry|
|
||||
res_type, amount = entry
|
||||
@values[res_type] += amount
|
||||
end
|
||||
end
|
||||
|
||||
private def has_amounts(vs : ResourceHash)
|
||||
vs.reduce true do |acc, entry|
|
||||
res_type, amount = entry
|
||||
acc && @values[res_type] >= amount
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user