diff options
| -rw-r--r-- | board.rb | 38 | ||||
| -rw-r--r-- | spec/board_spec.rb | 84 |
2 files changed, 122 insertions, 0 deletions
@@ -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 |
