struct Point def initialize(@x : Int32, @y : Int32) end def x @x end def y @y end def distance(p : Point) : Int32 return (p.x - @x).abs + (p.y - @y).abs end end abstract class Tile def initialize(@point : Point) @cap = 0 @cur = 0 end def point @point end def cap @cap end def cur @cur end def withdraw(value) if value >= @cur wd = @cur @cur = 0 return wd else @cur -= value return value end end def charge(value) if value + @cur > @cap @cur = @cap else @cur += value end end abstract def letter : Char end class GrassTile < Tile def letter : Char '.' end end class WoodTile < Tile def initialize(@point : Point, cap : Int32) @cap = cap @cur = cap end def letter : Char 'f' end end class WoodMillTile < Tile def letter : Char 'm' end end class ForesterHouseTile < Tile def letter : Char 'h' end end class Map SIZE = 4 def initialize @data = {} of String => Tile (0...SIZE).each do |x| (0...SIZE).each do |y| self.set(GrassTile.new(Point.new(x, y))) end end 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)) end def get(point : Point) : Tile @data[key(point)] end def set(tile : Tile) @data[key(tile.point)] = tile end def set(point : Point, tile : Tile) @data[key(point)] = tile end def tiles (0...SIZE).each do |x| (0...SIZE).each do |y| point = Point.new(x, y) tile = self.get(point) yield point, tile end end end def nearest_point(point : Point, &block) : Point | Nil p = nil d = Int32::MAX tiles do |tile_point, tile| if (yield tile) tile_dist = tile_point.distance(point) if tile_dist < d d = tile_dist p = tile_point end end end p end def nearest_wood(point : Point) : Point | Nil nearest_point point do |tile| tile.letter == 'f' && tile.cur > 0 end end def nearest_any_wood(point : Point) : Point | Nil nearest_point point do |tile| tile.letter == 'f' && tile.cur < tile.cap end end def print (0...SIZE).each do |x| (0...SIZE).each do |y| printf "%c", @data[key(Point.new(x, y))].letter end printf "\n" end end private def key(p : Point) : String return sprintf "%d:%d", p.x, p.y end end