Skip to content

Instantly share code, notes, and snippets.

@StevenJL
Created April 17, 2018 19:01
Show Gist options
  • Select an option

  • Save StevenJL/a82361a6bdb21c6380f33ea293774e9d to your computer and use it in GitHub Desktop.

Select an option

Save StevenJL/a82361a6bdb21c6380f33ea293774e9d to your computer and use it in GitHub Desktop.
require "pry"
class Ship
def self.find_by_id(id)
SHIPS.select {|ship| ship.id == id }.first
end
attr_reader :id, :length
def initialize(id:, length:)
@length = length
@id = id
@times_hit = 0
end
def take_damage
@times_hit -= 1
end
def sunk?
@length - @times_hit == 0
end
end
EMPTY_SPACE = ""
SHIPS = [
Ship.new(id: 1, length: 2),
Ship.new(id: 2, length: 3),
Ship.new(id: 3, length: 4),
Ship.new(id: 4, length: 5),
]
class Board
# Error classes
class ShipOutOfBoardError < StandardError; end
class ShipOnTopOfOtherShipError < StandardError; end
BOARD_ROW_MAX_INDX = 9
BOARD_COL_MAX_INDX = 9
def initialize
@board = create_board
end
def ship_at_location?(coords)
row_indx, col_indx = coords
@board[row_indx][col_indx] != EMPTY_SPACE
end
def register_hit(coords)
row_indx, col_indx = coords
ship_id = @board[row_indx][col_indx]
@board[row_indx][col_indx] = EMPTY_SPACE
ship = Ship.find_by_id(ship_id)
ship.take_damage
# check if ship
# check if won
end
def place(ship, coords, orientation)
raise ShipOutOfBoardError if ship_out_of_range?(ship, coords, orientation)
raise ShipOnTopOfOtherShipError if ship_on_top_other_ship?(ship, coords, orientation)
ship_id = ship.id
ship_length = ship.length
case orientation
when :horizontal
coords_to_write = compute_horizontal_coords(coords, ship_length)
write_ship_id(coords_to_write, ship_id)
when :vertical
coords_to_write = compute_vertical_coords(coords, ship_length)
write_ship_id(coords_to_write, ship_id)
end
end
def print_board
puts @board.inspect
end
def write_ship_id(coords, ship_id)
coords.each do |coord|
row_indx, col_indx = coord
@board[row_indx][col_indx] = ship_id
end
end
def ship_on_top_other_ship?(ship, coords, orientation)
ship_length = ship.length
case orientation
when :horizontal
coords_to_check = compute_horizontal_coords(coords, ship_length)
when :vertical
coords_to_check = compute_vertical_coords(coords, ship_length)
end
coords_to_check.each do |coord|
row_indx, col_indx = coord
return false unless @board[row_indx][col_indx] != EMPTY_SPACE
end
true
end
def create_board
board = []
10.times do
board << Array.new(10, EMPTY_SPACE)
end
board
end
def compute_horizontal_coords(coords, length)
output = []
row_indx, col_indx = coords
length.times do |delta|
output << [row_indx, col_indx + delta]
end
output
end
def compute_vertical_coords(coords, length)
output = []
row_indx, col_indx = coords
length.times do |delta|
output << [row_indx + delta, col_indx]
end
output
end
def ship_out_of_range?(ship, coords, orientation)
ship_length = ship.length
case orientation
when :horizontal
coords_to_check = compute_horizontal_coords(coords, ship_length)
when :vertical
coords_to_check = compute_vertical_coords(coords, ship_length)
end
coords_to_check.each do |coord|
row_indx, col_indx = coord
return true unless row_indx.between?(0, BOARD_ROW_MAX_INDX)
return true unless col_indx.between?(0, BOARD_COL_MAX_INDX)
end
false
end
end
class BattleShipGame
def initialize
@board = Board.new
end
# orientation = :horizontal or :vertial
def place(ship, coords, orientation)
@board.place(ship, coords, orientation)
end
def fire(coords)
if @board.ship_at_location?(coords)
puts "YOU HIT PART OF A SHIP!"
@board.register_hit(coords)
end
end
def print_board
puts @board.print_board
end
end
bsg = BattleShipGame.new
ship1 = SHIPS[0]
# ship4 = SHIPS[3]
bsg.place(ship1, [0,0], :horizontal)
bsg.fire([0,0])
# bsg.place(ship1, [0,0], :horizontal)
# bsg.place(ship4, [9,9], :horizontal)
bsg.print_board
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment