Class: TTT::Game
- Inherits:
-
Object
- Object
- TTT::Game
- Defined in:
- lib/ttt/game.rb
Constant Summary collapse
- DEFAULT_BOARD =
'0'*9
Instance Attribute Summary collapse
Class Method Summary collapse
- .congruent?(board1, board2) ⇒ Boolean
- .each_congruent(board) ⇒ Object
- .each_rotation(board) ⇒ Object
- .reflect_board(board) ⇒ Object
- .rotate_board(board) ⇒ Object
- .winning_states {|0, 1, 2| ... } ⇒ Object
Instance Method Summary collapse
- #[](position) ⇒ Object
- #available_moves ⇒ Object
-
#initialize(board = DEFAULT_BOARD) ⇒ Game
constructor
A new instance of Game.
- #mark(position) ⇒ Object
- #over? ⇒ Boolean
- #pristine_mark(position) ⇒ Object
- #status(player_number) ⇒ Object
- #tie? ⇒ Boolean
- #turn ⇒ Object
- #winner ⇒ Object
- #winning_positions ⇒ Object
- #winning_states(&block) ⇒ Object
Constructor Details
#initialize(board = DEFAULT_BOARD) ⇒ Game
Returns a new instance of Game.
7 8 9 |
# File 'lib/ttt/game.rb', line 7 def initialize(board=DEFAULT_BOARD) self.board = board.dup end |
Instance Attribute Details
#board(style = nil) ⇒ Object
20 21 22 23 |
# File 'lib/ttt/game.rb', line 20 def board(style=nil) return @board unless style " %s | %s | %s \n----|---|----\n %s | %s | %s \n----|---|----\n %s | %s | %s " % @board.gsub('0', ' ').split('') end |
Class Method Details
.congruent?(board1, board2) ⇒ Boolean
86 87 88 |
# File 'lib/ttt/game.rb', line 86 def congruent?(board1, board2) each_congruent(board2).any? { |congruent| board1 == congruent } end |
.each_congruent(board) ⇒ Object
90 91 92 93 94 |
# File 'lib/ttt/game.rb', line 90 def each_congruent(board) return to_enum(:each_congruent, board) unless block_given? each_rotation(board) { |congruent| yield congruent } each_rotation(reflect_board board) { |congruent| yield congruent } end |
.each_rotation(board) ⇒ Object
102 103 104 105 106 107 108 109 |
# File 'lib/ttt/game.rb', line 102 def each_rotation(board) return to_enum(:each_rotation, board) unless block_given? board = board.dup 4.times do yield board.dup board = rotate_board(board) end end |
.reflect_board(board) ⇒ Object
96 97 98 99 100 |
# File 'lib/ttt/game.rb', line 96 def reflect_board(board) board = board.dup board[0..2], board[6..8] = board[6..8], board[0..2] board end |
.rotate_board(board) ⇒ Object
111 112 113 114 115 116 |
# File 'lib/ttt/game.rb', line 111 def rotate_board(board) board = board.dup board[0], board[1], board[2], board[3], board[5], board[6], board[7], board[8] = board[6], board[3], board[0], board[7], board[1], board[8], board[5], board[2] board end |
.winning_states {|0, 1, 2| ... } ⇒ Object
118 119 120 121 122 123 124 125 126 127 |
# File 'lib/ttt/game.rb', line 118 def winning_states yield 0, 1, 2 yield 3, 4, 5 yield 6, 7, 8 yield 0, 3, 6 yield 1, 4, 7 yield 2, 5, 8 yield 0, 4, 8 yield 2, 4, 6 end |
Instance Method Details
#[](position) ⇒ Object
74 75 76 77 |
# File 'lib/ttt/game.rb', line 74 def [](position) player = board[position-1, 1].to_i return player if player == 1 || player == 2 end |
#available_moves ⇒ Object
45 46 47 48 49 50 51 52 |
# File 'lib/ttt/game.rb', line 45 def available_moves return [] if over? to_return = [] board.split(//).each_with_index do |char, index| to_return << index.next if char != '1' && char != '2' end to_return end |
#mark(position) ⇒ Object
16 17 18 |
# File 'lib/ttt/game.rb', line 16 def mark(position) board[position-1] = turn.to_s end |
#over? ⇒ Boolean
25 26 27 |
# File 'lib/ttt/game.rb', line 25 def over? winner || board.split(//).all? { |char| char == '1' || char == '2' } end |
#pristine_mark(position) ⇒ Object
54 55 56 57 58 |
# File 'lib/ttt/game.rb', line 54 def pristine_mark(position) marked = self.class.new board.dup marked.mark position marked end |
#status(player_number) ⇒ Object
29 30 31 32 33 34 |
# File 'lib/ttt/game.rb', line 29 def status(player_number) return nil unless over? (winner == player_number) ? :wins : winner ? :loses : :ties end |
#tie? ⇒ Boolean
36 37 38 |
# File 'lib/ttt/game.rb', line 36 def tie? over? && !winner end |
#turn ⇒ Object
11 12 13 14 |
# File 'lib/ttt/game.rb', line 11 def turn return if over? board.scan('1').size - board.scan('2').size + 1 end |
#winner ⇒ Object
40 41 42 43 |
# File 'lib/ttt/game.rb', line 40 def winner return if winning_positions.empty? self[winning_positions.first] end |
#winning_positions ⇒ Object
64 65 66 67 68 69 70 71 72 |
# File 'lib/ttt/game.rb', line 64 def winning_positions winning_states do |pos1, pos2, pos3| next unless board[pos1, 1] == board[pos2, 1] next unless board[pos1, 1] == board[pos3, 1] next unless board[pos1, 1] =~ /^(1|2)$/ return [pos1+1, pos2+1, pos3+1] end [] end |
#winning_states(&block) ⇒ Object
60 61 62 |
# File 'lib/ttt/game.rb', line 60 def winning_states(&block) self.class.winning_states(&block) end |