Last active
August 29, 2015 14:23
-
-
Save oinak/d6421cacc89548df1e97 to your computer and use it in GitHub Desktop.
As a meditation on https://practicingruby.com/articles/meditations-on-bad-and-good-code-1 artice, here is my first attempt at refactoring
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module TicTacToe | |
class Game | |
def self.play | |
new.run | |
end | |
def players | |
@players ||= %w(X O).cycle | |
end | |
def board | |
@board ||= Board.new | |
end | |
def run | |
play_turn until board.finished?(@current_player) | |
end | |
def play_turn | |
advance_turn | |
make_move(read_move) | |
end | |
def advance_turn | |
@current_player = players.next | |
end | |
def make_move(move) | |
board.set(move.row, move.col, move.player) | |
end | |
def read_move | |
loop do | |
board.draw | |
move = Move.read(@current_player) | |
return move if valid? move | |
end | |
end | |
def valid?(move) | |
move.valid? && board.free?(move.row, move.col) | |
end | |
end | |
class Move < Struct.new(:row, :col, :player); | |
def valid? | |
row && col | |
end | |
def self.read(player) | |
row,col = gets.split.map(&:to_i) | |
new(row, col, player) | |
end | |
end | |
class Board | |
FREE = ' ' | |
def initialize | |
@rows ||= Array.new(3) { Array.new(3){ FREE } } | |
end | |
def set(row, col, player) | |
@rows[row][col] = player | |
end | |
def draw | |
puts "\n 0 1 2" | |
puts @rows.map.with_index{ |row, x| "#{x}:#{row * "|"}" } * "\n" | |
print "\nrow col >> " | |
end | |
def free?(row, col) | |
@rows.fetch(row).fetch(col) == FREE | |
rescue IndexError | |
puts 'Out of bounds' | |
false | |
end | |
def finished?(player) | |
full? || tic_tac_toe?(player) | |
end | |
def full? | |
@rows.flatten.none?{|c| c == FREE } | |
end | |
def tic_tac_toe?(player) | |
lines.any? {|line| line.all? { |cell| cell == player }} | |
end | |
def lines | |
rows + cols + diagonals | |
end | |
def rows | |
@rows | |
end | |
def cols | |
@rows.transpose | |
end | |
def diagonals | |
[ | |
(0..2).map{|d| @rows[d][d] }, | |
(0..2).map{|d| @rows[d][2-d] } | |
] | |
end | |
end | |
end | |
if __FILE__ == $PROGRAM_NAME | |
TicTacToe::Game.play | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This can also be used as a nice programing/refactoring exercise for interviews