Created
April 17, 2018 19:01
-
-
Save StevenJL/a82361a6bdb21c6380f33ea293774e9d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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