diff --git a/src/map.cr b/src/map.cr index 4049caa..7d817a9 100644 --- a/src/map.cr +++ b/src/map.cr @@ -123,6 +123,24 @@ class Map p end + def nearest_any_wood(point : Point) : Point | Nil + p = nil + d = 99999 + (0...4).each do |x| + (0...4).each do |y| + tile = self.get(Point.new(x, y)) + if tile.letter == 'f' + td = Point.new(x, y).distance(point) + if td < d + d = td + p = Point.new(x, y) + end + end + end + end + p + end + def print (0...4).each do |x| (0...4).each do |y| diff --git a/src/queue.cr b/src/queue.cr index 6f8e6f0..4ae64fe 100644 --- a/src/queue.cr +++ b/src/queue.cr @@ -5,9 +5,10 @@ class App::CommandQueue def push(ts : Int32, cmd : Command) @data.push({ts: ts, cmd: cmd}) - @data.sort! do |x| - -x.[:ts] + @data.sort! do |a, b| + b[:ts] <=> a[:ts] end + # puts @data end def pop(ts : Int32) diff --git a/src/village.cr b/src/village.cr index 2e13754..4e75ee3 100644 --- a/src/village.cr +++ b/src/village.cr @@ -16,21 +16,23 @@ class Resources end abstract class Command - abstract def start(world : World) + abstract def start(world : World) : Int32 abstract def finish(world : World) end class BuildWoodMillCommand < Command + BASE_TIME = 30 + def initialize(@point : Point) end def start(world : World) : Int32 - printf "start build mill at [%d:%d]\n", @point.x, @point.y - return 30 + printf " << start build mill at [%d:%d]\n", @point.x, @point.y + return BASE_TIME end def finish(world : World) - printf "finish build mill at [%d,%d]\n", @point.x, @point.y + printf " << finish build mill at [%d,%d]\n", @point.x, @point.y mill = WoodMillTile.new(@point) world.map.set(mill) world.push(GetWoodCommand.new(@point)) @@ -51,11 +53,64 @@ class GetWoodCommand < Command dist = @point.distance(wood_point) tile = world.map.get(wood_point) @wood = tile.withdraw(BASE_WOOD) - printf "start cut down wood at [%d,%d] -> %d -> %d -> [%d,%d]\n", + printf " << start cut down wood at [%d,%d] -> %d -> %d -> [%d,%d]\n", @point.x, @point.y, dist, @wood, wood_point.x, wood_point.y return BASE_TIME + 2 * dist + else + printf " << no wood tile\n" + @wood = 0 + return BASE_TIME + end + end + + def finish(world : World) + printf " << finish cut down wood at [%d,%d]\n", @point.x, @point.y + world.resources.add_wood(@wood) + world.push(GetWoodCommand.new(@point)) + end +end + +class BuildForesterHouseCommand < Command + BASE_TIME = 50 + + def initialize(@point : Point) + end + + def start(world : World) : Int32 + printf " >> start build forester house at [%d:%d]\n", @point.x, @point.y + return BASE_TIME + end + + def finish(world : World) + printf " >> finish build forester house at [%d,%d]\n", @point.x, @point.y + tile = ForesterHouseTile.new(@point) + world.map.set(tile) + world.push(GrowWoodCommand.new(@point)) + end +end + +class GrowWoodCommand < Command + BASE_TIME = 15 + BASE_WOOD = 30 + + @wood_point : Point | Nil + + def initialize(@point : Point) + @wood_point = nil + end + + def start(world : World) : Int32 + wood_point = world.map.nearest_any_wood(@point) + if !wood_point.nil? + dist = @point.distance(wood_point) + @wood_point = wood_point + printf " >> start grow wood at [%d,%d] -> %d -> [%d,%d]\n", + @point.x, @point.y, + dist, + wood_point.x, wood_point.y + return BASE_TIME + 2 * dist else printf "no wood tile\n" @wood = 0 @@ -64,9 +119,12 @@ class GetWoodCommand < Command end def finish(world : World) - printf "finish cut down wood at [%d,%d]\n", @point.x, @point.y - world.resources.add_wood(@wood) - world.push(GetWoodCommand.new(@point)) + printf " >> finish grow wood at [%d,%d]\n", @point.x, @point.y + if !@wood_point.nil? + tile = world.map.get(@wood_point.as(Point)) + tile.charge(BASE_WOOD) + end + world.push(GrowWoodCommand.new(@point)) end end @@ -93,7 +151,7 @@ class World def push(command : Command) dur = command.start(self) done_at = @ts + dur - printf "world:plan `%s` at %d\n", typeof(command), done_at + printf "world : %d : plan `%s` at %d\n", @ts, typeof(command), done_at @queue.push(done_at, command) end @@ -105,7 +163,7 @@ class World end cmd_ts, cmd = item[:ts], item[:cmd] @ts = cmd_ts - printf "world:finish `%s` at %d\n", typeof(cmd), cmd_ts + printf "world : %d : finish `%s`\n", @ts, typeof(cmd) cmd.finish(self) end end @@ -114,5 +172,6 @@ end w = World.new w.map.print w.push(BuildWoodMillCommand.new(Point.new(0, 0))) +w.push(BuildForesterHouseCommand.new(Point.new(0, 0))) w.run(120) printf "Wood: %d\n", w.resources.wood