Skip to content

Instantly share code, notes, and snippets.

@ugisozols
Created July 30, 2013 18:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ugisozols/6115340 to your computer and use it in GitHub Desktop.
Save ugisozols/6115340 to your computer and use it in GitHub Desktop.
require "rspec"
class Grid
attr_reader :cells, :ships
SIZE = 10
def initialize
@cells = SIZE.times.map { [nil] * SIZE }
@ships = []
end
def display
cells.map do |row|
row.map do |cell|
cell || '.'
end.join + "\n"
end.join
end
def place_ship(*coordinates)
ships << Ship.new(*coordinates)
end
def shoot(x, y)
if ship = ships.detect{|s| s.shoot(x, y)}
if ship.sunk?
ship.coordinates.each do |cx, cy|
cells[cx][cy] = "X"
end
else
cells[x][y] = "*"
end
else
cells[x][y] = "O"
end
self
end
def game_over?
ships.all? { |s| s.sunk? }
end
def valid?
ships.all? do |ship|
ship.coordinates.all? do |x, y|
ships.all? do |other_ship|
next true if ship == other_ship
other_ship.coordinates.all? do |ox, oy|
(x - ox).abs > 1 || (y - oy).abs > 1
end
end
end
end
end
end
class Ship
attr_reader :coordinates
def initialize(*coordinates)
@coordinates = coordinates
@unshot = @coordinates.dup
end
def shoot(x, y)
@unshot.delete([x, y])
end
def sunk?
@unshot.empty?
end
def valid?
@coordinates.all? do |x,y|
0 <= x && x < Grid::SIZE &&
0 <= y && y < Grid::SIZE
end
end
end
describe Grid do
let(:grid) { Grid.new }
context "with empty" do
it "displays empty grid" do
grid.display.should == <<-EOS
..........
..........
..........
..........
..........
..........
..........
..........
..........
..........
EOS
end
end
context "when 1 single cell ship" do
before do
grid.place_ship([0,0])
end
describe "#shoot" do
it "marks missed shot" do
expect(grid.shoot(1,1).display).to eq(<<-EOS
..........
.O........
..........
..........
..........
..........
..........
..........
..........
..........
EOS
)
end
it "marks successful shot" do
expect(grid.shoot(0,0).display).to eq(<<-EOS
X.........
..........
..........
..........
..........
..........
..........
..........
..........
..........
EOS
)
end
specify "game over when all ships shot" do
grid.shoot(0,0)
expect(grid.game_over?).to be_true
end
end
end
context "when 1 multiple cell ship" do
before do
grid.place_ship([0,0], [0, 1])
end
it "marks successful shot" do
expect(grid.shoot(0,0).display).to eq(<<-EOS
*.........
..........
..........
..........
..........
..........
..........
..........
..........
..........
EOS
)
end
it "marks ship as sunk" do
expect(grid.shoot(0,0).shoot(0,1).display).to eq(<<-EOS
XX........
..........
..........
..........
..........
..........
..........
..........
..........
..........
EOS
)
end
end
describe "valid grid" do
it "is valid with one ship" do
grid.place_ship([0,0], [0, 1])
expect(grid.valid?).to be_true
end
it "is not valid with overlaping ships" do
grid.place_ship([0,0], [0, 1])
grid.place_ship([0,1], [0, 2])
expect(grid.valid?).to be_false
end
it "is valid with two distant ships" do
grid.place_ship([0,0], [0, 1])
grid.place_ship([7,0], [7, 1])
expect(grid.valid?).to be_true
end
it "is not valid with ships that are too close" do
grid.place_ship([0,0], [0, 1])
grid.place_ship([1,2], [1, 3])
expect(grid.valid?).to be_false
end
end
describe "valid ship" do
it "is valid with coordinates inside grid" do
Ship.new([0,0], [0,1]).should be_valid
end
it "is not valid with coordinates outside grid" do
Ship.new([0,0], [0,-1]).should_not be_valid
end
end
context "when placing ships randomly" do
before do
# grid.palce_random_ship(3)
# grid.palce_random_ship(2)
# grid.palce_random_ship(3)
end
it "does something" do
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment