Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Break down procedure into several helper functions.

At this point, reading Game#play is much more revealing than before, and the
general structure of the application has improved.  It is possible to try out
some of these features in isolation and is now easier to do manual testing.  But
this is still essentially procedural code in an object oriented technicolor
dream coat.

Automated testing would be tedious as-is because of the mixture of presentation
/ control code and logic.  A re-design of the code is in order, replacing the
many procedures that operate on data such as the board with single purpose
objects.  That's what we'll start on next.
  • Loading branch information...
commit 286724de5328fda779caa500ccc76a0ad5de2bd7 1 parent 2579626
@practicingruby authored
Showing with 65 additions and 39 deletions.
  1. +65 −39 lib/tictactoe/game.rb
View
104 lib/tictactoe/game.rb
@@ -1,6 +1,5 @@
module TicTacToe
class Game
-
def initialize
@board = [[nil,nil,nil],
[nil,nil,nil],
@@ -9,59 +8,86 @@ def initialize
@players = [:X, :O].cycle
end
- attr_reader :board, :players
+ attr_reader :board, :players, :current_player
def play
- left_diagonal = [[0,0],[1,1],[2,2]]
- right_diagonal = [[2,0],[1,1],[0,2]]
-
- current_player = players.next
+ start_new_turn
loop do
- puts board.map { |row| row.map { |e| e || " " }.join("|") }.join("\n")
- print "\n>> "
- row, col = gets.split.map { |e| e.to_i }
- puts
-
- begin
- cell_contents = board.fetch(row).fetch(col)
- rescue IndexError
- puts "Out of bounds, try another position"
- next
- end
-
- if cell_contents
- puts "Cell occupied, try another position"
- next
- end
+ display_board
+
+ row, col = move_input
+ next unless valid_move?(row,col)
board[row][col] = current_player
- lines = []
+ if winning_move?(row, col)
+ puts "#{current_player} wins!"
+ return
+ end
- [left_diagonal, right_diagonal].each do |line|
- lines << line if line.include?([row,col])
+ if draw?
+ puts "It's a draw!"
+ return
end
- lines << (0..2).map { |c1| [row, c1] }
- lines << (0..2).map { |r1| [r1, col] }
+ start_new_turn
+ end
+ end
- win = lines.any? do |line|
- line.all? { |row,col| board[row][col] == current_player }
- end
+ def start_new_turn
+ @current_player = @players.next
+ end
- if win
- puts "#{current_player} wins!"
- exit
- end
+ def display_board
+ puts board.map { |row| row.map { |e| e || " " }.join("|") }.join("\n")
+ end
- if board.flatten.compact.length == 9
- puts "It's a draw!"
- exit
- end
+ def winning_move?(row, col)
+ left_diagonal = [[0,0],[1,1],[2,2]]
+ right_diagonal = [[2,0],[1,1],[0,2]]
+
+ lines = []
+
+ [left_diagonal, right_diagonal].each do |line|
+ lines << line if line.include?([row,col])
+ end
+
+ lines << (0..2).map { |c1| [row, c1] }
+ lines << (0..2).map { |r1| [r1, col] }
+
+ lines.any? do |line|
+ line.all? { |row,col| board[row][col] == current_player }
+ end
+ end
+
+ def draw?
+ board.flatten.compact.length == 9
+ end
- current_player = players.next
+ def valid_move?(row,col)
+ begin
+ cell_contents = board.fetch(row).fetch(col)
+ rescue IndexError
+ puts "Out of bounds, try another position"
+ return false
end
+
+ if cell_contents
+ puts "Cell occupied, try another position"
+ return false
+ end
+
+ true
end
+
+ def move_input
+ print "\n>> "
+ row, col = gets.split.map { |e| e.to_i }
+ puts
+
+ [row, col]
+ end
+
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.