Class: TTT::Game

Inherits:
Object
  • Object
show all
Defined in:
lib/ttt/game.rb

Constant Summary collapse

DEFAULT_BOARD =
'0'*9

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

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

Returns:

  • (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

Yields:

  • (0, 1, 2)


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_movesObject



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

Returns:

  • (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

Returns:

  • (Boolean)


36
37
38
# File 'lib/ttt/game.rb', line 36

def tie?
  over? && !winner
end

#turnObject



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

#winnerObject



40
41
42
43
# File 'lib/ttt/game.rb', line 40

def winner
  return if winning_positions.empty?
  self[winning_positions.first]
end

#winning_positionsObject



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