ruby_ttt 0.1.5 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
data/lib/ai.rb CHANGED
@@ -5,6 +5,10 @@ LOSE = -1
5
5
  TIE = 0
6
6
 
7
7
  class AI
8
+ attr_reader :current_player
9
+ def initialize(player)
10
+ @current_player = player
11
+ end
8
12
 
9
13
  def computer_move(board, player)
10
14
  test_board = board.dup
@@ -28,39 +32,39 @@ class AI
28
32
  end
29
33
 
30
34
  def get_move_score(board, player, cell)
31
- board.add_marker(player.marker, cell)
35
+ player.add_marker(board, cell)
32
36
  best_score = apply_minimax(board, player, cell, depth=0, NEG_INF, POS_INF)
33
37
  board.remove_marker(cell)
34
38
  best_score
35
39
  end
36
40
 
37
41
  def get_score(board, player)
38
- return WIN if board.winner?(player.marker) && player.current_player?
42
+ return WIN if board.winner?(player.marker) && (player == current_player)
39
43
  return LOSE if board.winner?(player.marker)
40
44
  TIE
41
45
  end
42
46
 
43
47
  def apply_minimax(board, player, cell, depth, alpha, beta)
44
48
  return get_score(board, player) if board.game_over?
45
- if player.current_player?
46
- maximizing_player = Maximizing.new(player)
49
+ if (player == current_player)
50
+ maximizing_player = MaximizingPlayer.new(player)
47
51
  alphabeta(board, maximizing_player, depth, alpha, beta)
48
52
  else
49
- minimizing_player = Minimizing.new(player)
53
+ minimizing_player = MinimizingPlayer.new(player)
50
54
  alphabeta(board, minimizing_player, depth, alpha, beta)
51
55
  end
52
56
  end
53
57
 
54
58
  def alphabeta(board, player, depth, alpha, beta)
55
59
  board.open_cells.each_key do |cell|
56
- board.add_marker(player.opponent.marker, cell)
60
+ player.opponent.add_marker(board, cell)
57
61
  score = (apply_minimax(board, player.opponent, cell, depth += 1, alpha, beta) / depth.to_f)
58
62
  alpha = player.get_alpha(alpha, score)
59
63
  beta = player.get_beta(beta, score)
60
64
  board.remove_marker(cell)
61
65
  break if alpha >= beta
62
66
  end
63
- player.return_value(alpha, beta)
67
+ player.return_best_score(alpha, beta)
64
68
  end
65
69
 
66
70
  end
@@ -46,22 +46,10 @@ class Board
46
46
  rows
47
47
  end
48
48
 
49
- def add_marker(marker, cell)
49
+ def add_test_marker(marker, cell)
50
50
  all_cells[cell] = marker
51
51
  end
52
52
 
53
- def winner?(marker)
54
- board_markers = all_cells.select { |k,v| v == marker }.keys
55
- winning_lines.each do |line|
56
- return true if (line & board_markers).length == num_of_rows
57
- end
58
- false
59
- end
60
-
61
- def game_over?
62
- !moves_remaining? || winner?(MARKER_X)|| winner?(MARKER_O)
63
- end
64
-
65
53
  def available_cell?(cell)
66
54
  valid_cell?(cell) && all_cells[cell].nil?
67
55
  end
@@ -78,6 +66,18 @@ class Board
78
66
  all_cells.has_value?(nil)
79
67
  end
80
68
 
69
+ def winner?(marker)
70
+ board_markers = all_cells.select { |cell, value| value == marker }.keys
71
+ winning_lines.each do |line|
72
+ return true if (line & board_markers).length == num_of_rows
73
+ end
74
+ false
75
+ end
76
+
77
+ def game_over?
78
+ !moves_remaining? || winner?(MARKER_X) || winner?(MARKER_O)
79
+ end
80
+
81
81
  def open_cells
82
82
  all_cells.select { |k,v| v.nil? }
83
83
  end
@@ -143,4 +143,78 @@ class Board
143
143
  diagonal
144
144
  end
145
145
 
146
+ end
147
+
148
+ class CLIBoard < Board
149
+ attr_accessor :all_cells, :num_of_rows, :winning_lines, :io
150
+ def initialize(num_of_rows)
151
+ super
152
+ @io = Kernel
153
+ end
154
+
155
+ def print_board_numbers
156
+ num = 1
157
+ io.print " "
158
+ num_of_rows.times do
159
+ io.print "--#{num}-- "
160
+ num += 1
161
+ end
162
+ io.print "\n"
163
+ end
164
+
165
+ def print_divider
166
+ io.print " "
167
+ num_of_rows.times { io.print "------" }
168
+ io.print "\n"
169
+ end
170
+
171
+ def print_board_rows
172
+ alpha = 'A'
173
+ all_rows.each do |row|
174
+ show_row(alpha, row)
175
+ alpha = alpha.next
176
+ end
177
+ end
178
+
179
+ def show_row(letter, cells)
180
+ io.print "#{letter}"
181
+ cells.each { |cell| io.print " | " + show_marker(cell) }
182
+ io.print " | #{letter}\n"
183
+ print_divider
184
+ end
185
+
186
+ def show_marker(cell)
187
+ all_cells[cell].nil? ? ' ' : all_cells[cell]
188
+ end
189
+
190
+ def display_board
191
+ print_board_numbers
192
+ print_board_rows
193
+ print_board_numbers
194
+ end
195
+
196
+ end
197
+
198
+ class WebBoard < Board
199
+
200
+ def print_active_board
201
+ board_string = ''
202
+ all_rows.each do |row|
203
+ board_string += "<div class='row'>"
204
+ row.each { |cell| board_string += "<button name='move' value='#{cell}'> #{all_cells[cell]} <span class='cell'>.</span></button>" }
205
+ board_string += "</div>"
206
+ end
207
+ board_string
208
+ end
209
+
210
+ def print_inactive_board
211
+ board_string = ''
212
+ all_rows.each do |row|
213
+ board_string += "<div class='row'>"
214
+ row.each { |cell| board_string += "<button> #{all_cells[cell]} <span class='cell'>.</span></button>" }
215
+ board_string += "</div>"
216
+ end
217
+ board_string
218
+ end
219
+
146
220
  end
@@ -0,0 +1,111 @@
1
+ COMPUTER_PLAYER = 'computer'
2
+ HUMAN_PLAYER = 'human'
3
+ AI_PLAYER = 'hard computer'
4
+ HARD_LEVEL = 'hard'
5
+ EASY_LEVEL = 'easy'
6
+
7
+ class GameSetup; end
8
+
9
+ class CLIGameSetup < GameSetup
10
+ attr_accessor :ui
11
+ def initialize
12
+ @ui = CLIUI.new
13
+ end
14
+
15
+ def get_settings
16
+ settings = {}
17
+ begin
18
+ players = set_up_players
19
+ settings[:board] = get_board
20
+ settings[:player_one] = players.player_one
21
+ settings[:player_two] = players.player_two
22
+ settings[:player_first_move] = players.player_goes_first
23
+ settings
24
+ rescue Interrupt
25
+ ui.early_exit_message
26
+ exit
27
+ end
28
+ end
29
+
30
+ def set_up_players
31
+ player_one_type = get_player_type(MARKER_X)
32
+ player_two_type = get_player_type(MARKER_O)
33
+ PlayerFactory.new(player_one_type, player_two_type)
34
+ end
35
+
36
+ def get_player_type(marker)
37
+ type = ui.request_player_type(marker)
38
+ validated_type = valid_type?(type) ? get_difficulty_level(type) : invalid_type(type, marker)
39
+ ui.type_assigned_message(validated_type, marker)
40
+ validated_type
41
+ end
42
+
43
+ def get_difficulty_level(type)
44
+ return type if type == HUMAN_PLAYER
45
+ level = ui.request_difficulty_level
46
+ valid_level?(level) ? ui.level_assigned_message(level) : invalid_level(level)
47
+ player_type_by_level(level)
48
+ end
49
+
50
+ def valid_type?(type)
51
+ (type == HUMAN_PLAYER) || (type == COMPUTER_PLAYER)
52
+ end
53
+
54
+ def invalid_type(type, marker)
55
+ ui.invalid_input_message(type)
56
+ get_player_type(marker)
57
+ end
58
+
59
+ def valid_level?(level)
60
+ (level == HARD_LEVEL) || (level == EASY_LEVEL)
61
+ end
62
+
63
+ def invalid_level(level)
64
+ ui.invalid_input_message(level)
65
+ get_difficulty_level(COMPUTER_PLAYER)
66
+ end
67
+
68
+ def player_type_by_level(level)
69
+ level == HARD_LEVEL ? AI_PLAYER : COMPUTER_PLAYER
70
+ end
71
+
72
+ def get_board
73
+ rows = ui.request_board_size
74
+ valid_board_size?(rows) ? ui.board_assigned_message(rows) : invalid_board_size(rows)
75
+ CLIBoard.new(rows.to_i)
76
+ end
77
+
78
+ def valid_board_size?(input)
79
+ rows = input.to_i
80
+ rows.is_a?(Integer) && (rows > 2 && rows < 6)
81
+ end
82
+
83
+ def invalid_board_size(rows)
84
+ ui.invalid_input_message(rows)
85
+ get_board
86
+ end
87
+
88
+ end
89
+
90
+ class WebGameSetup < GameSetup
91
+
92
+ # def set_up_players(player_one_type, player_two_type)
93
+ # PlayerFactory.new(player_one_type, player_two_type)
94
+ # end
95
+
96
+ # def get_board
97
+ # board = Board.new(session[:board_size])
98
+ # board.all_cells = session[:current_board]
99
+ # end
100
+
101
+ # def get_settings
102
+ # settings = {}
103
+ # players = set_up_players
104
+ # settings[:board] = get_board
105
+ # settings[:player_one] = players.player_one
106
+ # settings[:player_two] = players.player_two
107
+ # settings[:player_goes_first] = players.player_goes_first
108
+ # settings
109
+ # end
110
+
111
+ end
@@ -1,19 +1,12 @@
1
1
  class Player
2
- attr_accessor :marker, :turn, :player_type, :opponent
2
+ attr_accessor :marker, :opponent
3
3
  def initialize(marker)
4
- @marker = marker
5
- @player_type = 'human'
6
- @turn = 0
7
- @opponent = nil
4
+ @marker = marker
5
+ @opponent = nil
8
6
  end
9
7
 
10
- def next_player_turn
11
- self.turn = 0
12
- self.opponent.turn = 1
13
- end
14
-
15
- def current_player?
16
- self.turn == 1
8
+ def add_marker(board, cell)
9
+ board.all_cells[cell] = self.marker
17
10
  end
18
11
 
19
12
  def get_alpha(alpha, score)
@@ -25,36 +18,55 @@ class Player
25
18
  end
26
19
  end
27
20
 
28
- class Minimizing < Player
29
- attr_accessor :marker, :turn, :opponent
21
+ class AIPlayer < Player
22
+
23
+ def make_move(board)
24
+ ai = AI.new(self)
25
+ cell = ai.computer_move(board, self)
26
+ add_marker(board, cell)
27
+ end
28
+
29
+ end
30
+
31
+ class ComputerPlayer < Player
32
+
33
+ def make_move(board)
34
+ cell = board.random_cell
35
+ add_marker(board, cell)
36
+ end
37
+
38
+ end
39
+
40
+ class HumanPlayer < Player; end
41
+
42
+ class MinimizingPlayer < Player
43
+ attr_accessor :marker, :opponent
30
44
  def initialize(player)
31
- @marker = player.marker
32
- @turn = player.turn
33
- @opponent = player.opponent
45
+ @marker = player.marker
46
+ @opponent = player.opponent
34
47
  end
35
48
 
36
49
  def get_alpha(alpha, score)
37
50
  score > alpha ? score : alpha
38
51
  end
39
52
 
40
- def return_value(alpha, beta)
53
+ def return_best_score(alpha, beta)
41
54
  alpha
42
55
  end
43
56
  end
44
57
 
45
- class Maximizing < Player
46
- attr_accessor :marker, :turn, :opponent
58
+ class MaximizingPlayer < Player
59
+ attr_accessor :marker, :opponent
47
60
  def initialize(player)
48
- @marker = player.marker
49
- @turn = player.turn
50
- @opponent = player.opponent
61
+ @marker = player.marker
62
+ @opponent = player.opponent
51
63
  end
52
64
 
53
65
  def get_beta(beta, score)
54
66
  score < beta ? score : beta
55
67
  end
56
68
 
57
- def return_value(alpha, beta)
69
+ def return_best_score(alpha, beta)
58
70
  beta
59
71
  end
60
72
  end
@@ -0,0 +1,31 @@
1
+ class PlayerFactory
2
+ attr_accessor :player_one, :player_two
3
+ def initialize(type_one, type_two)
4
+ @player_one = create_player(type_one, MARKER_X)
5
+ @player_two = create_player(type_two, MARKER_O)
6
+ set_opponents
7
+ end
8
+
9
+ def create_player(type, marker)
10
+ case type
11
+ when COMPUTER_PLAYER
12
+ ComputerPlayer.new(marker)
13
+ when HUMAN_PLAYER
14
+ HumanPlayer.new(marker)
15
+ when AI_PLAYER
16
+ AIPlayer.new(marker)
17
+ else
18
+ raise "Invalid player type"
19
+ end
20
+ end
21
+
22
+ def player_goes_first
23
+ rand(0..1) == 1 ? player_one : player_two
24
+ end
25
+
26
+ def set_opponents
27
+ player_one.opponent = player_two
28
+ player_two.opponent = player_one
29
+ end
30
+
31
+ end
@@ -1,92 +1,64 @@
1
1
  require 'ai'
2
2
  require 'board'
3
+ require 'player_factory'
4
+ require 'game_setup'
3
5
  require 'player'
4
6
  require 'ui'
5
7
 
6
- EASY_LEVEL = 'easy'
7
- HARD_LEVEL = 'hard'
8
- COMPUTER_PLAYER = 'computer'
9
- HUMAN_PLAYER = 'human'
10
-
11
8
  class Game
12
- attr_accessor :board, :player_one, :player_two, :ai, :difficulty_level
13
- def initialize(board, player_one, player_two)
14
- @board = board
15
- @player_one = player_one
16
- @player_two = player_two
17
- @ai = AI.new
18
- @difficulty_level = nil
19
- end
20
-
21
- def set_opponents
22
- player_one.opponent = player_two
23
- player_two.opponent = player_one
9
+ attr_accessor :board, :player_one, :player_two, :ui, :player_first_move
10
+ def initialize(settings)
11
+ @board = settings[:board]
12
+ @player_one = settings[:player_one]
13
+ @player_two = settings[:player_two]
14
+ @player_first_move = settings[:player_first_move]
15
+ @ui = UI.new
24
16
  end
25
17
 
26
- def computer_player_selected?
27
- (player_one.player_type == COMPUTER_PLAYER) || (player_two.player_type == COMPUTER_PLAYER)
18
+ def advance_game
19
+ game_status_check(current_player.opponent.marker)
20
+ ui.next_move_message(current_player.marker) unless board.game_over?
28
21
  end
29
22
 
30
- def who_goes_first
31
- rand(0..1) == 1 ? set_first_turn(player_one) : set_first_turn(player_two)
23
+ def game_status_check(marker)
24
+ if board.winner?(marker)
25
+ ui.winning_game_message(marker)
26
+ elsif !board.moves_remaining?
27
+ ui.tie_game_message
28
+ end
32
29
  end
33
30
 
34
- def set_first_turn(player)
35
- player.turn = 1
36
- ui.first_move_message(player)
31
+ def verify_move(cell)
32
+ return false if !board.available_cell?(cell)
33
+ current_player.add_marker(board, cell)
34
+ true
37
35
  end
38
36
 
39
- def verify_move(cell)
40
- if board.available_cell?(cell)
41
- board.add_marker(current_player.marker, cell)
42
- true
37
+ def current_player
38
+ if total_markers(MARKER_X) > total_markers(MARKER_O)
39
+ player_two
40
+ elsif total_markers(MARKER_O) > total_markers(MARKER_X)
41
+ player_one
43
42
  else
44
- invalid_move(cell)
43
+ player_first_move
45
44
  end
46
45
  end
47
46
 
48
- def get_computer_move
49
- difficulty_level == HARD_LEVEL ? ai.computer_move(board, current_player) : board.random_cell
50
- end
51
-
52
- def computer_move?
53
- current_player.player_type == COMPUTER_PLAYER
47
+ def total_markers(marker)
48
+ board.all_cells.select { |cell, value| value == marker }.count
54
49
  end
55
50
 
56
- def advance_game
57
- game_status_check
58
- current_player.next_player_turn
59
- ui.next_move_message(current_player) unless board.game_over?
60
- end
61
-
62
- def game_status_check
63
- if board.winner?(current_player.marker)
64
- ui.winning_game_message(current_player)
65
- elsif !board.moves_remaining?
66
- ui.tie_game_message
67
- end
68
- end
69
-
70
- def current_player
71
- player_one.current_player? ? player_one : player_two
72
- end
73
51
  end
74
52
 
75
53
  class CLIGame < Game
76
- attr_accessor :ui
77
-
78
- def initialize(board, player_one, player_two)
54
+ attr_accessor :board, :player_one, :player_two, :ui, :player_first_move
55
+ def initialize(settings)
79
56
  super
80
- @ui = CLIUI.new(board)
57
+ @ui = CLIUI.new
81
58
  end
82
59
 
83
- def start_cli_game!
60
+ def start_game!
84
61
  begin
85
- set_opponents
86
- get_player_type(player_one)
87
- get_player_type(player_two)
88
- level = get_difficulty_level
89
- who_goes_first
90
62
  play!
91
63
  rescue Interrupt
92
64
  ui.early_exit_message
@@ -94,71 +66,33 @@ class CLIGame < Game
94
66
  end
95
67
  end
96
68
 
97
- def get_player_type(player)
98
- type = ui.request_player_type(player.marker)
99
- validate_type(type, player) ? set_player_type(type, player) : invalid_type(type, player)
100
- end
101
-
102
- def get_difficulty_level
103
- return nil unless computer_player_selected?
104
- level = ui.request_difficulty_level
105
- validate_level(level) ? ui.level_assigned_message(level) : invalid_level(level)
106
- end
107
-
108
- def validate_type(type, player)
109
- (type == HUMAN_PLAYER) || (type == COMPUTER_PLAYER)
110
- end
111
-
112
- def set_player_type(type, player)
113
- player.player_type = type
114
- ui.type_assigned_message(type, player.marker)
115
- end
116
-
117
- def invalid_type(type, player)
118
- ui.invalid_input_message(type)
119
- get_player_type(player)
120
- end
121
-
122
- def validate_level(level)
123
- (level == HARD_LEVEL) || (level == EASY_LEVEL)
124
- end
125
-
126
- def invalid_level(level)
127
- ui.invalid_input_message(level)
128
- get_difficulty_level
129
- end
130
-
131
69
  def play!
132
70
  until board.game_over?
133
- ui.display_board
134
- move = computer_move? ? get_computer_move : ui.request_human_move
135
- advance_game if verify_move(move)
71
+ board.display_board
72
+ get_next_move
136
73
  end
137
74
  exit_game
138
75
  end
139
76
 
77
+ def get_next_move
78
+ if current_player.is_a?(HumanPlayer)
79
+ move = ui.request_human_move
80
+ verify_move(move) ? advance_game : invalid_move(move)
81
+ else
82
+ current_player.make_move(board)
83
+ advance_game
84
+ end
85
+ end
86
+
140
87
  def invalid_move(cell)
141
88
  board.valid_cell?(cell) ? ui.taken_cell_message(cell) : ui.bad_cell_message(cell)
142
89
  end
143
90
 
144
91
  def exit_game
145
- ui.display_board
92
+ board.display_board
146
93
  ui.io.exit
147
94
  end
148
95
 
149
96
  end
150
97
 
151
- class WebGame < Game
152
- attr_accessor :ui
153
-
154
- def initialize(board, player_one, player_two)
155
- super
156
- @ui = WebUI.new(board)
157
- end
158
-
159
- def set_player_types(player_one_type, player_two_type)
160
- player_one.player_type = player_one_type
161
- player_two.player_type = player_two_type
162
- end
163
-
164
- end
98
+ class WebGame < Game; end
data/lib/ui.rb CHANGED
@@ -1,19 +1,16 @@
1
1
  class UI
2
- attr_accessor :board
3
- def initialize(board)
4
- @board = board
5
- end
2
+ def initialize; end
6
3
 
7
- def first_move_message(player)
8
- "Player '#{player.marker}' goes first."
4
+ def first_move_message(marker)
5
+ "Player '#{marker}' goes first."
9
6
  end
10
7
 
11
- def next_move_message(player)
12
- "Player '#{player.marker}': Make your move."
8
+ def next_move_message(marker)
9
+ "Player '#{marker}': Make your move."
13
10
  end
14
11
 
15
- def winning_game_message(player)
16
- "GAME OVER! Player '#{player.marker}' wins!"
12
+ def winning_game_message(marker)
13
+ "GAME OVER! Player '#{marker}' wins!"
17
14
  end
18
15
 
19
16
  def tie_game_message
@@ -24,8 +21,7 @@ end
24
21
 
25
22
  class CLIUI < UI
26
23
  attr_accessor :io
27
- def initialize(board)
28
- super
24
+ def initialize
29
25
  @io = Kernel
30
26
  end
31
27
 
@@ -39,6 +35,11 @@ class CLIUI < UI
39
35
  io.gets.chomp.downcase
40
36
  end
41
37
 
38
+ def request_board_size
39
+ board_size_message
40
+ io.gets.chomp.downcase
41
+ end
42
+
42
43
  def request_human_move
43
44
  standardize(io.gets.chomp)
44
45
  end
@@ -51,12 +52,20 @@ class CLIUI < UI
51
52
  io.print "Select computer difficulty level: Enter 'easy' or 'hard.'\n"
52
53
  end
53
54
 
55
+ def board_size_message
56
+ io.print "Enter the number of rows you want your board to have (3-5).\n"
57
+ end
58
+
54
59
  def level_assigned_message(level)
55
60
  io.print "You selected difficulty level #{level.upcase}.\n"
56
61
  end
57
62
 
63
+ def board_assigned_message(rows)
64
+ io.print "You selected a board with #{rows} rows.\n"
65
+ end
66
+
58
67
  def invalid_input_message(input)
59
- io.print " #{input} is not a valid option.\n"
68
+ io.print "#{input} is not a valid option.\n"
60
69
  end
61
70
 
62
71
  def player_type_message(marker)
@@ -67,58 +76,17 @@ class CLIUI < UI
67
76
  io.print "Player " + "'#{marker}' " + "is #{type}.\n"
68
77
  end
69
78
 
70
- def print_board_numbers
71
- num = 1
72
- io.print " "
73
- board.num_of_rows.times do
74
- io.print "--#{num}-- "
75
- num += 1
76
- end
77
- io.print "\n"
78
- end
79
-
80
- def print_divider
81
- io.print " "
82
- board.num_of_rows.times { io.print "------" }
83
- io.print "\n"
84
- end
85
-
86
- def print_board_rows
87
- alpha = 'A'
88
- board.all_rows.each do |row|
89
- show_row(alpha, row)
90
- alpha = alpha.next
91
- end
92
- end
93
-
94
- def show_row(letter, cells)
95
- io.print "#{letter}"
96
- cells.each { |cell| io.print " | " + show_marker(cell) }
97
- io.print " | #{letter}\n"
98
- print_divider
99
- end
100
-
101
- def show_marker(cell)
102
- board.all_cells[cell].nil? ? ' ' : board.all_cells[cell]
103
- end
104
-
105
- def display_board
106
- print_board_numbers
107
- print_board_rows
108
- print_board_numbers
109
- end
110
-
111
- def first_move_message(player)
79
+ def first_move_message(marker)
112
80
  output = super
113
81
  io.print "\n\n************ New Game ************\n"
114
82
  io.print output + "\n"
115
83
  end
116
84
 
117
- def next_move_message(player)
118
- io.print "Player '#{player.marker}': Enter open cell ID.\n"
85
+ def next_move_message(marker)
86
+ io.print "Player '#{marker}': Enter open cell ID.\n"
119
87
  end
120
88
 
121
- def winning_game_message(player)
89
+ def winning_game_message(marker)
122
90
  output = super
123
91
  io.print output + "\n"
124
92
  end
@@ -142,28 +110,4 @@ class CLIUI < UI
142
110
  io.print "Goodbye!\n\n"
143
111
  end
144
112
 
145
- end
146
-
147
- class WebUI < UI
148
-
149
- def print_active_board
150
- board_string = ''
151
- board.all_rows.each do |row|
152
- board_string += "<div class='row'>"
153
- row.each { |cell| board_string += "<button name='move' value='#{cell}'> #{board.all_cells[cell]} <span class='cell'>.</span></button>" }
154
- board_string += "</div>"
155
- end
156
- board_string
157
- end
158
-
159
- def print_inactive_board
160
- board_string = ''
161
- board.all_rows.each do |row|
162
- board_string += "<div class='row'>"
163
- row.each { |cell| board_string += "<button> #{board.all_cells[cell]} <span class='cell'>.</span></button>" }
164
- board_string += "</div>"
165
- end
166
- board_string
167
- end
168
-
169
113
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_ttt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.9
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-12-17 00:00:00.000000000 Z
12
+ date: 2013-12-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -37,7 +37,9 @@ extra_rdoc_files: []
37
37
  files:
38
38
  - lib/ai.rb
39
39
  - lib/board.rb
40
+ - lib/game_setup.rb
40
41
  - lib/player.rb
42
+ - lib/player_factory.rb
41
43
  - lib/ruby_ttt.rb
42
44
  - lib/ui.rb
43
45
  homepage: http://rubygems.org/gems/ruby_ttt