Add restore command

This commit is contained in:
2019-10-13 16:54:33 +03:00
parent 6cf4759e5e
commit 45d0042a29
7 changed files with 163 additions and 29 deletions

View File

@ -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

View File

@ -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
),
}
)

View File

@ -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,7 +63,9 @@ module Game
holded = @holded.as(Resource)
world.resources.inc(holded)
end
world.push(MineCommand.new(@point))
if !@once
world.push(MineCommand.new(@point))
end
end
private def nearest_deposit(world : World, res_type : Resource::Type) : DepositTile?
@ -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

View File

@ -1,4 +1,5 @@
class Game::Deposit
@cap : Capacity = 0
@cur : Capacity = 0
def initialize(@type : Resource::Type, @cap : Capacity)

View File

@ -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