Skip to content

Instantly share code, notes, and snippets.

@jingxia1219
Last active June 18, 2018 01:44
Show Gist options
  • Save jingxia1219/946bfc28ce70a4f23a409bccf33757e7 to your computer and use it in GitHub Desktop.
Save jingxia1219/946bfc28ce70a4f23a409bccf33757e7 to your computer and use it in GitHub Desktop.
App_Academy BattleShip_Solution
require_relative "board"
require_relative "player"
class BattleshipGame
attr_reader :board, :player
def initialize(player = HumanPlayer.new("Jeff"), board = Board.random)
@player = player
@board = board
@hit = false
end
def attack(pos)
if board[pos] == :s
@hit = true
else
@hit = false
end
board[pos] = :x
end
def count
@board.count
end
def declare_winner
puts "Congratulations. You win!"
end
def display_status
system("clear")
board.display
puts "It's a hit!" if hit?
puts "There are #{count} ships remaining."
end
def game_over?
board.won?
end
def hit?
@hit
end
def play
play_turn until game_over?
declare_winner
end
def play_turn
pos = nil
until valid_play?(pos)
display_status
pos = player.get_play
end
attack(pos)
end
def valid_play?(pos)
pos.is_a?(Array) && board.in_range?(pos)
end
end
if __FILE__ == $PROGRAM_NAME
BattleshipGame.new.play
end
class Board
DISPLAY_HASH = {
nil => " ",
:s => " ",
:x => "x"
}
def self.default_grid
Array.new(10) { Array.new(10) }
end
def self.random
self.new(self.default_grid, true)
end
attr_reader :grid
def initialize(grid = self.class.default_grid, random = false)
@grid = grid
randomize if random
end
def [](pos)
row, col = pos
grid[row][col]
end
def []=(pos, val)
row, col = pos
grid[row][col] = val
end
def count
grid.flatten.select { |el| el == :s }.length
end
def display
header = (0..9).to_a.join(" ")
p " #{header}"
grid.each_with_index { |row, i| display_row(row, i) }
end
def display_row(row, i)
chars = row.map { |el| DISPLAY_HASH[el] }.join(" ")
p "#{i} #{chars}"
end
def empty?(pos = nil)
if pos
self[pos].nil?
else
count == 0
end
end
def full?
grid.flatten.none?(&:nil?)
end
def in_range?(pos)
pos.all? { |x| x.between?(0, grid.length - 1) }
end
def place_random_ship
raise "hell" if full?
pos = random_pos
until empty?(pos)
pos = random_pos
end
self[pos] = :s
end
def randomize(count = 10)
count.times { place_random_ship }
end
def random_pos
[rand(size), rand(size)]
end
def size
grid.length
end
def won?
grid.flatten.none? { |el| el == :s }
end
end
class HumanPlayer
def initialize(name)
@name = name
end
def get_play
gets.chomp.split(",").map { |el| Integer(el) }
end
def prompt
puts "Please enter a target square (i.e., '3,4')"
print "> "
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment