connect_four_ab-akh 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/connect_four_ab-akh +32 -0
- data/lib/connect_four_ab-akh/board.rb +33 -0
- data/lib/connect_four_ab-akh/game.rb +79 -0
- data/lib/connect_four_ab-akh/player.rb +9 -0
- data/lib/connect_four_ab-akh/turn.rb +335 -0
- data/lib/connect_four_ab-akh.rb +30 -0
- metadata +63 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 96eea4eeb42f21b2dbea427824d2ce49a156df72b9c7f9f2cb0b84b4d3615561
|
4
|
+
data.tar.gz: 6ed98f45a0eeb05f3bf4251bba3d5726fe060e6836a8bafd19bd5f1773a945fe
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a46c6b7ff8487cb2f2d56249de2fa9fb48541537e03bf34b668d1f8be39ee38bab28d8c2cfcdcf2d6692117c6b996c5a33d11ec55b5026520e079837126352d7
|
7
|
+
data.tar.gz: 1e43f3970dcc3c4b3093f8f58bbe3c05f20290615fe3e3e3587eb628494bdd9e5c34359b35d5f8f74b11d8e46116fac13a7d3605c29b15ec4299e5121d9f2402
|
@@ -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
|
@@ -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,79 @@
|
|
1
|
+
class Game
|
2
|
+
attr_reader :board,
|
3
|
+
:player,
|
4
|
+
:computer
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@board = Board.new
|
8
|
+
@player = Player.new("Player", "X")
|
9
|
+
@computer = Player.new("Computer", "O")
|
10
|
+
end
|
11
|
+
|
12
|
+
def start
|
13
|
+
puts welcome_user
|
14
|
+
puts print_board
|
15
|
+
end
|
16
|
+
|
17
|
+
def welcome_user
|
18
|
+
"Welcome to CONNECT FOUR"
|
19
|
+
end
|
20
|
+
|
21
|
+
def print_board
|
22
|
+
# Create board string accumulator
|
23
|
+
board_string = "ABCDEFG\n"
|
24
|
+
counter = 6
|
25
|
+
|
26
|
+
# Add each board cell's checker value to string in reverse row order, starting at 6
|
27
|
+
6.times do
|
28
|
+
|
29
|
+
# Create a hash of each key:value pair of the row corresponding to the counter
|
30
|
+
row_string = @board.layout.select do |cell|
|
31
|
+
@board.layout[cell][:row] == counter
|
32
|
+
end
|
33
|
+
#require "pry"; binding.pry
|
34
|
+
# Add each checker piece or '.' to the string accumulator
|
35
|
+
row_string.each do |cell|
|
36
|
+
if cell[1][:checker] != nil
|
37
|
+
board_string << cell[1][:checker]
|
38
|
+
else
|
39
|
+
board_string << "."
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Add line break to end of string accumulator
|
44
|
+
board_string << "\n"
|
45
|
+
|
46
|
+
counter -= 1
|
47
|
+
end
|
48
|
+
board_string
|
49
|
+
end
|
50
|
+
|
51
|
+
def start
|
52
|
+
puts print_board
|
53
|
+
|
54
|
+
turn = Turn.new(@board, @player)
|
55
|
+
winner = nil
|
56
|
+
|
57
|
+
until turn.board_full?
|
58
|
+
turn = Turn.new(@board, @player)
|
59
|
+
winner = turn.play_turn
|
60
|
+
puts print_board
|
61
|
+
puts
|
62
|
+
break if winner != nil
|
63
|
+
|
64
|
+
turn = Turn.new(@board, @computer)
|
65
|
+
winner = turn.play_turn
|
66
|
+
puts print_board
|
67
|
+
puts
|
68
|
+
break if winner != nil
|
69
|
+
end
|
70
|
+
|
71
|
+
if winner == @player
|
72
|
+
puts "Congratulations #{@player.name}, you win!"
|
73
|
+
elsif winner == @computer
|
74
|
+
puts "Sorry #{@player.name}, you lose!"
|
75
|
+
else
|
76
|
+
"The game was a DRAW, you couldn't beat a computer choosing at random"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -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 "✧・゚:* Select A Column *:・゚✧"
|
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
|
@@ -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
|
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.1
|
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/connect_four_ab-akh.rb
|
37
|
+
- lib/connect_four_ab-akh/board.rb
|
38
|
+
- lib/connect_four_ab-akh/game.rb
|
39
|
+
- lib/connect_four_ab-akh/player.rb
|
40
|
+
- lib/connect_four_ab-akh/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: []
|