From fcc7a4aa62844a44976c14bf41ac974554c1156f Mon Sep 17 00:00:00 2001 From: mayconmrr Date: Sat, 1 Aug 2020 12:42:51 -0600 Subject: [PATCH 1/3] Code improvements by using ruby matrix lib --- tictactoe/tic_tac_toe.rb | 92 +++++++++++++--------------------------- 1 file changed, 30 insertions(+), 62 deletions(-) diff --git a/tictactoe/tic_tac_toe.rb b/tictactoe/tic_tac_toe.rb index 05db3f7..29f549a 100644 --- a/tictactoe/tic_tac_toe.rb +++ b/tictactoe/tic_tac_toe.rb @@ -1,83 +1,51 @@ +require 'matrix' class TicTacToe def initialize(board) - @board = board + @board = Matrix[*board] + @board_dimension = board.first.size end def winner - row1 = @board[0] - row2 = @board[1] - row3 = @board[2] + return 'o' if lines_for('o') + return 'x' if lines_for('x') - # row checks + return 'o' if columns_for('o') + return 'x' if columns_for('x') - if row1[0] == "o" && row1[1] == "o" && row1[2] == "o" - return "o" - end - - if row2[0] == "o" && row2[1] == "o" && row2[2] == "o" - return "o" - end - - if row3[0] == "o" && row3[1] == "o" && row3[2] == "o" - return "o" - end - - if row1[0] == "x" && row1[1] == "x" && row1[2] == "x" - return "x" - end - - if row2[0] == "x" && row2[1] == "x" && row2[2] == "x" - return "x" - end - - if row3[0] == "x" && row3[1] == "x" && row3[2] == "x" - return "x" - end - - # column checks - - if row1[0] == "o" && row2[0] == "o" && row3[0] == "o" - return "o" - end + return 'o' if diagonals_for('o') + return 'x' if diagonals_for('x') - if row1[1] == "o" && row2[1] == "o" && row3[1] == "o" - return "o" - end + 'draw' + end - if row1[2] == "o" && row2[2] == "o" && row3[2] == "o" - return "o" - end + private - if row1[0] == "x" && row2[0] == "x" && row3[0] == "x" - return "x" + def lines_for(string) + @board_dimension.times do |i| + return true if @board.row(i).uniq == [string] end - if row1[1] == "x" && row2[1] == "x" && row3[1] == "x" - return "x" - end + false + end - if row1[2] == "x" && row2[2] == "x" && row3[2] == "x" - return "x" + def columns_for(string) + @board_dimension.times do |i| + return true if @board.column(i).uniq == [string] end - # diagonal checks - - if row1[0] == "o" && row2[1] == "o" && row3[2] == "o" - return "o" - end + false + end - if row1[2] == "o" && row2[1] == "o" && row3[0] == "o" - return "o" - end + def diagonals_for(string) + return true if @board.each(:diagonal).to_a.uniq == [string] - if row1[0] == "x" && row2[1] == "x" && row3[2] == "x" - return "x" - end + return true if matrix_reverse.each(:diagonal).to_a.uniq == [string] - if row1[2] == "x" && row2[1] == "x" && row3[0] == "x" - return "x" - end + false + end - return "draw" + def matrix_reverse + revert_matrix = @board.to_a.map(&:reverse) + Matrix[*revert_matrix] end end From 62442c4483d3893399efef356c84fc9d8d83523a Mon Sep 17 00:00:00 2001 From: mayconmrr Date: Sat, 1 Aug 2020 12:47:44 -0600 Subject: [PATCH 2/3] Implement unfinished_game method when the board is not completed --- tictactoe/spec/tic_tac_toe_spec.rb | 122 ++++++++++++++--------------- tictactoe/tic_tac_toe.rb | 6 ++ 2 files changed, 67 insertions(+), 61 deletions(-) diff --git a/tictactoe/spec/tic_tac_toe_spec.rb b/tictactoe/spec/tic_tac_toe_spec.rb index edc016b..1d44647 100644 --- a/tictactoe/spec/tic_tac_toe_spec.rb +++ b/tictactoe/spec/tic_tac_toe_spec.rb @@ -155,65 +155,65 @@ end end - # describe "5 x 5 board" do - # it "returns the correct winner when match found on a row" do - # board = [ - # ["o", "o", "o", "o", "o"], - # ["x", "x", " ", " ", " "], - # ["x", "x", "x", " ", " "], - # [" ", " ", " ", " ", " "], - # [" ", " ", " ", " ", " "] - # ] - - # expect(TicTacToe.new(board).winner).to eq("o") - # end - - # it "returns the correct winner when match found on a column" do - # board = [ - # ["o", "x", "x", " ", " "], - # ["o", "x", " ", " ", " "], - # ["o", "x", "x", " ", " "], - # ["o", " ", " ", " ", " "], - # ["o", " ", " ", " ", " "] - # ] - - # expect(TicTacToe.new(board).winner).to eq("o") - # end - - # it "returns the correct winner when match found on a forward diagonal" do - # board = [ - # [" ", "x", "x", " ", "o"], - # [" ", "x", " ", "o", " "], - # ["x", "x", "o", " ", " "], - # [" ", "o", " ", " ", " "], - # ["o", " ", " ", " ", " "] - # ] - - # expect(TicTacToe.new(board).winner).to eq("o") - # end - - # it "returns the correct winner when match found on a backward diagonal" do - # board = [ - # ["o", "x", "x", " ", " "], - # [" ", "o", " ", "x", " "], - # ["x", "x", "o", " ", " "], - # [" ", " ", " ", "o", " "], - # [" ", " ", " ", " ", "o"] - # ] - - # expect(TicTacToe.new(board).winner).to eq("o") - # end - # end - - # describe "unfinished" do - # it "returns 'unfinished' when the board not finished yet" do - # board = [ - # ["o", "x", "o"], - # ["o", "x", "x"], - # ["x", "o", " "] - # ] - - # expect(TicTacToe.new(board).winner).to eq("unfinished") - # end - # end + describe "5 x 5 board" do + it "returns the correct winner when match found on a row" do + board = [ + ["o", "o", "o", "o", "o"], + ["x", "x", " ", " ", " "], + ["x", "x", "x", " ", " "], + [" ", " ", " ", " ", " "], + [" ", " ", " ", " ", " "] + ] + + expect(TicTacToe.new(board).winner).to eq("o") + end + + it "returns the correct winner when match found on a column" do + board = [ + ["o", "x", "x", " ", " "], + ["o", "x", " ", " ", " "], + ["o", "x", "x", " ", " "], + ["o", " ", " ", " ", " "], + ["o", " ", " ", " ", " "] + ] + + expect(TicTacToe.new(board).winner).to eq("o") + end + + it "returns the correct winner when match found on a forward diagonal" do + board = [ + [" ", "x", "x", " ", "o"], + [" ", "x", " ", "o", " "], + ["x", "x", "o", " ", " "], + [" ", "o", " ", " ", " "], + ["o", " ", " ", " ", " "] + ] + + expect(TicTacToe.new(board).winner).to eq("o") + end + + it "returns the correct winner when match found on a backward diagonal" do + board = [ + ["o", "x", "x", " ", " "], + [" ", "o", " ", "x", " "], + ["x", "x", "o", " ", " "], + [" ", " ", " ", "o", " "], + [" ", " ", " ", " ", "o"] + ] + + expect(TicTacToe.new(board).winner).to eq("o") + end + end + + describe "unfinished" do + it "returns 'unfinished' when the board not finished yet" do + board = [ + ["o", "x", "o"], + ["o", "x", "x"], + ["x", "o", " "] + ] + + expect(TicTacToe.new(board).winner).to eq("unfinished") + end + end end diff --git a/tictactoe/tic_tac_toe.rb b/tictactoe/tic_tac_toe.rb index 29f549a..a76c45d 100644 --- a/tictactoe/tic_tac_toe.rb +++ b/tictactoe/tic_tac_toe.rb @@ -15,6 +15,8 @@ def winner return 'o' if diagonals_for('o') return 'x' if diagonals_for('x') + return 'unfinished' if unfinished_game? + 'draw' end @@ -48,4 +50,8 @@ def matrix_reverse revert_matrix = @board.to_a.map(&:reverse) Matrix[*revert_matrix] end + + def unfinished_game? + @board.to_a.flatten.include?(' ') + end end From 0c00bc99a694cbc17645ec3d99334f0fa0d03479 Mon Sep 17 00:00:00 2001 From: mayconmrr Date: Sat, 1 Aug 2020 12:59:08 -0600 Subject: [PATCH 3/3] Improve winner method readability --- tictactoe/tic_tac_toe.rb | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/tictactoe/tic_tac_toe.rb b/tictactoe/tic_tac_toe.rb index a76c45d..2facc6a 100644 --- a/tictactoe/tic_tac_toe.rb +++ b/tictactoe/tic_tac_toe.rb @@ -6,34 +6,27 @@ def initialize(board) end def winner - return 'o' if lines_for('o') - return 'x' if lines_for('x') + return 'o' if victory_for?('o') - return 'o' if columns_for('o') - return 'x' if columns_for('x') + return 'x' if victory_for?('x') - return 'o' if diagonals_for('o') - return 'x' if diagonals_for('x') - - return 'unfinished' if unfinished_game? - - 'draw' + unfinished_game? ? 'unfinished' : 'draw' end private + def victory_for?(string) + lines_for(string) || columns_for(string) || diagonals_for(string) + end + def lines_for(string) - @board_dimension.times do |i| - return true if @board.row(i).uniq == [string] - end + @board_dimension.times { |i| return true if @board.row(i).uniq == [string] } false end def columns_for(string) - @board_dimension.times do |i| - return true if @board.column(i).uniq == [string] - end + @board_dimension.times { |i| return true if @board.column(i).uniq == [string] } false end