Refactor for expansion types

This commit is contained in:
Anton Vakhrushev 2019-09-20 18:23:36 +03:00
parent d8d9beaf60
commit 6df32784a8
6 changed files with 155 additions and 176 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@
/docs/ /docs/
/lib/ /lib/
*.dwarf *.dwarf
*.sublime*

View File

@ -13,18 +13,18 @@
## Ресурсы: ## Ресурсы:
- [ ] Кристаллы (базовый ресурс) - [x] Кристаллы (базовый ресурс)
## Здания: ## Здания:
### Базовые здания ### Базовые здания
- [ ] Главная база (склад) - [x] Главная база (склад)
- [ ] Добыча кристаллов - [x] Добыча кристаллов
- [ ] Выращивание кристаллов - [x] Выращивание кристаллов
- [ ] Терраформатор - [ ] Терраформатор
## Карта ## Карта
- [ ] Скалы - [x] Скалы
- [ ] Вода - [ ] Вода

View File

@ -1,138 +1,114 @@
require "colorize" require "./tile"
abstract class Command abstract class Command
abstract def start(world : World) : Int32 abstract def start(world : World) : Int32
abstract def finish(world : World) abstract def finish(world : World)
end end
class BuildWoodMillCommand < Command class BuildCrystalHarvesterCommand < Command
BASE_TIME = 30 BUILD_TIME = 30
def initialize(@point : Point) def initialize(@point : Point)
end end
def start(world : World) : Int32 def start(world : World) : Int32
printf " << start build mill at [%d:%d]\n", @point.x, @point.y BUILD_TIME
BASE_TIME
end end
def finish(world : World) def finish(world : World)
printf " << finish build mill at [%d,%d]\n", @point.x, @point.y harverster = CrystalHarvesterTile.new(@point)
mill = WoodMillTile.new(@point) world.map.set(harverster)
world.map.set(mill) world.push(HarvestCrystalCommand.new(@point))
world.push(GetWoodCommand.new(@point))
end end
end end
class GetWoodCommand < Command class HarvestCrystalCommand < Command
BASE_TIME = 10 HARVEST_VALUE = 80
BASE_WOOD = 80 HARVEST_TIME = 10
REST_TIME = 5 REST_TIME = 5
def initialize(@point : Point) def initialize(@point : Point)
@wood = 0 @value = 0
end end
def start(world : World) : Int32 def start(world : World) : Int32
wood_tile = nearest_wood(world) deposit_tile = nearest_deposit(world)
stock_tile = nearest_stock(world) stock_tile = nearest_stock(world)
if wood_tile && stock_tile if deposit_tile && stock_tile
calc_time(wood_tile.as(Tile), stock_tile.as(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 else
puts " << no wood or stock tile".colorize(:red)
REST_TIME REST_TIME
end end
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) def finish(world : World)
printf " << finish cut down wood at [%d,%d]\n", @point.x, @point.y world.resources.add_crystal(@value)
world.resources.add_wood(@wood) world.push(HarvestCrystalCommand.new(@point))
world.push(GetWoodCommand.new(@point))
end end
private def nearest_wood(world : World) private def nearest_deposit(world : World)
world.map.nearest_tile @point do |tile| world.map.nearest_tile @point do |tile|
tile.supports(TileType::Wood) && tile.cur > 0 tile.type == TileType::CrystalDeposits && tile.cur > 0
end end
end end
private def nearest_stock(world : World) private def nearest_stock(world : World)
world.map.nearest_tile @point do |tile| world.map.nearest_tile @point do |tile|
tile.supports(TileType::Stock) tile.type == TileType::Warehouse
end end
end end
end end
class BuildForesterHouseCommand < Command class BuildCrystalRestorerCommand < Command
BASE_TIME = 50 BUILD_TIME = 50
def initialize(@point : Point) def initialize(@point : Point)
end end
def start(world : World) : Int32 def start(world : World) : Int32
printf " >> start build forester house at [%d:%d]\n", @point.x, @point.y BUILD_TIME
BASE_TIME
end end
def finish(world : World) def finish(world : World)
printf " >> finish build forester house at [%d,%d]\n", @point.x, @point.y world.map.set(CrystalRestorerTile.new(@point))
tile = ForesterHouseTile.new(@point) world.push(RestoreCrystalCommand.new(@point))
world.map.set(tile)
world.push(GrowWoodCommand.new(@point))
end end
end end
class GrowWoodCommand < Command class RestoreCrystalCommand < Command
BASE_TIME = 15 RESTORE_TIME = 15
BASE_WOOD = 30 RESTORE_VALUE = 30
REST_TIME = 5 REST_TIME = 5
@wood_tile : Tile | Nil @target_tile : Tile | Nil
def initialize(@point : Point) def initialize(@point : Point)
@wood_tile = nil @target_tile = nil
end end
def start(world : World) : Int32 def start(world : World) : Int32
@wood_tile = nearest_wood(world) @target_tile = nearest_deposit(world)
if @wood_tile if @target_tile
calc_time(@wood_tile.as(Tile)) dist = @point.distance(@target_tile.as(Tile).point)
RESTORE_TIME + 2 * dist
else else
printf " >> no wood tile\n"
REST_TIME REST_TIME
end end
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) def finish(world : World)
printf " >> finish grow wood at [%d,%d]\n", @point.x, @point.y if @target_tile
if @wood_tile @target_tile.as(Tile).charge(RESTORE_VALUE)
printf " >> finish grow wood for %d\n", BASE_WOOD
@wood_tile.as(Tile).charge(BASE_WOOD)
end end
world.push(GrowWoodCommand.new(@point)) world.push(RestoreCrystalCommand.new(@point))
end end
private def nearest_wood(world : World) private def nearest_deposit(world : World)
world.map.nearest_tile @point do |tile| 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 end
end end

View File

@ -4,15 +4,15 @@ require "./map"
require "./queue" require "./queue"
class Resources class Resources
def initialize(@wood = 0) def initialize(@crystal = 0)
end end
def add_wood(x) def add_crystal(x)
@wood += x @crystal += x
end end
def wood def crystal
@wood @crystal
end end
end end
@ -59,9 +59,9 @@ end
w = World.new w = World.new
w.map.print w.map.print
w.push(BuildWoodMillCommand.new(Point.new(2, 3))) w.push(BuildCrystalHarvesterCommand.new(Point.new(2, 3)))
w.push(BuildForesterHouseCommand.new(Point.new(1, 2))) w.push(BuildCrystalRestorerCommand.new(Point.new(1, 2)))
w.push(BuildForesterHouseCommand.new(Point.new(3, 2))) w.push(BuildCrystalRestorerCommand.new(Point.new(3, 2)))
w.run(60) w.run(60)
w.map.print w.map.print
printf "Wood: %d\n", w.resources.wood printf "Wood: %d\n", w.resources.crystal

View File

@ -13,97 +13,6 @@ struct Point
end end
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 class Map
SIZE = 4 SIZE = 4
@ -111,13 +20,13 @@ class Map
@data = {} of String => Tile @data = {} of String => Tile
(0...SIZE).each do |x| (0...SIZE).each do |x|
(0...SIZE).each do |y| (0...SIZE).each do |y|
self.set(StoneTile.new(Point.new(x, y))) self.set(PlateauTile.new(Point.new(x, y)))
end end
end end
self.set(MainBaseTile.new(Point.new(0, 0))) self.set(MainBaseTile.new(Point.new(0, 0)))
self.set(WoodTile.new(Point.new(1, 1), 100)) self.set(CrystalTile.new(Point.new(1, 1), 100))
self.set(WoodTile.new(Point.new(3, 1), 200)) self.set(CrystalTile.new(Point.new(3, 1), 200))
self.set(WoodTile.new(Point.new(2, 2), 100)) self.set(CrystalTile.new(Point.new(2, 2), 100))
end end
def get(point : Point) : Tile def get(point : Point) : Tile

93
src/tile.cr Normal file
View File

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