ruby_ttt 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/board.rb +1 -0
- data/lib/game_setup.rb +29 -21
- data/lib/player.rb +0 -2
- data/lib/ruby_ttt.rb +20 -17
- data/lib/ui.rb +55 -4
- metadata +1 -1
data/lib/board.rb
CHANGED
data/lib/game_setup.rb
CHANGED
@@ -2,34 +2,51 @@ EASY_LEVEL = 'easy'
|
|
2
2
|
HARD_LEVEL = 'hard'
|
3
3
|
COMPUTER_PLAYER = 'computer'
|
4
4
|
HUMAN_PLAYER = 'human'
|
5
|
+
|
5
6
|
class GameSetup
|
6
7
|
attr_accessor :ui, :board, :player_one, :player_two
|
7
|
-
def initialize(
|
8
|
-
@board = board
|
9
|
-
@ui =
|
8
|
+
def initialize(ui, player_one, player_two)
|
9
|
+
@board = ui.board
|
10
|
+
@ui = ui
|
10
11
|
@player_one = player_one
|
11
12
|
@player_two = player_two
|
12
13
|
end
|
13
14
|
|
14
|
-
def
|
15
|
+
def set_opponents
|
16
|
+
player_one.opponent = player_two
|
17
|
+
player_two.opponent = player_one
|
18
|
+
end
|
19
|
+
|
20
|
+
def computer_player_selected?
|
21
|
+
(player_one.player_type == COMPUTER_PLAYER) || (player_two.player_type == COMPUTER_PLAYER)
|
22
|
+
end
|
23
|
+
|
24
|
+
def who_goes_first
|
25
|
+
rand(0..1) == 1 ? set_first_turn(player_one) : set_first_turn(player_two)
|
26
|
+
end
|
27
|
+
|
28
|
+
def set_first_turn(player)
|
29
|
+
player.turn = 1
|
30
|
+
ui.first_move_message(player)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class CLIGameSetup < GameSetup
|
35
|
+
|
36
|
+
def start_cli_game!
|
15
37
|
begin
|
16
38
|
set_opponents
|
17
39
|
get_player_type(player_one)
|
18
40
|
get_player_type(player_two)
|
19
41
|
level = get_difficulty_level
|
20
42
|
who_goes_first
|
21
|
-
Game.new(
|
43
|
+
Game.new(ui, player_one, player_two, level).play!
|
22
44
|
rescue Interrupt
|
23
45
|
ui.early_exit_message
|
24
46
|
exit
|
25
47
|
end
|
26
48
|
end
|
27
49
|
|
28
|
-
def set_opponents
|
29
|
-
player_one.opponent = player_two
|
30
|
-
player_two.opponent = player_one
|
31
|
-
end
|
32
|
-
|
33
50
|
def get_player_type(player)
|
34
51
|
type = ui.request_player_type(player.marker)
|
35
52
|
validate_type(type, player) ? set_player_type(type, player) : invalid_type(type, player)
|
@@ -41,10 +58,6 @@ class GameSetup
|
|
41
58
|
validate_level(level) ? ui.level_assigned_message(level) : invalid_level(level)
|
42
59
|
end
|
43
60
|
|
44
|
-
def computer_player_selected?
|
45
|
-
(player_one.player_type == COMPUTER_PLAYER) || (player_two.player_type == COMPUTER_PLAYER)
|
46
|
-
end
|
47
|
-
|
48
61
|
def validate_type(type, player)
|
49
62
|
(type == HUMAN_PLAYER) || (type == COMPUTER_PLAYER)
|
50
63
|
end
|
@@ -68,14 +81,9 @@ class GameSetup
|
|
68
81
|
get_difficulty_level
|
69
82
|
end
|
70
83
|
|
71
|
-
|
72
|
-
rand(0..1) == 1 ? set_first_turn(player_one) : set_first_turn(player_two)
|
73
|
-
end
|
84
|
+
end
|
74
85
|
|
75
|
-
|
76
|
-
player.turn = 1
|
77
|
-
ui.first_move_message(player)
|
78
|
-
end
|
86
|
+
class WebGameSetup < GameSetup
|
79
87
|
|
80
88
|
def set_player_types(player_one_type, player_two_type)
|
81
89
|
player_one.player_type = player_one_type
|
data/lib/player.rb
CHANGED
data/lib/ruby_ttt.rb
CHANGED
@@ -5,24 +5,15 @@ require 'ui'
|
|
5
5
|
require 'game_setup'
|
6
6
|
class Game
|
7
7
|
attr_accessor :board, :ui, :player_one, :player_two, :ai, :difficulty_level
|
8
|
-
def initialize(board, player_one, player_two, difficulty_level)
|
8
|
+
def initialize(board, ui, player_one, player_two, difficulty_level)
|
9
9
|
@board = board
|
10
|
-
@ui =
|
10
|
+
@ui = ui
|
11
11
|
@player_one = player_one
|
12
12
|
@player_two = player_two
|
13
13
|
@ai = AI.new
|
14
14
|
@difficulty_level = difficulty_level
|
15
15
|
end
|
16
16
|
|
17
|
-
def play!
|
18
|
-
until board.game_over?
|
19
|
-
ui.display_board
|
20
|
-
move = get_next_move
|
21
|
-
advance_game if verify_move(move)
|
22
|
-
end
|
23
|
-
exit_game
|
24
|
-
end
|
25
|
-
|
26
17
|
def verify_move(cell)
|
27
18
|
if board.available_cell?(cell)
|
28
19
|
board.add_marker(current_player.marker, cell)
|
@@ -32,8 +23,7 @@ class Game
|
|
32
23
|
end
|
33
24
|
end
|
34
25
|
|
35
|
-
def
|
36
|
-
return ui.request_human_move if !computer_move?
|
26
|
+
def get_computer_move
|
37
27
|
difficulty_level == HARD_LEVEL ? ai.computer_move(board, current_player) : board.random_cell
|
38
28
|
end
|
39
29
|
|
@@ -55,14 +45,27 @@ class Game
|
|
55
45
|
end
|
56
46
|
end
|
57
47
|
|
58
|
-
def invalid_move(cell)
|
59
|
-
board.valid_cell?(cell) ? ui.taken_cell_message(cell) : ui.bad_cell_message(cell)
|
60
|
-
end
|
61
|
-
|
62
48
|
def current_player
|
63
49
|
player_one.current_player? ? player_one : player_two
|
64
50
|
end
|
65
51
|
|
52
|
+
end
|
53
|
+
|
54
|
+
class CLIGame < Game
|
55
|
+
|
56
|
+
def play!
|
57
|
+
until board.game_over?
|
58
|
+
ui.display_board
|
59
|
+
move = computer_move? ? get_computer_move : ui.request_human_move
|
60
|
+
advance_game if verify_move(move)
|
61
|
+
end
|
62
|
+
exit_game
|
63
|
+
end
|
64
|
+
|
65
|
+
def invalid_move(cell)
|
66
|
+
board.valid_cell?(cell) ? ui.taken_cell_message(cell) : ui.bad_cell_message(cell)
|
67
|
+
end
|
68
|
+
|
66
69
|
def exit_game
|
67
70
|
ui.display_board
|
68
71
|
ui.io.exit
|
data/lib/ui.rb
CHANGED
@@ -1,7 +1,31 @@
|
|
1
1
|
class UI
|
2
|
-
attr_accessor :board
|
2
|
+
attr_accessor :board
|
3
3
|
def initialize(board)
|
4
4
|
@board = board
|
5
|
+
end
|
6
|
+
|
7
|
+
def first_move_message(player)
|
8
|
+
"Player '#{player.marker}' goes first."
|
9
|
+
end
|
10
|
+
|
11
|
+
def next_move_message(player)
|
12
|
+
"Player '#{player.marker}': Make your move."
|
13
|
+
end
|
14
|
+
|
15
|
+
def winning_game_message(player)
|
16
|
+
"GAME OVER! Player '#{player.marker}' wins!"
|
17
|
+
end
|
18
|
+
|
19
|
+
def tie_game_message
|
20
|
+
"GAME OVER! It's a tie!"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
class CLIUI < UI
|
26
|
+
attr_accessor :io
|
27
|
+
def initialize(board)
|
28
|
+
super
|
5
29
|
@io = Kernel
|
6
30
|
end
|
7
31
|
|
@@ -85,8 +109,9 @@ class UI
|
|
85
109
|
end
|
86
110
|
|
87
111
|
def first_move_message(player)
|
112
|
+
output = super
|
88
113
|
io.print "\n\n************ New Game ************\n"
|
89
|
-
io.print
|
114
|
+
io.print output + "\n"
|
90
115
|
end
|
91
116
|
|
92
117
|
def next_move_message(player)
|
@@ -94,11 +119,13 @@ class UI
|
|
94
119
|
end
|
95
120
|
|
96
121
|
def winning_game_message(player)
|
97
|
-
|
122
|
+
output = super
|
123
|
+
io.print output + "\n"
|
98
124
|
end
|
99
125
|
|
100
126
|
def tie_game_message
|
101
|
-
|
127
|
+
output = super
|
128
|
+
io.print output + "\n"
|
102
129
|
end
|
103
130
|
|
104
131
|
def taken_cell_message(cell)
|
@@ -115,4 +142,28 @@ class UI
|
|
115
142
|
io.print "Goodbye!\n\n"
|
116
143
|
end
|
117
144
|
|
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
|
+
|
118
169
|
end
|