Move part of game code to Game namespace

This commit is contained in:
Anton Vakhrushev 2019-10-04 16:40:42 +03:00
parent d4b37377b9
commit ce9d9afd31
6 changed files with 138 additions and 137 deletions

View File

@ -4,7 +4,7 @@ require "./../src/game/command"
macro define_dummy_classes(count) macro define_dummy_classes(count)
{% for i in (1...count) %} {% for i in (1...count) %}
class Test::DummyCommand{{ i }} < Command class Test::DummyCommand{{ i }} < Game::Command
def start(world) : Int32 def start(world) : Int32
end end

View File

@ -3,18 +3,18 @@ require "../src/game/world"
describe "World" do describe "World" do
it "should build crystal harvester" do it "should build crystal harvester" do
world = World.new world = Game::World.new
point = Point.new(2, 3) point = Point.new(2, 3)
cmd = BuildCrystalHarvesterCommand.new(point) cmd = Game::BuildCrystalHarvesterCommand.new(point)
world.push(cmd) world.push(cmd)
world.run(100) world.run(100)
world.map.get(point).has_role(TileRole::CrystalHarvester) world.map.get(point).has_role(TileRole::CrystalHarvester)
end end
it "should fail when not enought resources" do it "should fail when not enought resources" do
world = World.new world = Game::World.new
point = Point.new(2, 3) point = Point.new(2, 3)
cmd = BuildCrystalRestorerCommand.new(point) cmd = Game::BuildCrystalRestorerCommand.new(point)
expect_raises(NotEnoughtResources) do expect_raises(NotEnoughtResources) do
world.push(cmd) world.push(cmd)
end end

View File

@ -5,7 +5,7 @@ require "./game/resources"
require "./game/world" require "./game/world"
require "./cli/command_router" require "./cli/command_router"
world = World.new world = Game::World.new
router = CLI::CommandRouter.new router = CLI::CommandRouter.new
@ -29,20 +29,20 @@ end
router.add "harv {x} {y}" do |p| router.add "harv {x} {y}" do |p|
x = p["x"].to_i32 x = p["x"].to_i32
y = p["y"].to_i32 y = p["y"].to_i32
world.push(BuildCrystalHarvesterCommand.new(Point.new(x, y))) world.push(Game::BuildCrystalHarvesterCommand.new(Point.new(x, y)))
printf "Build harvester at %d %d\n", x, y printf "Build harvester at %d %d\n", x, y
end end
router.add "rest {x} {y}" do |p| router.add "rest {x} {y}" do |p|
x = p["x"].to_i32 x = p["x"].to_i32
y = p["y"].to_i32 y = p["y"].to_i32
world.push(BuildCrystalRestorerCommand.new(Point.new(x, y))) world.push(Game::BuildCrystalRestorerCommand.new(Point.new(x, y)))
end end
router.add "terr {x} {y}" do |p| router.add "terr {x} {y}" do |p|
x = p["x"].to_i32 x = p["x"].to_i32
y = p["y"].to_i32 y = p["y"].to_i32
world.push(BuildTerraformerCommand.new(Point.new(x, y))) world.push(Game::BuildTerraformerCommand.new(Point.new(x, y)))
end end
def normalize_command(cmd) def normalize_command(cmd)

View File

@ -1,149 +1,151 @@
require "./tile" require "./tile"
abstract class Command module Game
abstract def start(world : World) : Int32 abstract class Command
abstract def finish(world : World) abstract def start(world : World) : Int32
end abstract def finish(world : World)
class BuildCrystalHarvesterCommand < Command
BUILD_TIME = 30
def initialize(@point : Point)
end end
def start(world : World) : Int32 class BuildCrystalHarvesterCommand < Command
BUILD_TIME BUILD_TIME = 30
end
def finish(world : World) def initialize(@point : Point)
world.map.set(CrystalHarvesterTile.new(@point)) end
world.push(HarvestCrystalCommand.new(@point))
end
end
class HarvestCrystalCommand < Command def start(world : World) : Int32
HARVEST_VALUE = 80 BUILD_TIME
HARVEST_TIME = 10 end
REST_TIME = 5
def initialize(@point : Point) def finish(world : World)
@value = 0 world.map.set(CrystalHarvesterTile.new(@point))
end world.push(HarvestCrystalCommand.new(@point))
def start(world : World) : Int32
deposit_tile = nearest_deposit(world)
stock_tile = nearest_stock(world)
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
REST_TIME
end end
end end
def finish(world : World) class HarvestCrystalCommand < Command
world.resources.inc(ResourceType::Crystal, @value) HARVEST_VALUE = 80
world.push(HarvestCrystalCommand.new(@point)) HARVEST_TIME = 10
end REST_TIME = 5
private def nearest_deposit(world : World) def initialize(@point : Point)
world.map.nearest_tile @point do |tile| @value = 0
tile.has_role(TileRole::CrystalDeposits) && tile.cur > 0 end
def start(world : World) : Int32
deposit_tile = nearest_deposit(world)
stock_tile = nearest_stock(world)
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
REST_TIME
end
end
def finish(world : World)
world.resources.inc(ResourceType::Crystal, @value)
world.push(HarvestCrystalCommand.new(@point))
end
private def nearest_deposit(world : World)
world.map.nearest_tile @point do |tile|
tile.has_role(TileRole::CrystalDeposits) && tile.cur > 0
end
end
private def nearest_stock(world : World)
world.map.nearest_tile @point do |tile|
tile.has_role(TileRole::Warehouse)
end
end end
end end
private def nearest_stock(world : World) class BuildCrystalRestorerCommand < Command
world.map.nearest_tile @point do |tile| CRYSTALS_COST = 100
tile.has_role(TileRole::Warehouse) BUILD_TIME = 50
def initialize(@point : Point)
end end
end
end
class BuildCrystalRestorerCommand < Command def start(world : World) : Int32
CRYSTALS_COST = 100 world.resources.dec(ResourceType::Crystal, CRYSTALS_COST)
BUILD_TIME = 50 BUILD_TIME
end
def initialize(@point : Point) def finish(world : World)
end world.map.set(CrystalRestorerTile.new(@point))
world.push(RestoreCrystalCommand.new(@point))
def start(world : World) : Int32
world.resources.dec(ResourceType::Crystal, CRYSTALS_COST)
BUILD_TIME
end
def finish(world : World)
world.map.set(CrystalRestorerTile.new(@point))
world.push(RestoreCrystalCommand.new(@point))
end
end
class RestoreCrystalCommand < Command
RESTORE_TIME = 15
RESTORE_VALUE = 30
REST_TIME = 5
@target_tile : Tile | Nil = nil
def initialize(@point : Point)
end
def start(world : World) : Int32
@target_tile = nearest_deposit(world)
if @target_tile
dist = @point.distance(@target_tile.as(Tile).point)
RESTORE_TIME + 2 * dist
else
REST_TIME
end end
end end
def finish(world : World) class RestoreCrystalCommand < Command
if @target_tile RESTORE_TIME = 15
@target_tile.as(Tile).charge(RESTORE_VALUE) RESTORE_VALUE = 30
REST_TIME = 5
@target_tile : Tile | Nil = nil
def initialize(@point : Point)
end
def start(world : World) : Int32
@target_tile = nearest_deposit(world)
if @target_tile
dist = @point.distance(@target_tile.as(Tile).point)
RESTORE_TIME + 2 * dist
else
REST_TIME
end
end
def finish(world : World)
if @target_tile
@target_tile.as(Tile).charge(RESTORE_VALUE)
end
world.push(RestoreCrystalCommand.new(@point))
end
private def nearest_deposit(world : World)
world.map.nearest_tile @point do |tile|
tile.has_role(TileRole::CrystalDeposits) && tile.cur < tile.cap
end
end end
world.push(RestoreCrystalCommand.new(@point))
end end
private def nearest_deposit(world : World) class BuildTerraformerCommand < Command
world.map.nearest_tile @point do |tile| CRYSTALS_COST = 100
tile.has_role(TileRole::CrystalDeposits) && tile.cur < tile.cap BUILD_TIME = 120
def initialize(@point : Point)
end
def start(world : World) : Int32
world.resources.dec(ResourceType::Crystal, CRYSTALS_COST)
BUILD_TIME
end
def finish(world : World)
world.map.set(TerraformerTile.new(@point))
world.push(TerraformCommand.new(@point))
end
end
class TerraformCommand < Command
PRODUCTION_TIME = 60
PRODUCTION_VALUE = 5
def initialize(@point : Point)
end
def start(world : World) : Int32
PRODUCTION_TIME
end
def finish(world : World)
world.resources.inc(ResourceType::Terraformation, PRODUCTION_VALUE)
world.push(TerraformCommand.new(@point))
end end
end end
end end
class BuildTerraformerCommand < Command
CRYSTALS_COST = 100
BUILD_TIME = 120
def initialize(@point : Point)
end
def start(world : World) : Int32
world.resources.dec(ResourceType::Crystal, CRYSTALS_COST)
BUILD_TIME
end
def finish(world : World)
world.map.set(TerraformerTile.new(@point))
world.push(TerraformCommand.new(@point))
end
end
class TerraformCommand < Command
PRODUCTION_TIME = 60
PRODUCTION_VALUE = 5
def initialize(@point : Point)
end
def start(world : World) : Int32
PRODUCTION_TIME
end
def finish(world : World)
world.resources.inc(ResourceType::Terraformation, PRODUCTION_VALUE)
world.push(TerraformCommand.new(@point))
end
end

View File

@ -1,6 +1,6 @@
class App::Queue class App::Queue
struct Item struct Item
def initialize(@ts : Int32, @command : Command) def initialize(@ts : Int32, @command : Game::Command)
end end
getter ts getter ts
@ -11,7 +11,7 @@ class App::Queue
@data = [] of Item @data = [] of Item
end end
def push(ts : Int32, value : Command) def push(ts : Int32, value : Game::Command)
# very unoptimal algo # very unoptimal algo
@data.push(Item.new(ts, value)) @data.push(Item.new(ts, value))
@data.sort! do |a, b| @data.sort! do |a, b|

View File

@ -1,10 +1,9 @@
require "./resources" require "./resources"
class World class Game::World
property ts : Int32 property ts : Int32
def initialize def initialize(@ts = 0)
@ts = 0
@map = Map.new @map = Map.new
@resources = Resources.new @resources = Resources.new
@tasks = App::Queue.new @tasks = App::Queue.new