From fe7d096891758305c9fd0cea0ac9c94d67413825 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Sun, 13 Oct 2019 11:56:21 +0300 Subject: [PATCH] Move app to separate class --- spec/app_spec.cr | 7 ++ spec/spec_helper.cr | 1 + src/app.cr | 149 +++++++++++++++++++++++++++++++++++ src/expansion.cr | 143 +-------------------------------- src/game/building.cr | 2 +- src/game/building_factory.cr | 20 ++--- 6 files changed, 169 insertions(+), 153 deletions(-) create mode 100644 spec/app_spec.cr create mode 100644 src/app.cr diff --git a/spec/app_spec.cr b/spec/app_spec.cr new file mode 100644 index 0000000..8ab8694 --- /dev/null +++ b/spec/app_spec.cr @@ -0,0 +1,7 @@ +require "./spec_helper" + +describe App do + it "should compile" do + app = App.new + end +end diff --git a/spec/spec_helper.cr b/spec/spec_helper.cr index 95301ed..9a592c8 100644 --- a/spec/spec_helper.cr +++ b/spec/spec_helper.cr @@ -1,6 +1,7 @@ require "spec" require "../src/game/**" require "../src/cli/**" +require "../src/app" def create_map_2x2 : Game::Map map = Game::Map.new 2, 2 diff --git a/src/app.cr b/src/app.cr new file mode 100644 index 0000000..376fed2 --- /dev/null +++ b/src/app.cr @@ -0,0 +1,149 @@ +require "colorize" +require "./game/**" +require "./cli/**" + +class App + @ts : Game::TimePoint + + def initialize + @map = Game::Generator.make 5, 5 + @ts = Time.local.to_unix + @world = Game::World.new @map, @ts + @buildings = Game::BuildingFactory.new + @router = CLI::CommandRouter.new + + @buildings.items.each do |i| + t = i[:t] + b = i[:b] + route = sprintf "%s {x} {y}", b.name.downcase + desc = sprintf "Build %s at x,y", b.name + @router.add route, desc do |p| + x = p["x"].to_i32 + y = p["y"].to_i32 + point = Game::Point.new(x, y) + @world.push(Game::BuildCommand.new(point, b)) + printf "Build %s at %d %d\n", b.name, x, y + end + end + + @router.add "help", "Show all commands" do |p| + printf "Commands:\n" + @router.routes.each do |r| + printf " %s - %s\n", r.route, r.desc + end + end + end + + def render_time(ts) + t = Time.unix(ts).in(Time::Location.load("Europe/Moscow")) + # It's future, baby + t += 200.years + t.to_s("%Y-%m-%d %H:%M:%S") + end + + def render_map(world) + rows = world.map.rows + cols = world.map.cols + (0...rows).each do |x| + if x == 0 + printf "+" + (0...cols).each do |y| + printf "------+" + end + print "\n" + end + printf "|" + (0...cols).each do |y| + tile = world.map.get(x, y) + printf "%s %d%d|", tile.letter.colorize(:green), x, y + end + print "\n" + printf "|" + (0...cols).each do |y| + printf " |" + end + print "\n" + printf "|" + (0...cols).each do |y| + tile = world.map.get(x, y) + if tile.letter == 'v' + printf "%6d|", world.map.get(x, y).cur + else + printf " |", world.map.get(x, y).cur + end + end + print "\n" + printf "+" + (0...cols).each do |y| + printf "------+" + end + print "\n" + end + end + + def render_commands(world) + items = world.queue.top(5) + if items.size != 0 + printf "Queue:\n" + end + wts = world.ts + items.each do |i| + ts_diff = i.ts - wts + if ts_diff < 60 + done_time = sprintf " %02ds", ts_diff + else + done_time = sprintf "%d:%02d", ts_diff // 60, ts_diff % 60 + end + printf " %s, %s, %s\n", render_time(i.ts), done_time, i.command.desc + end + end + + def render_resources(world) + printf "Resources:\n Crystals: %5d\n Terraformation: %5d\n", + world.resources[Game::Resources::Type::Crystals], + world.resources[Game::Resources::Type::Terraformation] + end + + def render_world(world) + printf "Now:\n %s\n\n", render_time(world.ts) + if world.win? + printf "YOU WIN!!! Score: %d\n\n", world.score + end + render_commands world + printf "\n" + render_resources world + printf "\n" + render_map world + printf "\n" + end + + def normalize_command(cmd) + cmd.downcase.gsub(/\s+/, ' ').strip + end + + CLEAR_SCREEN_ESC_CODE = "\u{001b}[2J" + + def run + printf CLEAR_SCREEN_ESC_CODE + loop do + render_world @world + printf "In > " + cmd = read_line() + norm = normalize_command(cmd) + if norm == "exit" + break + end + printf CLEAR_SCREEN_ESC_CODE + current_time = Time.local.to_unix + @world.run current_time + begin + @router.handle cmd + rescue Game::NotEnoughtResources + printf ">>> Not enought resources <<<\n" + rescue Game::InvalidPlaceForBuilding + printf ">>> Can't build here <<<\n" + end + printf "\n" + end + end +end diff --git a/src/expansion.cr b/src/expansion.cr index 6bff100..3cb947e 100644 --- a/src/expansion.cr +++ b/src/expansion.cr @@ -1,141 +1,4 @@ -require "colorize" -require "./game/**" -require "./cli/**" +require "./app" -map = Game::Generator.make 5, 5 -ts = Time.local.to_unix -world = Game::World.new map, ts -buildings = Game::BuildingFactory.new -router = CLI::CommandRouter.new - -buildings.items.each do |i| - t = i[:t] - b = i[:b] - route = sprintf "%s {x} {y}", b.name.downcase - desc = sprintf "Build %s at x,y", b.name - router.add route, desc do |p| - x = p["x"].to_i32 - y = p["y"].to_i32 - point = Game::Point.new(x, y) - world.push(Game::BuildCommand.new(point, b)) - printf "Build %s at %d %d\n", b.name, x, y - end -end - -router.add "help", "Show all commands" do |p| - printf "Commands:\n" - router.routes.each do |r| - printf " %s - %s\n", r.route, r.desc - end -end - -def render_time(ts) - t = Time.unix(ts).in(Time::Location.load("Europe/Moscow")) - # It's future, baby - t += 200.years - t.to_s("%Y-%m-%d %H:%M:%S") -end - -def render_map(world) - rows = world.map.rows - cols = world.map.cols - (0...rows).each do |x| - if x == 0 - printf "+" - (0...cols).each do |y| - printf "------+" - end - print "\n" - end - printf "|" - (0...cols).each do |y| - tile = world.map.get(x, y) - printf "%s %d%d|", tile.letter.colorize(:green), x, y - end - print "\n" - printf "|" - (0...cols).each do |y| - printf " |" - end - print "\n" - printf "|" - (0...cols).each do |y| - tile = world.map.get(x, y) - if tile.letter == 'v' - printf "%6d|", world.map.get(x, y).cur - else - printf " |", world.map.get(x, y).cur - end - end - print "\n" - printf "+" - (0...cols).each do |y| - printf "------+" - end - print "\n" - end -end - -def render_commands(world) - items = world.queue.top(5) - if items.size != 0 - printf "Queue:\n" - end - wts = world.ts - items.each do |i| - ts_diff = i.ts - wts - if ts_diff < 60 - done_time = sprintf " %02ds", ts_diff - else - done_time = sprintf "%d:%02d", ts_diff // 60, ts_diff % 60 - end - printf " %s, %s, %s\n", render_time(i.ts), done_time, i.command.desc - end -end - -def render_resources(world) - printf "Resources:\n Crystals: %5d\n Terraformation: %5d\n", - world.resources[Game::Resources::Type::Crystals], - world.resources[Game::Resources::Type::Terraformation] -end - -def render_world(world) - printf "Now:\n %s\n\n", render_time(world.ts) - if world.win? - printf "YOU WIN!!! Score: %d\n\n", world.score - end - render_commands world - printf "\n" - render_resources world - printf "\n" - render_map world - printf "\n" -end - -def normalize_command(cmd) - cmd.downcase.gsub(/\s+/, ' ').strip -end - -CLEAR_SCREEN_ESC_CODE = "\u{001b}[2J" - -printf CLEAR_SCREEN_ESC_CODE -loop do - render_world world - printf "In > " - cmd = read_line() - norm = normalize_command(cmd) - if norm == "exit" - break - end - printf CLEAR_SCREEN_ESC_CODE - current_time = Time.local.to_unix - world.run current_time - begin - router.handle cmd - rescue Game::NotEnoughtResources - printf ">>> Not enought resources <<<\n" - rescue Game::InvalidPlaceForBuilding - printf ">>> Can't build here <<<\n" - end - printf "\n" -end +app = App.new +app.run diff --git a/src/game/building.cr b/src/game/building.cr index 75dd3a0..2ea5d7a 100644 --- a/src/game/building.cr +++ b/src/game/building.cr @@ -9,7 +9,7 @@ module Game end class Mining - def initialize(@ts : TimeSpan, @dep : DepositSpan) + def initialize(@ts : TimeSpan, @dep : Deposit::Span) end getter ts diff --git a/src/game/building_factory.cr b/src/game/building_factory.cr index 9ca4649..79de342 100644 --- a/src/game/building_factory.cr +++ b/src/game/building_factory.cr @@ -4,22 +4,20 @@ module Game @items = [] of NamedTuple(t: Building::Type, b: Building) add( - Building.new Building::Type::StartPoint, "Start", storage: 100 + Building.new Building::Type::StartPoint, storage: 100 ) add( - Building.new Building::Type::CrystalMiner, "Miner", **{ - mining: Production.new( + Building.new Building::Type::CrystalMiner, **{ + mining: Mining.new( ts: 20, - input: Resources.new, - res: Resources::Type::Crystals, - cap: 40, + dep: Deposit::Span.new(Resources::Type::Crystals, 40) ), } ) add( - Building.new Building::Type::CrystalRestorer, "Restorer", **{ + Building.new Building::Type::CrystalRestorer, **{ construction: Construction.new( ts: 30, cost: Resources.new({ @@ -27,17 +25,15 @@ module Game }), requirements: [] of Game::Building::Type ), - restoration: Restoration.new( + restoration: Mining.new( ts: 30, - input: Resources.new, - res: Resources::Type::Crystals, - cap: 20 + dep: Deposit::Span.new(Resources::Type::Crystals, 20) ), } ) add( - Building.new Building::Type::Terraformer, "Terraformator", **{ + Building.new Building::Type::Terraformer, **{ construction: Construction.new( ts: 120, cost: Resources.new({