ruby_ttt 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|