From 6df32784a8db6f6b36255661268274e356406bf5 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Fri, 20 Sep 2019 18:23:36 +0300 Subject: [PATCH] Refactor for expansion types --- .gitignore | 1 + WORLD.md | 10 ++--- src/command.cr | 110 ++++++++++++++++++----------------------------- src/expansion.cr | 18 ++++---- src/map.cr | 99 ++---------------------------------------- src/tile.cr | 93 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 155 insertions(+), 176 deletions(-) create mode 100644 src/tile.cr diff --git a/.gitignore b/.gitignore index 76cb2d2..58a0a0c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /docs/ /lib/ *.dwarf +*.sublime* \ No newline at end of file diff --git a/WORLD.md b/WORLD.md index 7e70f8e..ad78dc1 100644 --- a/WORLD.md +++ b/WORLD.md @@ -13,18 +13,18 @@ ## Ресурсы: -- [ ] Кристаллы (базовый ресурс) +- [x] Кристаллы (базовый ресурс) ## Здания: ### Базовые здания -- [ ] Главная база (склад) -- [ ] Добыча кристаллов -- [ ] Выращивание кристаллов +- [x] Главная база (склад) +- [x] Добыча кристаллов +- [x] Выращивание кристаллов - [ ] Терраформатор ## Карта -- [ ] Скалы +- [x] Скалы - [ ] Вода diff --git a/src/command.cr b/src/command.cr index 5b39533..2c8cccb 100644 --- a/src/command.cr +++ b/src/command.cr @@ -1,138 +1,114 @@ -require "colorize" +require "./tile" abstract class Command abstract def start(world : World) : Int32 abstract def finish(world : World) end -class BuildWoodMillCommand < Command - BASE_TIME = 30 +class BuildCrystalHarvesterCommand < Command + BUILD_TIME = 30 def initialize(@point : Point) end def start(world : World) : Int32 - printf " << start build mill at [%d:%d]\n", @point.x, @point.y - BASE_TIME + BUILD_TIME end def finish(world : World) - 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)) + harverster = CrystalHarvesterTile.new(@point) + world.map.set(harverster) + world.push(HarvestCrystalCommand.new(@point)) end end -class GetWoodCommand < Command - BASE_TIME = 10 - BASE_WOOD = 80 - REST_TIME = 5 +class HarvestCrystalCommand < Command + HARVEST_VALUE = 80 + HARVEST_TIME = 10 + REST_TIME = 5 def initialize(@point : Point) - @wood = 0 + @value = 0 end def start(world : World) : Int32 - wood_tile = nearest_wood(world) + deposit_tile = nearest_deposit(world) stock_tile = nearest_stock(world) - if wood_tile && stock_tile - calc_time(wood_tile.as(Tile), stock_tile.as(Tile)) + if deposit_tile && stock_tile + wood_dist = @point.distance(deposit_tile.point) + stock_dist = @point.distance(stock_tile.point) + @value = deposit_tile.withdraw(HARVEST_VALUE) + HARVEST_TIME + 2 * wood_dist + 2 * stock_dist else - puts " << no wood or stock tile".colorize(:red) REST_TIME end end - private def calc_time(wood_tile : Tile, stock_tile : Tile) - wood_dist = @point.distance(wood_tile.point) - stock_dist = @point.distance(stock_tile.point) - @wood = wood_tile.withdraw(BASE_WOOD) - printf " << wood %d, %d, %d\n", BASE_TIME, 2 * wood_dist, 2 * stock_dist - BASE_TIME + 2 * wood_dist + 2 * stock_dist - 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)) + world.resources.add_crystal(@value) + world.push(HarvestCrystalCommand.new(@point)) end - private def nearest_wood(world : World) + private def nearest_deposit(world : World) world.map.nearest_tile @point do |tile| - tile.supports(TileType::Wood) && tile.cur > 0 + tile.type == TileType::CrystalDeposits && tile.cur > 0 end end private def nearest_stock(world : World) world.map.nearest_tile @point do |tile| - tile.supports(TileType::Stock) + tile.type == TileType::Warehouse end end end -class BuildForesterHouseCommand < Command - BASE_TIME = 50 +class BuildCrystalRestorerCommand < Command + BUILD_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 - BASE_TIME + BUILD_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)) + world.map.set(CrystalRestorerTile.new(@point)) + world.push(RestoreCrystalCommand.new(@point)) end end -class GrowWoodCommand < Command - BASE_TIME = 15 - BASE_WOOD = 30 - REST_TIME = 5 +class RestoreCrystalCommand < Command + RESTORE_TIME = 15 + RESTORE_VALUE = 30 + REST_TIME = 5 - @wood_tile : Tile | Nil + @target_tile : Tile | Nil def initialize(@point : Point) - @wood_tile = nil + @target_tile = nil end def start(world : World) : Int32 - @wood_tile = nearest_wood(world) - if @wood_tile - calc_time(@wood_tile.as(Tile)) + @target_tile = nearest_deposit(world) + if @target_tile + dist = @point.distance(@target_tile.as(Tile).point) + RESTORE_TIME + 2 * dist else - printf " >> no wood tile\n" REST_TIME end end - private def calc_time(wood_tile : Tile) - wood_point = wood_tile.point - dist = @point.distance(wood_point) - printf " >> start grow wood at [%d,%d] -> %d -> [%d,%d]\n", - @point.x, @point.y, - dist, - wood_point.x, wood_point.y - BASE_TIME + 2 * dist - end - def finish(world : World) - printf " >> finish grow wood at [%d,%d]\n", @point.x, @point.y - if @wood_tile - printf " >> finish grow wood for %d\n", BASE_WOOD - @wood_tile.as(Tile).charge(BASE_WOOD) + if @target_tile + @target_tile.as(Tile).charge(RESTORE_VALUE) end - world.push(GrowWoodCommand.new(@point)) + world.push(RestoreCrystalCommand.new(@point)) end - private def nearest_wood(world : World) + private def nearest_deposit(world : World) world.map.nearest_tile @point do |tile| - tile.supports(TileType::Wood) && tile.cur < tile.cap + tile.type == TileType::CrystalDeposits && tile.cur < tile.cap end end end diff --git a/src/expansion.cr b/src/expansion.cr index 12bdad6..ee92af6 100644 --- a/src/expansion.cr +++ b/src/expansion.cr @@ -4,15 +4,15 @@ require "./map" require "./queue" class Resources - def initialize(@wood = 0) + def initialize(@crystal = 0) end - def add_wood(x) - @wood += x + def add_crystal(x) + @crystal += x end - def wood - @wood + def crystal + @crystal end end @@ -59,9 +59,9 @@ end w = World.new w.map.print -w.push(BuildWoodMillCommand.new(Point.new(2, 3))) -w.push(BuildForesterHouseCommand.new(Point.new(1, 2))) -w.push(BuildForesterHouseCommand.new(Point.new(3, 2))) +w.push(BuildCrystalHarvesterCommand.new(Point.new(2, 3))) +w.push(BuildCrystalRestorerCommand.new(Point.new(1, 2))) +w.push(BuildCrystalRestorerCommand.new(Point.new(3, 2))) w.run(60) w.map.print -printf "Wood: %d\n", w.resources.wood +printf "Wood: %d\n", w.resources.crystal diff --git a/src/map.cr b/src/map.cr index 9873ad2..ee3fe4a 100644 --- a/src/map.cr +++ b/src/map.cr @@ -13,97 +13,6 @@ struct Point end end -enum TileType - Stock - Wood -end - -abstract class Tile - property cap : Int32 = 0 - property cur : Int32 = 0 - - def initialize(@point : Point) - end - - getter point - getter cap - getter cur - - abstract def letter : Char - abstract def supports(t : TileType) : Bool - - def withdraw(value) - if value >= @cur - wd = @cur - @cur = 0 - wd - else - @cur -= value - value - end - end - - def charge(value) - charged = @cur + value - @cur = charged <= @cap ? charged : @cap - end -end - -class StoneTile < Tile - def letter : Char - '.' - end - - def supports(t : TileType) : Bool - false - end -end - -class MainBaseTile < Tile - def letter : Char - 'M' - end - - def supports(t : TileType) : Bool - t == TileType::Stock - end -end - -class WoodTile < Tile - def initialize(@point : Point, cap : Int32) - @cap = cap - @cur = cap - end - - def letter : Char - 'f' - end - - def supports(t : TileType) : Bool - t == TileType::Wood - end -end - -class WoodMillTile < Tile - def letter : Char - 'm' - end - - def supports(t : TileType) : Bool - t == TileType::Wood - end -end - -class ForesterHouseTile < Tile - def letter : Char - 'h' - end - - def supports(t : TileType) : Bool - false - end -end - class Map SIZE = 4 @@ -111,13 +20,13 @@ class Map @data = {} of String => Tile (0...SIZE).each do |x| (0...SIZE).each do |y| - self.set(StoneTile.new(Point.new(x, y))) + self.set(PlateauTile.new(Point.new(x, y))) end end self.set(MainBaseTile.new(Point.new(0, 0))) - self.set(WoodTile.new(Point.new(1, 1), 100)) - self.set(WoodTile.new(Point.new(3, 1), 200)) - self.set(WoodTile.new(Point.new(2, 2), 100)) + self.set(CrystalTile.new(Point.new(1, 1), 100)) + self.set(CrystalTile.new(Point.new(3, 1), 200)) + self.set(CrystalTile.new(Point.new(2, 2), 100)) end def get(point : Point) : Tile diff --git a/src/tile.cr b/src/tile.cr new file mode 100644 index 0000000..da69806 --- /dev/null +++ b/src/tile.cr @@ -0,0 +1,93 @@ +enum TileType + CrystalDeposits + CrystalHarvester + CrystalRestorer + Plateau + Warehouse +end + +abstract class Tile + property cap : Int32 = 0 + property cur : Int32 = 0 + + def initialize(@point : Point) + end + + getter point + getter cap + getter cur + + abstract def letter : Char + abstract def type : TileType + + def withdraw(value) + if value >= @cur + wd = @cur + @cur = 0 + wd + else + @cur -= value + value + end + end + + def charge(value) + charged = @cur + value + @cur = charged <= @cap ? charged : @cap + end +end + +class PlateauTile < Tile + def letter : Char + '.' + end + + def type : TileType + TileType::Plateau + end +end + +class MainBaseTile < Tile + def letter : Char + 'H' + end + + def type : TileType + TileType::Warehouse + end +end + +class CrystalTile < Tile + def initialize(@point : Point, cap : Int32) + @cap = cap + @cur = cap + end + + def letter : Char + 'f' + end + + def type : TileType + TileType::CrystalDeposits + end +end + +class CrystalHarvesterTile < Tile + def letter : Char + 'm' + end + + def type : TileType + TileType::CrystalHarvester + end +end + +class CrystalRestorerTile < Tile + def letter : Char + 'h' + end + + def type : TileType + TileType::CrystalRestorer + end +end