connect_four 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/.travis.yml +8 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +32 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +27 -0
- data/Rakefile +44 -0
- data/VERSION +1 -0
- data/connect_four.gemspec +62 -0
- data/lib/connect_four.rb +270 -0
- data/lib/play_connect_four.rb +4 -0
- data/spec/connect_four_spec.rb +31 -0
- data/spec/spec_helper.rb +12 -0
- metadata +131 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "rspec", "~> 2.8.0"
|
10
|
+
gem "bundler"
|
11
|
+
gem "jeweler", "~> 1.8.4"
|
12
|
+
end
|
13
|
+
|
14
|
+
#we need colorize for colored console output.
|
15
|
+
gem 'colorize'
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
colorize (0.5.8)
|
5
|
+
diff-lcs (1.1.3)
|
6
|
+
git (1.2.5)
|
7
|
+
jeweler (1.8.4)
|
8
|
+
bundler (~> 1.0)
|
9
|
+
git (>= 1.2.5)
|
10
|
+
rake
|
11
|
+
rdoc
|
12
|
+
json (1.7.5)
|
13
|
+
rake (10.0.2)
|
14
|
+
rdoc (3.12)
|
15
|
+
json (~> 1.4)
|
16
|
+
rspec (2.8.0)
|
17
|
+
rspec-core (~> 2.8.0)
|
18
|
+
rspec-expectations (~> 2.8.0)
|
19
|
+
rspec-mocks (~> 2.8.0)
|
20
|
+
rspec-core (2.8.0)
|
21
|
+
rspec-expectations (2.8.0)
|
22
|
+
diff-lcs (~> 1.1.2)
|
23
|
+
rspec-mocks (2.8.0)
|
24
|
+
|
25
|
+
PLATFORMS
|
26
|
+
x86-mingw32
|
27
|
+
|
28
|
+
DEPENDENCIES
|
29
|
+
bundler
|
30
|
+
colorize
|
31
|
+
jeweler (~> 1.8.4)
|
32
|
+
rspec (~> 2.8.0)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Price Hardman
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
= connect_four
|
2
|
+
|
3
|
+
Play connect four in the command line!
|
4
|
+
|
5
|
+
This gem allows for two players to play Connect Four in the terminal.
|
6
|
+
|
7
|
+
Play by requiring 'connect_four', creating an instance of the Game class, and then calling the play method on that Game object.
|
8
|
+
|
9
|
+
Under the hood:
|
10
|
+
|
11
|
+
The board is a 6x7 array of Cell objects, which hold their state (open or occupied) and their searchpaths. Searchpaths are the game's way of determining a winner. Each cell has a collection of valid searchpaths, routes the game will travel outward radially up to 3 spaces from the starting cell to look for adjacent moves by the given player. For example, the bottom right cell has N, NE, and E as its searchpaths, since going any direction other than those would take us off the board. After every player's turn, the game will travel all the searchpaths of every cell on which that player has made a move. If all three cells on the path (plus the starting cell) are in that player's move history, then that player is declared the winner and the game is over.
|
12
|
+
|
13
|
+
== Contributing to connect_four
|
14
|
+
|
15
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
16
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
17
|
+
* Fork the project.
|
18
|
+
* Start a feature/bugfix branch.
|
19
|
+
* Commit and push until you are happy with your contribution.
|
20
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
21
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
22
|
+
|
23
|
+
== Copyright
|
24
|
+
|
25
|
+
Copyright (c) 2012 Price Hardman. See LICENSE.txt for
|
26
|
+
further details.
|
27
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "connect_four"
|
18
|
+
gem.homepage = "http://github.com/PriceHardman/connect_four"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = "Play connect four in the command line."
|
21
|
+
gem.description = "The connect_four.rb file contains classes for an object-oriented connect four game, designed to be played between two human players on the command line. Colored player symbols courtesy of the colorize gem. Play by creating an instance of Game and calling the play method on it."
|
22
|
+
gem.email = "PriceHardman@gmail.com"
|
23
|
+
gem.authors = ["Price Hardman"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rspec/core'
|
29
|
+
require 'rspec/core/rake_task'
|
30
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
31
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
32
|
+
end
|
33
|
+
|
34
|
+
task :default => :spec
|
35
|
+
|
36
|
+
require 'rdoc/task'
|
37
|
+
Rake::RDocTask.new do |rdoc|
|
38
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
39
|
+
|
40
|
+
rdoc.rdoc_dir = 'rdoc'
|
41
|
+
rdoc.title = "connect_four #{version}"
|
42
|
+
rdoc.rdoc_files.include('README*')
|
43
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
44
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "connect_four"
|
8
|
+
s.version = "0.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Price Hardman"]
|
12
|
+
s.date = "2012-12-11"
|
13
|
+
s.description = "The connect_four.rb file contains classes for an object-oriented connect four game, designed to be played between two human players on the command line. Colored player symbols courtesy of the colorize gem. Play by creating an instance of Game and calling the play method on it."
|
14
|
+
s.email = "PriceHardman@gmail.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".rspec",
|
22
|
+
".travis.yml",
|
23
|
+
"Gemfile",
|
24
|
+
"Gemfile.lock",
|
25
|
+
"LICENSE.txt",
|
26
|
+
"README.rdoc",
|
27
|
+
"Rakefile",
|
28
|
+
"VERSION",
|
29
|
+
"connect_four.gemspec",
|
30
|
+
"lib/connect_four.rb",
|
31
|
+
"lib/play_connect_four.rb",
|
32
|
+
"spec/connect_four_spec.rb",
|
33
|
+
"spec/spec_helper.rb"
|
34
|
+
]
|
35
|
+
s.homepage = "http://github.com/PriceHardman/connect_four"
|
36
|
+
s.licenses = ["MIT"]
|
37
|
+
s.require_paths = ["lib"]
|
38
|
+
s.rubygems_version = "1.8.24"
|
39
|
+
s.summary = "Play connect four in the command line."
|
40
|
+
|
41
|
+
if s.respond_to? :specification_version then
|
42
|
+
s.specification_version = 3
|
43
|
+
|
44
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
45
|
+
s.add_runtime_dependency(%q<colorize>, [">= 0"])
|
46
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
|
47
|
+
s.add_development_dependency(%q<bundler>, [">= 0"])
|
48
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
|
49
|
+
else
|
50
|
+
s.add_dependency(%q<colorize>, [">= 0"])
|
51
|
+
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
52
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
53
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
54
|
+
end
|
55
|
+
else
|
56
|
+
s.add_dependency(%q<colorize>, [">= 0"])
|
57
|
+
s.add_dependency(%q<rspec>, ["~> 2.8.0"])
|
58
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
59
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
data/lib/connect_four.rb
ADDED
@@ -0,0 +1,270 @@
|
|
1
|
+
require 'colorize'
|
2
|
+
|
3
|
+
class Cell
|
4
|
+
#Each spot on the board is represented by a cell object, which contains the state of that spot
|
5
|
+
# (e.g. empty, player1, player2)
|
6
|
+
attr_accessor :state
|
7
|
+
attr_reader :row, :column, :search_paths
|
8
|
+
def initialize(args)
|
9
|
+
@state = " " #available to have a move made in it.
|
10
|
+
@row = args[:row] #set at initialization
|
11
|
+
@column = args[:column] #set at initialization
|
12
|
+
@search_paths = [] #will become set based on position on the board.
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_search_path(path)
|
16
|
+
@search_paths << path
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
class Board
|
22
|
+
#the board class is, at its core, a 6x7 array of cell objects. The board class is also responsible for setting the
|
23
|
+
#correct searchpaths for the cells, which will be how the game searches for a winner.
|
24
|
+
attr_accessor :path_coords
|
25
|
+
attr_reader :rows, :columns, :winner, :grid
|
26
|
+
def initialize
|
27
|
+
@grid = create_board
|
28
|
+
@rows = ("A".."F").to_a
|
29
|
+
@columns = ("1".."7").to_a
|
30
|
+
@path_coords = {:N =>[-1,0],:NE =>[-1,1],:E =>[0,1],:SE =>[1,1],:S =>[1,0],:SW =>[1,-1],:W =>[0,-1],:NW =>[-1,-1]}
|
31
|
+
end
|
32
|
+
|
33
|
+
def cell(a1,column = nil)
|
34
|
+
#takes either an alphanumeric string argument (e.g. B3), or two Fixnums, and returns cell at those coordinates.
|
35
|
+
a1.is_a?(String) ? @grid[@rows.index(a1[0].upcase)][@columns.index(a1[1])] : @grid[a1][column]
|
36
|
+
end
|
37
|
+
|
38
|
+
def offset(cell_x_y, x_offset, y_offset)
|
39
|
+
@grid[cell_x_y.row + x_offset][cell_x_y.column + y_offset]
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def create_board #creates the board as 6x7 multidimensional array of Cell objects.
|
44
|
+
board = Array.new(6){Array.new(7)}
|
45
|
+
board.each_with_index do |row,row_number|
|
46
|
+
row.each_index do |column_number|
|
47
|
+
board[row_number][column_number] = Cell.new({:row => row_number,:column => column_number})
|
48
|
+
set_search_paths(board[row_number][column_number])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
board #return the populated array of cell objects.
|
52
|
+
end
|
53
|
+
|
54
|
+
def set_search_paths(cell)
|
55
|
+
#adds search paths to the appropriate cells. For example, the bottom left cell will get N, NE, and E searchpaths,
|
56
|
+
#since SE,S,SW,W,or NW paths would take us off the board. These searchpaths are how we test for a winner,
|
57
|
+
#without searching every possible winning configuration.
|
58
|
+
if cell.row > 2
|
59
|
+
cell.add_search_path(:N)
|
60
|
+
end
|
61
|
+
|
62
|
+
if (cell.row >2) && (cell.column < 4)
|
63
|
+
cell.add_search_path(:NE)
|
64
|
+
end
|
65
|
+
|
66
|
+
if cell.column < 4
|
67
|
+
cell.add_search_path(:E)
|
68
|
+
end
|
69
|
+
|
70
|
+
if (cell.row<3) && (cell.column < 4)
|
71
|
+
cell.add_search_path(:SE)
|
72
|
+
end
|
73
|
+
|
74
|
+
if cell.row < 3
|
75
|
+
cell.add_search_path(:S)
|
76
|
+
end
|
77
|
+
|
78
|
+
if (cell.row<3)&&(cell.column>2)
|
79
|
+
cell.add_search_path(:SW)
|
80
|
+
end
|
81
|
+
|
82
|
+
if (cell.column > 2)
|
83
|
+
cell.add_search_path(:W)
|
84
|
+
end
|
85
|
+
|
86
|
+
if (cell.row>2)&&(cell.column>2)
|
87
|
+
cell.add_search_path(:NW)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
class Game
|
94
|
+
#This class initialized instances of all the other classes, contains the main game loop, and handles IO.
|
95
|
+
attr_accessor :player1,:player2, :current_player, :other_player, :board
|
96
|
+
|
97
|
+
def initialize
|
98
|
+
@board = Board.new #initialize the board, along with all the cells
|
99
|
+
@player1 = Player.new #initialize player 1
|
100
|
+
@player2 = Player.new #initialize player 2
|
101
|
+
@current_player = who_goes_first #this var will keep track of whose turn it is.
|
102
|
+
@other_player = other_player
|
103
|
+
@moves_remaining = 42 #counts down the number of moves remaining
|
104
|
+
@game_over = false #
|
105
|
+
@winner = nil
|
106
|
+
end
|
107
|
+
|
108
|
+
def set_player_symbols
|
109
|
+
@player1.symbol = rand>0.5 ? "X".red : "O".blue #randomly assigns player 1 red X's or blue O's as their symbol
|
110
|
+
@player2.symbol = (@player1.symbol == "X".red) ? "O".blue : "X".red #assigns player 2 the other symbol.
|
111
|
+
end
|
112
|
+
|
113
|
+
def who_goes_first
|
114
|
+
rand>0.5 ? @player1 : @player2 #randomly decides who will go first
|
115
|
+
end
|
116
|
+
|
117
|
+
def other_player
|
118
|
+
@current_player==@player1 ? @player2 : @player1
|
119
|
+
end
|
120
|
+
|
121
|
+
def switch_current_player
|
122
|
+
buffer = @current_player
|
123
|
+
@current_player = @other_player
|
124
|
+
@other_player = buffer
|
125
|
+
end
|
126
|
+
|
127
|
+
def state(a1)
|
128
|
+
@board.cell(a1).state
|
129
|
+
end
|
130
|
+
|
131
|
+
def game_setup
|
132
|
+
puts <<-eos
|
133
|
+
|
134
|
+
WELCOME TO RUBY CONNECT FOUR
|
135
|
+
|
136
|
+
|
137
|
+
eos
|
138
|
+
|
139
|
+
print "\nPlayer 1, please enter your name: "
|
140
|
+
@player1.name = gets.chomp
|
141
|
+
print "\n\nPlayer 2, please enter your name: "
|
142
|
+
@player2.name = gets.chomp
|
143
|
+
|
144
|
+
set_player_symbols #randomly sets their symbols
|
145
|
+
|
146
|
+
puts <<-eos
|
147
|
+
|
148
|
+
By luck of the draw, #{@current_player.name} will go first, and their symbol is #{@current_player.symbol}.
|
149
|
+
#{@other_player.name} will go second, and their symbol is #{@other_player.symbol}.
|
150
|
+
|
151
|
+
eos
|
152
|
+
end
|
153
|
+
|
154
|
+
def show_board #prints a heredoc showing the board.
|
155
|
+
puts <<-eos
|
156
|
+
===============================
|
157
|
+
|| #{state("A1")} | #{state("A2")} | #{state("A3")} | #{state("A4")} | #{state("A5")} | #{state("A6")} | #{state("A7")} ||
|
158
|
+
-------------------------------
|
159
|
+
|| #{state("B1")} | #{state("B2")} | #{state("B3")} | #{state("B4")} | #{state("B5")} | #{state("B6")} | #{state("B7")} ||
|
160
|
+
-------------------------------
|
161
|
+
|| #{state("C1")} | #{state("C2")} | #{state("C3")} | #{state("C4")} | #{state("C5")} | #{state("C6")} | #{state("C7")} ||
|
162
|
+
-------------------------------
|
163
|
+
|| #{state("D1")} | #{state("D2")} | #{state("D3")} | #{state("D4")} | #{state("D5")} | #{state("D6")} | #{state("D7")} ||
|
164
|
+
-------------------------------
|
165
|
+
|| #{state("E1")} | #{state("E2")} | #{state("E3")} | #{state("E4")} | #{state("E5")} | #{state("E6")} | #{state("E7")} ||
|
166
|
+
-------------------------------
|
167
|
+
|| #{state("F1")} | #{state("F2")} | #{state("F3")} | #{state("F4")} | #{state("F5")} | #{state("F6")} | #{state("F7")} ||
|
168
|
+
===============================
|
169
|
+
1 2 3 4 5 6 7
|
170
|
+
eos
|
171
|
+
end
|
172
|
+
|
173
|
+
def buffer_space
|
174
|
+
puts "\n\n\n\n"
|
175
|
+
end
|
176
|
+
|
177
|
+
def turn
|
178
|
+
#the procedure every turn
|
179
|
+
print "It is #{@current_player.name}'s turn. Make your move by entering the desired column number: "
|
180
|
+
input = gets.chomp.to_i #get the move as a string
|
181
|
+
validate_turn(input)
|
182
|
+
check_for_winner
|
183
|
+
switch_current_player
|
184
|
+
end
|
185
|
+
|
186
|
+
def validate_turn(column) #checks to see if the move is in bounds and on a vacant cell. If not, asks for another.
|
187
|
+
if (1..7).member?(column)
|
188
|
+
for i in 0..5
|
189
|
+
if (i==5)&&(@board.cell(0,column-1).state!=" ")
|
190
|
+
print "Oops, that column is full! Pick a different column: "
|
191
|
+
input = gets.chomp.to_i
|
192
|
+
validate_turn(input)
|
193
|
+
elsif @board.cell(5-i,column-1).state == " "
|
194
|
+
@board.cell(5-i,column-1).state = @current_player.symbol #places their symbol in that cell
|
195
|
+
@current_player.add_move(@board.cell(5-i,column-1)) #adds that cell into their moves array
|
196
|
+
break
|
197
|
+
else
|
198
|
+
end
|
199
|
+
end
|
200
|
+
else
|
201
|
+
print "Uh-oh! Please enter a valid column number:"
|
202
|
+
input = gets.chomp.to_i
|
203
|
+
validate_turn(input)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def check_for_winner
|
208
|
+
#For each cell in current player's moves array (i.e. the cells on which they've made moves),
|
209
|
+
#perform searches on each search path in that cell's list of valid search_paths.
|
210
|
+
@current_player.moves.each do |move|
|
211
|
+
#perform searches on each search_path
|
212
|
+
move.search_paths.each do |path|
|
213
|
+
#initiate a counter at 1. Travel along the given search path and increment the counter if the next cell
|
214
|
+
#in the path is in that player's moves array.
|
215
|
+
counter = 1
|
216
|
+
for i in 1..3
|
217
|
+
if @current_player.moves.any?{|x| x==@board.offset(move,
|
218
|
+
i*(@board.path_coords[path][0]),
|
219
|
+
i*(@board.path_coords[path][1]))}
|
220
|
+
counter+=1
|
221
|
+
else
|
222
|
+
end
|
223
|
+
if counter==4
|
224
|
+
@game_over = true
|
225
|
+
@winner = @current_player
|
226
|
+
break
|
227
|
+
else
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
#check for a draw
|
234
|
+
if (@game_over==false) && (@player1.moves.length+@player2.moves.length==42)
|
235
|
+
@game_over = true
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def play
|
240
|
+
buffer_space #put blank space at the start
|
241
|
+
game_setup
|
242
|
+
until @game_over #main game loop, continues until the board reports a winner, which it checks for after every move.
|
243
|
+
show_board
|
244
|
+
turn
|
245
|
+
buffer_space
|
246
|
+
end
|
247
|
+
show_board
|
248
|
+
if @winner==nil
|
249
|
+
puts "The game is a draw!"
|
250
|
+
else
|
251
|
+
puts "Congratulations! #{@winner.name} is the winner. Bye bye!"
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
class Player
|
257
|
+
attr_accessor :symbol, :name, :color, :moves
|
258
|
+
#we're going to be passing @moves to the board object to check for a winner, so it should be able to
|
259
|
+
#read the moves.
|
260
|
+
|
261
|
+
def initialize
|
262
|
+
@symbol = nil
|
263
|
+
@name = nil
|
264
|
+
@moves = []
|
265
|
+
end
|
266
|
+
|
267
|
+
def add_move(cell) #adds a cell object to player's moves array
|
268
|
+
@moves << cell
|
269
|
+
end
|
270
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "ConnectFour" do
|
4
|
+
before :each do
|
5
|
+
@game = Game.new
|
6
|
+
@game.player1.name = "Me"
|
7
|
+
@game.player2.name = "You"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "Should feature a Game object" do
|
11
|
+
@game.kind_of?(Game).should be_true
|
12
|
+
end
|
13
|
+
|
14
|
+
it "Should randomly decide who goes first" do
|
15
|
+
@game.who_goes_first
|
16
|
+
[@game.player1,@game.player2].should include @game.current_player
|
17
|
+
end
|
18
|
+
|
19
|
+
it "Should go to the next player's turn when told to" do
|
20
|
+
@game.current_player = @game.player1
|
21
|
+
@game.other_player = @game.player2
|
22
|
+
@game.switch_current_player
|
23
|
+
@game.current_player.should eq @game.player2
|
24
|
+
@game.other_player.should eq @game.player1
|
25
|
+
end
|
26
|
+
|
27
|
+
it "Should properly assign search paths to the cells on the board" do
|
28
|
+
@game.board.grid[5][0].search_paths.should_not include :S
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'connect_four'
|
5
|
+
|
6
|
+
# Requires supporting files with custom matchers and macros, etc,
|
7
|
+
# in ./support/ and its subdirectories.
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: connect_four
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Price Hardman
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-11 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: colorize
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 2.8.0
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.8.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: bundler
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: jeweler
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.8.4
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.8.4
|
78
|
+
description: The connect_four.rb file contains classes for an object-oriented connect
|
79
|
+
four game, designed to be played between two human players on the command line.
|
80
|
+
Colored player symbols courtesy of the colorize gem. Play by creating an instance
|
81
|
+
of Game and calling the play method on it.
|
82
|
+
email: PriceHardman@gmail.com
|
83
|
+
executables: []
|
84
|
+
extensions: []
|
85
|
+
extra_rdoc_files:
|
86
|
+
- LICENSE.txt
|
87
|
+
- README.rdoc
|
88
|
+
files:
|
89
|
+
- .document
|
90
|
+
- .rspec
|
91
|
+
- .travis.yml
|
92
|
+
- Gemfile
|
93
|
+
- Gemfile.lock
|
94
|
+
- LICENSE.txt
|
95
|
+
- README.rdoc
|
96
|
+
- Rakefile
|
97
|
+
- VERSION
|
98
|
+
- connect_four.gemspec
|
99
|
+
- lib/connect_four.rb
|
100
|
+
- lib/play_connect_four.rb
|
101
|
+
- spec/connect_four_spec.rb
|
102
|
+
- spec/spec_helper.rb
|
103
|
+
homepage: http://github.com/PriceHardman/connect_four
|
104
|
+
licenses:
|
105
|
+
- MIT
|
106
|
+
post_install_message:
|
107
|
+
rdoc_options: []
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
none: false
|
112
|
+
requirements:
|
113
|
+
- - ! '>='
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
segments:
|
117
|
+
- 0
|
118
|
+
hash: -224533651
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
none: false
|
121
|
+
requirements:
|
122
|
+
- - ! '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
requirements: []
|
126
|
+
rubyforge_project:
|
127
|
+
rubygems_version: 1.8.24
|
128
|
+
signing_key:
|
129
|
+
specification_version: 3
|
130
|
+
summary: Play connect four in the command line.
|
131
|
+
test_files: []
|