module SiegeBoard
Constants
- EMPTY
- PLAYER_A
- PLAYER_B
- SIZE
- WALL
Public Instance Methods
Source
# File lib/siege_game.rb, line 16 def coord_to_index(coord) match = coord.to_s.strip.match(/\A([A-E])([1-5])\z/i) return nil unless match col = match[1].upcase.ord - "A".ord row = match[2].to_i - 1 return nil unless row.between?(0, SIZE - 1) && col.between?(0, SIZE - 1) row * SIZE + col end
Source
# File lib/siege_game.rb, line 33 def fresh_grid Array.new(SIZE * SIZE, EMPTY) end
Source
# File lib/siege_game.rb, line 27 def index_to_coord(index) row = index / SIZE col = index % SIZE "#{%w[A B C D E][col]}#{row + 1}" end
Source
# File lib/siege_game.rb, line 69 def move_unit(grid:, unit:, dest_index:) return { error: "Invalid coordinate." } if dest_index.nil? return { error: "Destination blocked." } unless grid[dest_index] == EMPTY from = unit_position(grid, unit) return { error: "Unit not on board." } unless from return { error: "Not adjacent." } unless neighbors(from).include?(dest_index) g = grid.dup g[from] = EMPTY g[dest_index] = unit { grid: g } end
Source
# File lib/siege_game.rb, line 44 def neighbors(index) row = index / SIZE col = index % SIZE deltas = [[-1, 0], [1, 0], [0, -1], [0, 1]] deltas.filter_map do |dr, dc| nr = row + dr nc = col + dc next unless nr.between?(0, SIZE - 1) && nc.between?(0, SIZE - 1) nr * SIZE + nc end end
Source
# File lib/siege_game.rb, line 37 def place_units(grid, player_a:, player_b:) g = grid.dup g[coord_to_index("A1")] = PLAYER_A g[coord_to_index("E5")] = PLAYER_B g end
Source
# File lib/siege_game.rb, line 83 def place_wall(grid:, index:) return { error: "Invalid coordinate." } if index.nil? return { error: "Cell occupied." } unless grid[index] == EMPTY g = grid.dup g[index] = WALL { grid: g } end
Source
# File lib/siege_game.rb, line 104 def render(grid) lines = [" A B C D E"] SIZE.times do |row| row_cells = (0...SIZE).map { |col| grid[row * SIZE + col] } lines << "#{row + 1} #{row_cells.join(' ')}" end lines.join("\n") end
Source
# File lib/siege_game.rb, line 57 def unit_for(game, user) if GameStore.same_nick?(user, game["challenger"]) PLAYER_A else PLAYER_B end end
Source
# File lib/siege_game.rb, line 65 def unit_position(grid, unit) grid.index(unit) end
Source
# File lib/siege_game.rb, line 92 def winner?(grid, unit) pos = unit_position(grid, unit) return nil unless pos case unit when PLAYER_A pos == coord_to_index("E5") ? PLAYER_A : nil when PLAYER_B pos == coord_to_index("A1") ? PLAYER_B : nil end end