Last active
June 18, 2018 01:44
-
-
Save jingxia1219/946bfc28ce70a4f23a409bccf33757e7 to your computer and use it in GitHub Desktop.
App_Academy BattleShip_Solution
This file contains 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_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