aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--board.rb38
-rw-r--r--spec/board_spec.rb84
2 files changed, 122 insertions, 0 deletions
diff --git a/board.rb b/board.rb
index df66a8d..4bef0d3 100644
--- a/board.rb
+++ b/board.rb
@@ -33,5 +33,43 @@ class Board
end
def winner?
+ initial = '.'
+
+ # Check horizontal
+ @board.each do |row|
+ return row[0] if array_items_equal(row) and row[0] != initial
+ end
+
+ # Check vertical
+ @board.transpose.each do |column|
+ return column[0] if array_items_equal(column) and column[0] != initial
+ end
+
+ # Check diagonals
+ descending = [
+ @board[0][0],
+ @board[1][1],
+ @board[2][2]
+ ]
+ if array_items_equal(descending) and descending[0] != initial
+ return descending[0]
+ end
+
+ ascending = [
+ @board[2][0],
+ @board[1][1],
+ @board[0][2]
+ ]
+ if array_items_equal(ascending) and ascending[0] != initial
+ return ascending[0]
+ end
+
+ nil
end
+
+ private
+
+ def array_items_equal(arr)
+ arr.uniq.length == 1
+ end
end
diff --git a/spec/board_spec.rb b/spec/board_spec.rb
index 09f50e1..70caa81 100644
--- a/spec/board_spec.rb
+++ b/spec/board_spec.rb
@@ -59,5 +59,89 @@ EOF
end
describe '#winner?' do
+ before do
+ @board = Board.new
+ end
+
+ it 'must be nil when no player has won' do
+ @board.winner?.must_be_nil
+ end
+
+ it 'must be the winning player' do
+ end
+
+ it 'counts horizontal matches as wins' do
+ @board.instance_variable_set(:@board, [
+ ['X', 'X', 'X'],
+ ['X', 'O', 'O'],
+ ['O', 'X', 'O'],
+ ])
+ @board.winner?.must_equal 'X'
+
+ @board.instance_variable_set(:@board, [
+ ['X', 'O', 'X'],
+ ['O', 'O', 'O'],
+ ['O', 'X', 'X'],
+ ])
+ @board.winner?.must_equal 'O'
+
+ @board.instance_variable_set(:@board, [
+ ['O', 'X', 'X'],
+ ['X', 'O', 'X'],
+ ['O', 'O', 'O'],
+ ])
+ @board.winner?.must_equal 'O'
+ end
+
+ it 'counts vertical matches as wins' do
+ @board.instance_variable_set(:@board, [
+ ['X', 'O', 'X'],
+ ['X', 'O', 'O'],
+ ['X', 'X', 'O'],
+ ])
+ @board.winner?.must_equal 'X'
+
+ @board.instance_variable_set(:@board, [
+ ['X', 'O', 'X'],
+ ['X', 'O', 'O'],
+ ['O', 'O', 'X'],
+ ])
+ @board.winner?.must_equal 'O'
+
+ @board.instance_variable_set(:@board, [
+ ['O', 'X', 'X'],
+ ['X', 'O', 'X'],
+ ['O', 'O', 'X'],
+ ])
+ @board.winner?.must_equal 'X'
+ end
+
+ it 'counts diagonal matches as wins' do
+ @board.instance_variable_set(:@board, [
+ ['O', 'X', 'X'],
+ ['X', 'O', 'O'],
+ ['O', 'X', 'O'],
+ ])
+ @board.winner?.must_equal 'O'
+
+ @board.instance_variable_set(:@board, [
+ ['X', 'O', 'X'],
+ ['O', 'X', 'O'],
+ ['O', 'X', 'X'],
+ ])
+ @board.winner?.must_equal 'X'
+ end
+ end
+
+ describe '#array_items_equal' do
+ it 'is true when all elements in the array are equal' do
+ Board.new.send(:array_items_equal,
+ ['X', 'X', 'X', 'X', 'X', 'X', 'X']).must_equal true
+ end
+
+ it 'is false when any element is not equal to the rest' do
+ Board.new.send(:array_items_equal,
+ ['X', 'O', 'X', 'X', 'X', 'X', 'X']).must_equal false
+ end
end
end