connect_four_ab_akh 1.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6b387897fe28e78c797bf4fd362b16c37f71fb8ee2f685d3b43b443a34059c86
4
+ data.tar.gz: b8cefe8b70ee775018c0a0b3250bef78dea52f2a620876701cec1b0a606f348c
5
+ SHA512:
6
+ metadata.gz: e4ea54a6790bf8be65340b7b003eede9f9b20b73e1632643531aa325df4f1b318a110af2ee69de795335a264ed8603c8bf908fb96b1f0d29cb53a3ceb46dc4b6
7
+ data.tar.gz: e9c4e766cf57c0f83afca95a4b9905ee5689eda735c979267c23817413bcf57dcb66e5aab035f64b1e39f60b7950056db2efaf4b266b252cd33ddd620736fa39
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require './lib/board'
4
+ require './lib/turn'
5
+ require './lib/game'
6
+ require './lib/player'
7
+
8
+ input = ""
9
+
10
+ until input == 'q'
11
+ puts
12
+ puts " ---------------------------------------------------"
13
+ puts "| Enter 'p' to play OR Enter 'q' to quit |"
14
+ puts " ---------------------------------------------------"
15
+ input = gets.chomp
16
+
17
+ if input == 'q'
18
+ break
19
+ elsif input == 'p'
20
+ game = Game.new
21
+
22
+ puts
23
+ puts game.welcome_user
24
+ puts "----------------------------------------------------"
25
+ puts game.start
26
+ puts
27
+
28
+ input = ""
29
+ else
30
+ "Invalid input"
31
+ end
32
+ end
data/lib/board.rb ADDED
@@ -0,0 +1,33 @@
1
+ class Board
2
+ attr_reader :layout
3
+
4
+ def initialize
5
+ @layout = build_board
6
+ end
7
+
8
+ def build_board
9
+ new_board = {}
10
+ col = ["A", "B", "C", "D", "E", "F", "G"]
11
+
12
+ #Creates 7 columns
13
+ 7.times do |i|
14
+
15
+ #Creates 6 rows
16
+ 6.times do |j|
17
+ #Determine row
18
+ row = j + 1
19
+
20
+ #Creates the key symbol for new_board hash
21
+ key = col[i] + row.to_s
22
+
23
+ #Putting key => value pair into new_board hash
24
+ new_board[key.to_sym] = {
25
+ column: i+1,
26
+ row: row,
27
+ checker: nil
28
+ }
29
+ end
30
+ end
31
+ new_board
32
+ end
33
+ end
@@ -0,0 +1,30 @@
1
+ require './lib/board'
2
+ require './lib/turn'
3
+ require './lib/game'
4
+ require './lib/player'
5
+
6
+ input = ""
7
+
8
+ until input == 'q'
9
+ puts
10
+ puts " ---------------------------------------------------"
11
+ puts "| Enter 'p' to play OR Enter 'q' to quit |"
12
+ puts " ---------------------------------------------------"
13
+ input = gets.chomp
14
+
15
+ if input == 'q'
16
+ break
17
+ elsif input == 'p'
18
+ game = Game.new
19
+
20
+ puts
21
+ puts game.welcome_user
22
+ puts "----------------------------------------------------"
23
+ puts game.start
24
+ puts
25
+
26
+ input = ""
27
+ else
28
+ "Invalid input"
29
+ end
30
+ end
data/lib/game.rb ADDED
@@ -0,0 +1,114 @@
1
+ class Game
2
+ attr_reader :board,
3
+ :player,
4
+ :computer
5
+
6
+ def initialize
7
+ @board = Board.new
8
+ @player1 = Player.new("Player", "X")
9
+ @player2 = Player.new("Computer", "O")
10
+ end
11
+
12
+ def welcome_user
13
+ " Welcome to CONNECT FOUR"
14
+ end
15
+
16
+ def print_board
17
+ # Create board string accumulator
18
+ board_string = " A B C D E F G\n"
19
+ counter = 6
20
+
21
+ # Add each board cell's checker value to string in reverse row order, starting at 6
22
+ 6.times do
23
+
24
+ # Create a hash of each key:value pair of the row corresponding to the counter
25
+ row_string = @board.layout.select do |cell|
26
+ @board.layout[cell][:row] == counter
27
+ end
28
+
29
+ # Add each checker piece or '.' to the string accumulator
30
+ row_string.each do |cell|
31
+ if cell[1][:checker] != nil
32
+ board_string << " #{cell[1][:checker]} "
33
+ else
34
+ board_string << " . "
35
+ end
36
+ end
37
+
38
+ # Add line break to end of string accumulator
39
+ board_string << "\n"
40
+
41
+ counter -= 1
42
+ end
43
+ board_string
44
+ end
45
+
46
+ def start
47
+ # Get total number of user players and request names
48
+ if get_number_of_players == "1"
49
+ puts "Player 1: Enter your name"
50
+ @player1.change_name(get_user_name)
51
+ else
52
+ puts "Player 1: Enter your name: "
53
+ @player1.change_name(get_user_name)
54
+ puts
55
+
56
+ puts "Player 2: Enter your name "
57
+ @player2.change_name(get_user_name)
58
+ puts
59
+ end
60
+
61
+ puts print_board
62
+ puts
63
+
64
+ turn = Turn.new(@board, @player1)
65
+ winner = nil
66
+
67
+ # Play until the board is full or a win condition is made
68
+ until turn.board_full?
69
+ turn = Turn.new(@board, @player1)
70
+ winner = turn.play_turn
71
+ puts print_board
72
+ puts
73
+ break if winner != nil
74
+
75
+ turn = Turn.new(@board, @player2)
76
+ winner = turn.play_turn
77
+ puts print_board
78
+ puts
79
+ break if winner != nil
80
+ end
81
+
82
+ #Print the appropriate winner response
83
+ if winner == nil
84
+ "The game was a DRAW, how could this have happened??"
85
+ elsif winner.name == "Computer"
86
+ "The computer won selecting at random, wow."
87
+ elsif winner == @player1
88
+ "Congratulations #{@player1.name}, you win!"
89
+ else
90
+ "Congratulations #{@player2.name}, you win!"
91
+ end
92
+ end
93
+
94
+ def get_number_of_players
95
+ input = ""
96
+
97
+ until input == '1' || input == '2'
98
+ puts "Please select '1' for single player against computer"
99
+ puts " OR"
100
+ puts " Select '2' for two player"
101
+ puts " _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_"
102
+ input = gets.chomp
103
+ end
104
+
105
+ input
106
+ end
107
+
108
+ def get_user_name
109
+ input = gets.chomp
110
+ puts "Good luck, #{input}!"
111
+ puts
112
+ input
113
+ end
114
+ end
data/lib/player.rb ADDED
@@ -0,0 +1,13 @@
1
+ class Player
2
+ attr_reader :name,
3
+ :checker
4
+
5
+ def initialize(name, checker)
6
+ @name = name
7
+ @checker = checker
8
+ end
9
+
10
+ def change_name(name)
11
+ @name = name
12
+ end
13
+ end
data/lib/turn.rb ADDED
@@ -0,0 +1,335 @@
1
+ require './lib/board'
2
+
3
+ class Turn
4
+ attr_reader :board, :player
5
+
6
+ def initialize(board, player)
7
+ @board = board
8
+ @player = player
9
+ end
10
+
11
+ def board_full?
12
+ full_board = 42
13
+ @board.layout.each do |cell, attr|
14
+ if attr[:checker] != nil
15
+ full_board -= 1
16
+ else
17
+ break
18
+ end
19
+ end
20
+
21
+ full_board == 0
22
+ end
23
+
24
+ def random_column
25
+ columns = ["A", "B", "C", "D", "E", "F", "G"]
26
+ columns.shuffle!
27
+
28
+ while column_full?(columns[0])
29
+ columns.shift
30
+ end
31
+
32
+ columns[0]
33
+ end
34
+
35
+ def column_full?(column)
36
+ columns = ["A", "B", "C", "D", "E", "F", "G"]
37
+
38
+ column_cells = @board.layout.select do |cell|
39
+ @board.layout[cell][:column] == (columns.index(column) + 1) && @board.layout[cell][:checker] == nil
40
+ end
41
+
42
+ column_cells.empty?
43
+ end
44
+
45
+ def lowest_position(column)
46
+ columns = ["A", "B", "C", "D", "E", "F", "G"]
47
+
48
+ column_cells = @board.layout.select do |cell|
49
+ @board.layout[cell][:column] == (columns.index(column) + 1) && @board.layout[cell][:checker] == nil
50
+ end
51
+
52
+ column_cells.keys[0]
53
+ end
54
+
55
+ def get_input
56
+ input = ""
57
+ columns = ["A", "B", "C", "D", "E", "F", "G"]
58
+
59
+ until columns.include?(input)
60
+ puts "✧・゚:* #{@player.name}, Select a Column for your '#{@player.checker}' checker! *:・゚✧"
61
+ puts " A - B - C - D - E - F - G"
62
+ puts
63
+ input = gets.chomp
64
+
65
+ if columns.include?(input) && column_full?(input) == true
66
+ puts "That column is FULL!"
67
+ input = ""
68
+ end
69
+ end
70
+
71
+ input
72
+ end
73
+
74
+ def add_checker(cell)
75
+ @board.layout[cell][:checker] = @player.checker
76
+ cell
77
+ end
78
+
79
+ def play_turn
80
+ if @player.name == "Computer"
81
+ if check_winner?(add_checker(lowest_position(random_column)))
82
+ winner = @player
83
+ end
84
+ else
85
+ if check_winner?(add_checker(lowest_position(get_input)))
86
+ winner = @player
87
+ end
88
+ end
89
+
90
+ winner
91
+ end
92
+
93
+ def connect_four?(four_cells)
94
+ checkers = []
95
+ winner = false
96
+
97
+ four_cells.each do |cell|
98
+ checkers << cell[1][:checker]
99
+ end
100
+
101
+ if checkers.uniq.size == 1 && !checkers.include?(nil)
102
+ winner = true
103
+ end
104
+
105
+ winner
106
+ end
107
+
108
+ def winner_row?(checker)
109
+ row = @board.layout[checker][:row]
110
+ column = @board.layout[checker][:column]
111
+
112
+ #Create a hash of each element in a row
113
+ row_set = @board.layout.select do |cell| #=> {}
114
+ @board.layout[cell][:row] == row
115
+ end
116
+
117
+ #Create an array of the sets of four cells in a row
118
+ sets_of_four = []
119
+ row_set.each_cons(4) do |set_of_four|
120
+ sets_of_four << set_of_four
121
+ end
122
+
123
+ #Create an array of the sets of four cells that contain the dropped checker
124
+ checker_sets = []
125
+ sets_of_four.each do |checker_set|
126
+
127
+ contains_checker = false
128
+ checker_set.each do |cell|
129
+ if @board.layout[cell[0]][:column] == column
130
+ contains_checker = true
131
+ end
132
+ end
133
+
134
+ if contains_checker
135
+ checker_sets << checker_set
136
+ end
137
+ end
138
+
139
+ #Determine if there is a row win condition containing the last checker dropped
140
+ winner = false
141
+ checker_sets.each do |set|
142
+ if connect_four?(set)
143
+ winner = true
144
+ end
145
+ end
146
+
147
+ winner
148
+ end
149
+
150
+ def winner_column?(checker)
151
+ row = @board.layout[checker][:row]
152
+ column = @board.layout[checker][:column]
153
+
154
+ #Create a hash of each element in a column
155
+ column_set = @board.layout.select do |cell| #=> {}
156
+ @board.layout[cell][:column] == column
157
+ end
158
+
159
+ #Create an array of the sets of four cells in a column
160
+ sets_of_four = []
161
+ column_set.each_cons(4) do |set_of_four|
162
+ sets_of_four << set_of_four
163
+ end
164
+
165
+ #Create an array of the sets of four cells that contain the dropped checker
166
+ checker_sets = []
167
+ sets_of_four.each do |checker_set|
168
+
169
+ contains_checker = false
170
+ checker_set.each do |cell|
171
+ if @board.layout[cell[0]][:row] == row
172
+ contains_checker = true
173
+ end
174
+ end
175
+
176
+ if contains_checker
177
+ checker_sets << checker_set
178
+ end
179
+ end
180
+
181
+ #Determine if there is a column win condition containing the last checker dropped
182
+ winner = false
183
+ checker_sets.each do |set|
184
+ if connect_four?(set)
185
+ winner = true
186
+ end
187
+ end
188
+
189
+ winner
190
+ end
191
+
192
+ def winner_down_diag?(checker)
193
+ row = @board.layout[checker][:row]
194
+ column = @board.layout[checker][:column]
195
+ diagonal_keys = [checker]
196
+
197
+ columns = ["A", "B", "C", "D", "E", "F", "G"] # <= Consider #Hash implementation
198
+
199
+ #Collect upper-left portion of the diagonal set
200
+ until (row + 1) > 6 || (column - 1) < 1
201
+ set_cell = (columns[column - 2] + (row + 1).to_s).to_sym
202
+ diagonal_keys << set_cell
203
+ row += 1
204
+ column -= 1
205
+ end
206
+
207
+ #Resets row and column to starting cell
208
+ row = @board.layout[checker][:row]
209
+ column = @board.layout[checker][:column]
210
+
211
+ #Collect lower-right portion of the diagonal set
212
+ until (row - 1) < 1 || (column + 1) > 7
213
+ set_cell = (columns[column] + (row - 1).to_s).to_sym
214
+ diagonal_keys << set_cell
215
+ row -= 1
216
+ column += 1
217
+ end
218
+
219
+ #Resets row and column to starting cell
220
+ row = @board.layout[checker][:row]
221
+ column = @board.layout[checker][:column]
222
+
223
+ #Create a hash of each cell, in order, from left => right
224
+ diagonal_set = {}
225
+ diagonal_keys.sort.each do |cell|
226
+ diagonal_set[cell] = @board.layout[cell]
227
+ end
228
+
229
+ #Create an array of the sets of four cells in a diagonal
230
+ sets_of_four = []
231
+ diagonal_set.each_cons(4) do |set_of_four|
232
+ sets_of_four << set_of_four
233
+ end
234
+
235
+ #Create an array of the sets of four cells that contain the dropped checker
236
+ checker_sets = []
237
+ sets_of_four.each do |checker_set|
238
+
239
+ contains_checker = false
240
+ checker_set.each do |cell|
241
+ if @board.layout[cell[0]][:row] == row && @board.layout[cell[0]][:column] == column
242
+ contains_checker = true
243
+ end
244
+ end
245
+
246
+ if contains_checker
247
+ checker_sets << checker_set
248
+ end
249
+ end
250
+
251
+ #Determine if there is a diagonal down win condition containing the last checker dropped
252
+ winner = false
253
+ checker_sets.each do |set|
254
+ if connect_four?(set)
255
+ winner = true
256
+ end
257
+ end
258
+
259
+ winner
260
+ end
261
+
262
+ def winner_up_diag?(checker)
263
+ row = @board.layout[checker][:row]
264
+ column = @board.layout[checker][:column]
265
+ diagonal_keys = [checker]
266
+
267
+ columns = ["A", "B", "C", "D", "E", "F", "G"] # <= Consider #Hash implementation
268
+
269
+ #Collect upper-right portion of the diagonal set
270
+ until (row + 1) > 6 || (column + 1) > 7
271
+ set_cell = (columns[column] + (row + 1).to_s).to_sym
272
+ diagonal_keys << set_cell
273
+ row += 1
274
+ column += 1
275
+ end
276
+
277
+ #Resets row and column to starting cell
278
+ row = @board.layout[checker][:row]
279
+ column = @board.layout[checker][:column]
280
+
281
+ #Collect lower-left portion of the diagonal set
282
+ until (row - 1) < 1 || (column - 1) < 1
283
+ set_cell = (columns[column - 2] + (row - 1).to_s).to_sym
284
+ diagonal_keys << set_cell
285
+ row -= 1
286
+ column -= 1
287
+ end
288
+
289
+ #Resets row and column to starting cell
290
+ row = @board.layout[checker][:row]
291
+ column = @board.layout[checker][:column]
292
+
293
+ #Create a hash of each cell, in order, from left => right
294
+ diagonal_set = {}
295
+ diagonal_keys.sort.each do |cell|
296
+ diagonal_set[cell] = @board.layout[cell]
297
+ end
298
+
299
+ #Create an array of the sets of four cells in a diagonal
300
+ sets_of_four = []
301
+ diagonal_set.each_cons(4) do |set_of_four|
302
+ sets_of_four << set_of_four
303
+ end
304
+
305
+ #Create an array of the sets of four cells that contain the dropped checker
306
+ checker_sets = []
307
+ sets_of_four.each do |checker_set|
308
+
309
+ contains_checker = false
310
+ checker_set.each do |cell|
311
+ if @board.layout[cell[0]][:row] == row && @board.layout[cell[0]][:column] == column
312
+ contains_checker = true
313
+ end
314
+ end
315
+
316
+ if contains_checker
317
+ checker_sets << checker_set
318
+ end
319
+ end
320
+
321
+ #Determine if there is a diagonal up win condition containing the last checker dropped
322
+ winner = false
323
+ checker_sets.each do |set|
324
+ if connect_four?(set)
325
+ winner = true
326
+ end
327
+ end
328
+
329
+ winner
330
+ end
331
+
332
+ def check_winner?(cell)
333
+ winner_row?(cell) || winner_column?(cell) || winner_down_diag?(cell) || winner_up_diag?(cell)
334
+ end
335
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: connect_four_ab_akh
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Adam Bailey
8
+ - Antonio Hunt
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2022-12-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '3.7'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '3.7'
28
+ description:
29
+ email:
30
+ executables:
31
+ - connect_four_ab_akh
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - bin/connect_four_ab_akh
36
+ - lib/board.rb
37
+ - lib/connect_four_ab_akh.rb
38
+ - lib/game.rb
39
+ - lib/player.rb
40
+ - lib/turn.rb
41
+ homepage:
42
+ licenses: []
43
+ metadata: {}
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubygems_version: 3.1.4
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: Connect Four - 1 or 2 players
63
+ test_files: []