connect_cuatro 0.2.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 +7 -0
- data/bin/connect_cuatro +4 -0
- data/lib/board.rb +101 -0
- data/lib/cli.rb +9 -0
- data/lib/connect_four.rb +90 -0
- data/lib/game_engine.rb +99 -0
- data/lib/ip_config.rb +4 -0
- data/lib/msg.rb +52 -0
- data/lib/multiplayer_game_engine.rb +149 -0
- data/lib/player.rb +9 -0
- metadata +55 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 07ff3f60ceb45977060c65c2589af0eafd766e1730ce122d53f3bcdde980b3ef
|
|
4
|
+
data.tar.gz: 3f5fc98c83e067b825386028088218edbba01b4b42c88a4fb61204205e2e180c
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f930ad3eacd2bf8f7312905ec7fc77b4721543ea238077593ec51a1b863a1aa402e4150cc37c35929b13a93c99fa73c2acfc39dafa5d8b11e4fd06fc3dab11d6
|
|
7
|
+
data.tar.gz: d7efd9647459774b052e88dccab13f207f819b1a290da20820ae55ba10da155a99ce9f65b426d0914e820be6c8754ca5e938f641db6faef6ba28cae4839848ab
|
data/bin/connect_cuatro
ADDED
data/lib/board.rb
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
class Board
|
|
2
|
+
attr_reader :board
|
|
3
|
+
|
|
4
|
+
def initialize(rows = 6, columns = 7)
|
|
5
|
+
# board 'height'
|
|
6
|
+
@num_rows = rows
|
|
7
|
+
# board 'width'
|
|
8
|
+
@num_columns = columns
|
|
9
|
+
# Initialize an empty board filled with '.'
|
|
10
|
+
@board = Array.new(@num_rows) { Array.new(@num_columns, '.') }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# return x, y coordinates
|
|
14
|
+
def drop_token(column, token)
|
|
15
|
+
col_idx = column_to_index(column)
|
|
16
|
+
row_idx = @num_rows - 1
|
|
17
|
+
@board.reverse_each do |row|
|
|
18
|
+
if row[col_idx] == "."
|
|
19
|
+
# animate dropping of token before return
|
|
20
|
+
self.animate_token(col_idx, row_idx, token)
|
|
21
|
+
row[col_idx] = token
|
|
22
|
+
return col_idx, row_idx
|
|
23
|
+
end
|
|
24
|
+
row_idx -= 1
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def animate_token(col_idx, row_idx, token)
|
|
29
|
+
row_idx.times do |i|
|
|
30
|
+
sleep 0.77
|
|
31
|
+
CLI.clear
|
|
32
|
+
@board.each_with_index do |row, idx|
|
|
33
|
+
pseudo_row = row.dup
|
|
34
|
+
if idx == i
|
|
35
|
+
pseudo_row[col_idx] = token
|
|
36
|
+
puts pseudo_row.join(' ')
|
|
37
|
+
else
|
|
38
|
+
puts row.join(' ')
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
# Print column numbers for easier reference
|
|
42
|
+
puts COLUMNS[0...@num_columns].join(' ')
|
|
43
|
+
end
|
|
44
|
+
sleep 0.77
|
|
45
|
+
CLI.clear
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def display
|
|
49
|
+
# Loop through each row and print it
|
|
50
|
+
@board.each do |row|
|
|
51
|
+
puts row.join(' ')
|
|
52
|
+
end
|
|
53
|
+
# Print column numbers for easier reference
|
|
54
|
+
puts COLUMNS[0...@num_columns].join(' ')
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def column_to_index(column)
|
|
58
|
+
COLUMNS.index(column)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def board_full?
|
|
62
|
+
!@board.flatten.include?(".")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def check_win(column, row, token)
|
|
66
|
+
DIRECTIONS.each do |dx, dy|
|
|
67
|
+
count = 1 # Start with the token just placed
|
|
68
|
+
|
|
69
|
+
# Check one direction
|
|
70
|
+
count += check_direction(column, row, dx, dy, token)
|
|
71
|
+
# Check the opposite direction
|
|
72
|
+
count += check_direction(column, row, -dx, -dy, token)
|
|
73
|
+
|
|
74
|
+
return true if count >= 4 # Four or more in a row
|
|
75
|
+
end
|
|
76
|
+
false
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def check_direction(column, row, dx, dy, token)
|
|
80
|
+
count = 0
|
|
81
|
+
x, y = column + dx, row - dy
|
|
82
|
+
|
|
83
|
+
while y.between?(0, @num_rows - 1) && x.between?(0, @num_columns - 1) && @board[y][x] == token
|
|
84
|
+
count += 1
|
|
85
|
+
x += dx
|
|
86
|
+
y -= dy
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
count
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
COLUMNS = %w{A B C D E F G}
|
|
94
|
+
|
|
95
|
+
DIRECTIONS = [
|
|
96
|
+
[0, 1], # Horizontal
|
|
97
|
+
[1, 0], # Vertical
|
|
98
|
+
[1, 1], # Diagonal right
|
|
99
|
+
[1, -1] # Diagonal left
|
|
100
|
+
]
|
|
101
|
+
end
|
data/lib/cli.rb
ADDED
data/lib/connect_four.rb
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require_relative 'game_engine'
|
|
3
|
+
require_relative 'multiplayer_game_engine'
|
|
4
|
+
require_relative 'msg'
|
|
5
|
+
require_relative 'ip_config'
|
|
6
|
+
|
|
7
|
+
class ConnectFour
|
|
8
|
+
include MSG, IP_CONFIG
|
|
9
|
+
|
|
10
|
+
attr_reader :game_engine
|
|
11
|
+
|
|
12
|
+
def initialize
|
|
13
|
+
@game_engine = nil
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def main_menu
|
|
17
|
+
puts WELCOME_MSG
|
|
18
|
+
play_quit = CLI.get_input
|
|
19
|
+
# play_quit = "P" # testing
|
|
20
|
+
if play_quit == "Q"
|
|
21
|
+
abort(BYE_MSG)
|
|
22
|
+
elsif play_quit == "P"
|
|
23
|
+
puts PLAY_MSG
|
|
24
|
+
set_game_engine
|
|
25
|
+
else
|
|
26
|
+
puts P_OR_Q_ERR_MSG
|
|
27
|
+
main_menu
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
#returns game engine MP or SP
|
|
32
|
+
def set_game_engine
|
|
33
|
+
puts ONEPLAYER_TWOPLAYER
|
|
34
|
+
game_mode = CLI.get_input
|
|
35
|
+
# game_mode = "2P" # testing
|
|
36
|
+
if game_mode == "1P"
|
|
37
|
+
@game_engine = GameEngine.new
|
|
38
|
+
self.start
|
|
39
|
+
elsif game_mode == "2P"
|
|
40
|
+
@game_engine = MPGameEngine.new
|
|
41
|
+
self.start
|
|
42
|
+
else
|
|
43
|
+
puts INPUT_ERR_MSG(game_mode)
|
|
44
|
+
set_game_engine
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def start
|
|
49
|
+
if @game_engine.class == MPGameEngine
|
|
50
|
+
self.loiter # wait in lobby
|
|
51
|
+
@game_engine.play_game
|
|
52
|
+
self.main_menu
|
|
53
|
+
else
|
|
54
|
+
@game_engine.play_game
|
|
55
|
+
self.main_menu
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def loiter
|
|
60
|
+
# make initial curl request
|
|
61
|
+
username = ENV['USER']
|
|
62
|
+
foe = ""
|
|
63
|
+
p1 = ""
|
|
64
|
+
# send /init request
|
|
65
|
+
response = `curl -s "#{P2P_IP}/init?player=#{username}"`.chomp # => '...patient'
|
|
66
|
+
until response == "start"
|
|
67
|
+
print WAITING_MSG
|
|
68
|
+
# send /start request; if game ready to start, will return foe
|
|
69
|
+
response = `curl -s "#{P2P_IP}/start?player=#{username}"`.chomp
|
|
70
|
+
if response.include?("start")
|
|
71
|
+
start_responses = response.split(" ")
|
|
72
|
+
foe = start_responses[1]
|
|
73
|
+
p1 = start_responses[2] # p1 used to set @current_player
|
|
74
|
+
response = "start"
|
|
75
|
+
break
|
|
76
|
+
end
|
|
77
|
+
LOADER_MSG(7) # wait 7 seconds
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
puts ""
|
|
81
|
+
puts OPP_FOUND
|
|
82
|
+
@game_engine.player1 = Player.new(username, token = "X")
|
|
83
|
+
@game_engine.player2 = Player.new(foe, token = "O")
|
|
84
|
+
@game_engine.set_current_player(p1)
|
|
85
|
+
print "game ready to start"
|
|
86
|
+
LOADER_MSG(3) # wait 3 seconds
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# ConnectFour.new.main_menu
|
data/lib/game_engine.rb
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
require_relative 'board'
|
|
2
|
+
require_relative 'player'
|
|
3
|
+
require_relative 'msg'
|
|
4
|
+
require_relative 'cli'
|
|
5
|
+
|
|
6
|
+
class GameEngine
|
|
7
|
+
include MSG
|
|
8
|
+
|
|
9
|
+
attr_reader :player1,
|
|
10
|
+
:ai,
|
|
11
|
+
:players,
|
|
12
|
+
:current_player,
|
|
13
|
+
:board,
|
|
14
|
+
:piece_count
|
|
15
|
+
|
|
16
|
+
def initialize
|
|
17
|
+
@player1 = Player.new(ENV['USER'], "X")
|
|
18
|
+
@ai = Player.new("HAL", "O")
|
|
19
|
+
@players = [@player1, @ai]
|
|
20
|
+
@board = Board.new
|
|
21
|
+
@current_player = @players[0]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def play_game # Player has hit 'p'
|
|
25
|
+
game_over = false
|
|
26
|
+
until game_over
|
|
27
|
+
puts @board.display
|
|
28
|
+
# keep false until valid input => in-range, un-filled column
|
|
29
|
+
turn_over = false
|
|
30
|
+
plyr = whose_turn
|
|
31
|
+
token_x, token_y = nil, nil # returned from #drop_token and passed to #win_condition
|
|
32
|
+
# if human player
|
|
33
|
+
if plyr == @player1
|
|
34
|
+
# force user to enter valid input
|
|
35
|
+
until turn_over
|
|
36
|
+
# only runs once (right after opponent takes turn)
|
|
37
|
+
puts PLAYER_TURN_MSG
|
|
38
|
+
column = CLI.get_input
|
|
39
|
+
if valid_input(column)
|
|
40
|
+
token_x, token_y = drop_token(column, plyr.token)
|
|
41
|
+
turn_over = true
|
|
42
|
+
else
|
|
43
|
+
# continue to run until HUMAN user enters valid input
|
|
44
|
+
puts INPUT_ERR_MSG(column)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
else
|
|
48
|
+
# computer's turn
|
|
49
|
+
# TODO trash talk
|
|
50
|
+
# keep false until computer picks unfilled column (idx always in-range)
|
|
51
|
+
until turn_over
|
|
52
|
+
column = Board::COLUMNS.sample
|
|
53
|
+
if valid_input(column)
|
|
54
|
+
token_x, token_y = drop_token(column, plyr.token)
|
|
55
|
+
turn_over = true
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
if @board.check_win(token_x, token_y, plyr.token)
|
|
60
|
+
puts @board.display
|
|
61
|
+
puts "#{VICTORY_MSG(plyr.name)}"
|
|
62
|
+
game_over = true
|
|
63
|
+
end
|
|
64
|
+
if @board.board_full?
|
|
65
|
+
puts @board.display
|
|
66
|
+
puts TIE_GAME_MSG
|
|
67
|
+
game_over = true
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def valid_input(column)
|
|
73
|
+
idx = @board.column_to_index(column)
|
|
74
|
+
if Board::COLUMNS.include?(column) && @board.board[0][idx] == '.'
|
|
75
|
+
return true
|
|
76
|
+
else
|
|
77
|
+
return false
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# returns player object and increments queue
|
|
82
|
+
def whose_turn
|
|
83
|
+
plyr = @current_player
|
|
84
|
+
if plyr == @players[0]
|
|
85
|
+
@current_player = @players[1]
|
|
86
|
+
else
|
|
87
|
+
@current_player = @players[0]
|
|
88
|
+
end
|
|
89
|
+
return plyr
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def drop_token(column, token)
|
|
93
|
+
idx = @board.column_to_index(column)
|
|
94
|
+
@board.drop_token(column, token)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# session = GameEngine.new
|
|
99
|
+
# session.main_menu
|
data/lib/ip_config.rb
ADDED
data/lib/msg.rb
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module MSG
|
|
2
|
+
ONEPLAYER_TWOPLAYER = "1P || 2P"
|
|
3
|
+
|
|
4
|
+
WELCOME_MSG = "Let's play **** CONNECT FOUR ****
|
|
5
|
+
Connect four of your checkers in a row while preventing your opponent from doing the same.\n
|
|
6
|
+
press 'p' to play; 'q' to quit:"
|
|
7
|
+
|
|
8
|
+
PLAY_MSG = "#{ENV["USER"]} says we're playing Connect Four!!"
|
|
9
|
+
|
|
10
|
+
BYE_MSG = "Sucka’s only see what’s in front of them while real game playa’s see the whole board, – 777\nDeuces!"
|
|
11
|
+
|
|
12
|
+
MP_BYE_MSG = "If you want to play again, rerun the script. Goodbye!"
|
|
13
|
+
|
|
14
|
+
P_OR_Q_ERR_MSG = "Sorry, I didn't understand that selection. press 'p' to play; 'q' to quit:"
|
|
15
|
+
|
|
16
|
+
PLAYER_TURN_MSG = "Choose where you want to drop your token"
|
|
17
|
+
|
|
18
|
+
TIE_GAME_MSG = "The board is full!! It's a draw!"
|
|
19
|
+
|
|
20
|
+
WAITING_MSG = "Waiting for opponent to join"
|
|
21
|
+
|
|
22
|
+
OPP_FOUND = "Opponent found...establishing connection"
|
|
23
|
+
|
|
24
|
+
def TIMES_UP_MSG(column)
|
|
25
|
+
"Time's up: you randomly chose column #{column}"
|
|
26
|
+
end
|
|
27
|
+
def WAITING_FOR_PLYR_MSG(plyr_name)
|
|
28
|
+
"Waiting for #{plyr_name} to make a move"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def LOADER_MSG(i)
|
|
32
|
+
i.times do
|
|
33
|
+
sleep 1.6
|
|
34
|
+
print " . "
|
|
35
|
+
end
|
|
36
|
+
puts ""
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def VICTORY_MSG(plyr_name)
|
|
40
|
+
if plyr_name == "HAL"
|
|
41
|
+
"HAL won!! You just lost to an unliving being!! Boom!!"
|
|
42
|
+
else
|
|
43
|
+
"#Hot Dog, we have a Winner! Congratulations #{plyr_name}!!!"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def INPUT_ERR_MSG(input)
|
|
48
|
+
"#{input} is an invalid selection"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# X_OR_O_MSG = "Pick your piece! X or O??"
|
|
52
|
+
end
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
require_relative 'board'
|
|
2
|
+
require_relative 'player'
|
|
3
|
+
require_relative 'msg'
|
|
4
|
+
require_relative 'cli'
|
|
5
|
+
require_relative 'ip_config'
|
|
6
|
+
require 'thread'
|
|
7
|
+
|
|
8
|
+
class MPGameEngine
|
|
9
|
+
include MSG, IP_CONFIG
|
|
10
|
+
|
|
11
|
+
attr_reader :board
|
|
12
|
+
attr_accessor :player1,
|
|
13
|
+
:player2,
|
|
14
|
+
:current_player
|
|
15
|
+
|
|
16
|
+
def initialize
|
|
17
|
+
@player1 = nil
|
|
18
|
+
@player2 = nil
|
|
19
|
+
@current_player = nil
|
|
20
|
+
@board = Board.new
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def players
|
|
24
|
+
[@player1, @player2]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def set_current_player(p1)
|
|
28
|
+
@current_player = self.players.filter { |player| player.name == p1 }.first
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def play_game # Player has hit 'p'
|
|
32
|
+
game_over = false
|
|
33
|
+
until game_over
|
|
34
|
+
puts @board.display
|
|
35
|
+
turn_over = false
|
|
36
|
+
plyr = whose_turn
|
|
37
|
+
token_x, token_y = nil, nil # returned from #drop_token and passed to #win_condition
|
|
38
|
+
# local client
|
|
39
|
+
if plyr == @player1
|
|
40
|
+
input_received = false
|
|
41
|
+
column = nil
|
|
42
|
+
mutex = Mutex.new
|
|
43
|
+
|
|
44
|
+
input_thread = Thread.new do
|
|
45
|
+
puts PLAYER_TURN_MSG
|
|
46
|
+
# keep false until valid input => in-range, un-filled column
|
|
47
|
+
until turn_over
|
|
48
|
+
ready = IO.select([STDIN], nil, nil, 1.6) # 4th arg is 'release after time' (s)
|
|
49
|
+
|
|
50
|
+
if ready
|
|
51
|
+
column = STDIN.gets.chomp.upcase
|
|
52
|
+
if valid_input(column)
|
|
53
|
+
mutex.synchronize do
|
|
54
|
+
input_received = true
|
|
55
|
+
turn_over = true
|
|
56
|
+
column = column
|
|
57
|
+
end
|
|
58
|
+
else
|
|
59
|
+
puts INPUT_ERR_MSG(column)
|
|
60
|
+
# continue to run until local client enters valid input
|
|
61
|
+
# loops back to until turn_over
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
timer_thread = Thread.new do
|
|
68
|
+
10.times do |i|
|
|
69
|
+
print "#{10 - i }. . "
|
|
70
|
+
sleep 1.6
|
|
71
|
+
break if mutex.synchronize { input_received }
|
|
72
|
+
end
|
|
73
|
+
# if the player doesn't select a column, random valid selection will occur
|
|
74
|
+
until turn_over
|
|
75
|
+
column = Board::COLUMNS.sample
|
|
76
|
+
if valid_input(column)
|
|
77
|
+
puts TIMES_UP_MSG(column)
|
|
78
|
+
mutex.synchronize do
|
|
79
|
+
input_received = true
|
|
80
|
+
turn_over = true
|
|
81
|
+
column = column
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
[input_thread, timer_thread].each(&:join)
|
|
88
|
+
|
|
89
|
+
token_x, token_y = drop_token(column, plyr.token)
|
|
90
|
+
# send valid column selection to server
|
|
91
|
+
`curl -s "#{P2P_IP}/move?player=#{plyr.name}?column=#{column}"`
|
|
92
|
+
else # remote client || @player2
|
|
93
|
+
until turn_over
|
|
94
|
+
11.times do
|
|
95
|
+
puts WAITING_FOR_PLYR_MSG(plyr.name)
|
|
96
|
+
response = `curl -s "#{P2P_IP}/status?player=#{@player1.name}"`.chomp
|
|
97
|
+
# require 'pry'; binding.pry
|
|
98
|
+
unless response.include?("patience") # unless this fails => response == <valid letter>
|
|
99
|
+
token_x, token_y = drop_token(response, plyr.token)
|
|
100
|
+
turn_over = true
|
|
101
|
+
break
|
|
102
|
+
end
|
|
103
|
+
sleep 1.6
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
if @board.check_win(token_x, token_y, plyr.token)
|
|
109
|
+
puts @board.display
|
|
110
|
+
puts "#{VICTORY_MSG(plyr.name)}"
|
|
111
|
+
game_over = true
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
if @board.board_full?
|
|
115
|
+
puts @board.display
|
|
116
|
+
puts TIE_GAME_MSG
|
|
117
|
+
game_over = true
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
sleep 1.6
|
|
121
|
+
# send /reset command to server to clear out stored variables
|
|
122
|
+
`curl -s "#{P2P_IP}/reset"`
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def valid_input(column)
|
|
126
|
+
idx = @board.column_to_index(column)
|
|
127
|
+
if Board::COLUMNS.include?(column) && @board.board[0][idx] == '.'
|
|
128
|
+
true
|
|
129
|
+
else
|
|
130
|
+
false
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# returns player object and increments queue
|
|
135
|
+
def whose_turn
|
|
136
|
+
plyr = @current_player
|
|
137
|
+
if plyr == players[0]
|
|
138
|
+
@current_player = players[1]
|
|
139
|
+
else
|
|
140
|
+
@current_player = players[0]
|
|
141
|
+
end
|
|
142
|
+
plyr
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def drop_token(column, token)
|
|
146
|
+
idx = @board.column_to_index(column)
|
|
147
|
+
@board.drop_token(column, token)
|
|
148
|
+
end
|
|
149
|
+
end
|
data/lib/player.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: connect_cuatro
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.2.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Matt Darlington
|
|
8
|
+
- Taylor Pubins
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2023-09-14 00:00:00.000000000 Z
|
|
13
|
+
dependencies: []
|
|
14
|
+
description: Digital version of the Classic Connect Four boardgame.
|
|
15
|
+
email:
|
|
16
|
+
- matthewsdarlington@gmail.com
|
|
17
|
+
- tpubz@icloud.com
|
|
18
|
+
executables:
|
|
19
|
+
- connect_cuatro
|
|
20
|
+
extensions: []
|
|
21
|
+
extra_rdoc_files: []
|
|
22
|
+
files:
|
|
23
|
+
- bin/connect_cuatro
|
|
24
|
+
- lib/board.rb
|
|
25
|
+
- lib/cli.rb
|
|
26
|
+
- lib/connect_four.rb
|
|
27
|
+
- lib/game_engine.rb
|
|
28
|
+
- lib/ip_config.rb
|
|
29
|
+
- lib/msg.rb
|
|
30
|
+
- lib/multiplayer_game_engine.rb
|
|
31
|
+
- lib/player.rb
|
|
32
|
+
homepage: http://rubygems.org/gems/connect_cuatro
|
|
33
|
+
licenses:
|
|
34
|
+
- MIT
|
|
35
|
+
metadata: {}
|
|
36
|
+
post_install_message:
|
|
37
|
+
rdoc_options: []
|
|
38
|
+
require_paths:
|
|
39
|
+
- lib
|
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
41
|
+
requirements:
|
|
42
|
+
- - ">="
|
|
43
|
+
- !ruby/object:Gem::Version
|
|
44
|
+
version: '0'
|
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
46
|
+
requirements:
|
|
47
|
+
- - ">="
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: '0'
|
|
50
|
+
requirements: []
|
|
51
|
+
rubygems_version: 3.4.19
|
|
52
|
+
signing_key:
|
|
53
|
+
specification_version: 4
|
|
54
|
+
summary: Connect Four -- Turing School of Software & Design -- Mod1 Project
|
|
55
|
+
test_files: []
|