connect_n_game 0.0.1
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/.gitignore +21 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +74 -0
- data/Rakefile +48 -0
- data/bin/connect_n_game +16 -0
- data/connect_n_game.gemspec +26 -0
- data/lib/cli/cli.rb +72 -0
- data/lib/cli/cli_debug.rb +20 -0
- data/lib/cli/cli_human.rb +41 -0
- data/lib/cli/cli_rack.rb +30 -0
- data/lib/cli/process_options.rb +62 -0
- data/lib/cli/select_players.rb +54 -0
- data/lib/connect_n_game.rb +13 -0
- data/lib/connect_n_game/exceptions.rb +8 -0
- data/lib/connect_n_game/game.rb +93 -0
- data/lib/connect_n_game/game/rack.rb +180 -0
- data/lib/connect_n_game/human.rb +30 -0
- data/lib/connect_n_game/player.rb +70 -0
- data/lib/connect_n_game/players/basic.rb +39 -0
- data/lib/connect_n_game/players/echo.rb +45 -0
- data/lib/connect_n_game/players/just_random.rb +40 -0
- data/lib/connect_n_game/players/middle.rb +41 -0
- data/lib/connect_n_game/players/prudent.rb +67 -0
- data/lib/connect_n_game/ui.rb +9 -0
- data/lib/connect_n_game/util.rb +26 -0
- data/lib/connect_n_game/version.rb +5 -0
- data/tests/test_game.rb +53 -0
- data/tests/test_module.rb +20 -0
- data/tests/test_player.rb +55 -0
- data/tests/test_rack.rb +222 -0
- data/tests/test_ui.rb +15 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d8c22e80821cd3f7868d2fb55e1382c2fcdb8f64
|
4
|
+
data.tar.gz: 1e71e994e2930b55160aef91e9f637df6675f24b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4131de533d207ecc4e94f88d7a9c33139ea5f0e272adf202222b5f0a25f19b034cf68cb24c00a90ccfe375a7f5166eafad79fba38851e54c01a9df76a57dc69e
|
7
|
+
data.tar.gz: 01ddd823edb705af2593621f6da26dce0d9bf7abbc55f40653f197d46303890923e6e0a45f1f85c4c43d8058a47735497db7ebcb102960dca09ade448c62da0a
|
data/.gitignore
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
*.bat
|
2
|
+
*.zip
|
3
|
+
*.tmp
|
4
|
+
*.gem
|
5
|
+
*.rbc
|
6
|
+
.bundle
|
7
|
+
.config
|
8
|
+
.yardoc
|
9
|
+
Gemfile.lock
|
10
|
+
InstalledFiles
|
11
|
+
_yardoc
|
12
|
+
coverage
|
13
|
+
docs/.~lock.*
|
14
|
+
lib/bundler/man
|
15
|
+
pkg
|
16
|
+
rdoc
|
17
|
+
spec/reports
|
18
|
+
test/tmp
|
19
|
+
test/version_tmp
|
20
|
+
tmp
|
21
|
+
temp.txt
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Peter Camilleri
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# ConnectNGame
|
2
|
+
|
3
|
+
This gem is a connect game with flexible board sizes. The classical game is
|
4
|
+
a seven by six playing rack with a goal of four in a row. This game supports
|
5
|
+
up to 14 by 12 rack with a goal of eight in a row.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'connect_n_game'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install connect_n_game
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
From the command line simply type:
|
26
|
+
|
27
|
+
$ connect_n_game [options]
|
28
|
+
|
29
|
+
To embed the game in another program use:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
require 'connect_n_game'
|
33
|
+
```
|
34
|
+
|
35
|
+
and then {W.I.P.}
|
36
|
+
|
37
|
+
### Options
|
38
|
+
|
39
|
+
To get help simply enter:
|
40
|
+
|
41
|
+
$ connect_n_game --help
|
42
|
+
|
43
|
+
The available options are:
|
44
|
+
|
45
|
+
```
|
46
|
+
Welcome to the Connect N Command Line Interface.
|
47
|
+
This is game version: 0.0.1.
|
48
|
+
|
49
|
+
Usage info: connect_n_game <options>
|
50
|
+
|
51
|
+
--help, -h, -? -- Display this message and quit.
|
52
|
+
--player, -p <name> -- Select player or automaton 'name'
|
53
|
+
Note: Limit of two players
|
54
|
+
--order, -o <4..8> -- The winning run length. Default=4
|
55
|
+
--debug, -d -- Display debug info.
|
56
|
+
|
57
|
+
Player Selection:
|
58
|
+
Basic Minimum tactical analysis.
|
59
|
+
Bruce An actual player.
|
60
|
+
Echo Really unoriginal.
|
61
|
+
Human An actual player.
|
62
|
+
Middle Moves toward the middle
|
63
|
+
Prudent Minimum tactical analysis with some defense.
|
64
|
+
Random Moves randomly.
|
65
|
+
Sheila An actual player.
|
66
|
+
```
|
67
|
+
|
68
|
+
## Contributing
|
69
|
+
|
70
|
+
1. Fork it ( https://github.com/PeterCamilleri/connect_n_game/fork )
|
71
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
72
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
73
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
74
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rdoc/task'
|
6
|
+
|
7
|
+
require "bundler/gem_tasks"
|
8
|
+
|
9
|
+
#Generate internal documentation with rdoc.
|
10
|
+
RDoc::Task.new do |rdoc|
|
11
|
+
rdoc.rdoc_dir = "rdoc"
|
12
|
+
|
13
|
+
#List out all the files to be documented.
|
14
|
+
rdoc.rdoc_files.include("lib/**/*.rb", "license.txt", "README.md")
|
15
|
+
|
16
|
+
#Make all access levels visible.
|
17
|
+
rdoc.options << '--visibility' << 'private'
|
18
|
+
#rdoc.options << '--verbose'
|
19
|
+
#rdoc.options << '--coverage-report'
|
20
|
+
|
21
|
+
#Set a title.
|
22
|
+
rdoc.options << '--title' << 'fOOrth Language Internals'
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
#Run the fOOrth unit test suite.
|
27
|
+
Rake::TestTask.new do |t|
|
28
|
+
#List out all the test files.
|
29
|
+
t.test_files = FileList['tests/**/*.rb']
|
30
|
+
t.verbose = false
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Fire up an IRB session with the game preloaded."
|
34
|
+
task :console do
|
35
|
+
require 'irb'
|
36
|
+
require 'irb/completion'
|
37
|
+
require './lib/connect_n_game'
|
38
|
+
puts "Starting an IRB console for connect_n_game."
|
39
|
+
ARGV.clear
|
40
|
+
IRB.start
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "What version of the connect_n_game is this?"
|
44
|
+
task :vers do |t|
|
45
|
+
puts
|
46
|
+
puts "connect_n_game version = #{ConnectNGame::VERSION}"
|
47
|
+
end
|
48
|
+
|
data/bin/connect_n_game
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
#Run the Connect N Game from the command line.
|
5
|
+
|
6
|
+
unless defined?(ConnectNGame)
|
7
|
+
begin
|
8
|
+
require 'connect_n_game'
|
9
|
+
rescue LoadError
|
10
|
+
require_relative '../lib/connect_n_game'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
require_relative '../lib/cli/cli'
|
15
|
+
|
16
|
+
ConnectNGame::CLI.new.main
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'connect_n_game/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "connect_n_game"
|
8
|
+
spec.version = ConnectNGame::VERSION
|
9
|
+
spec.authors = ["Peter Camilleri"]
|
10
|
+
spec.email = ["peter.c.camilleri@gmail.com"]
|
11
|
+
spec.summary = "The Connect 4 (or more) Game gem."
|
12
|
+
spec.description = "The Captain's Mistress Game Generalized for 4 to 8 pieces."
|
13
|
+
spec.homepage = "http://teuthida-technologies.com/"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency 'minitest', "~> 5.5.1"
|
24
|
+
spec.add_development_dependency 'rdoc', "~> 4.0.1"
|
25
|
+
|
26
|
+
end
|
data/lib/cli/cli.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#The command line interface for the connect_n_game.
|
3
|
+
|
4
|
+
require_relative 'process_options'
|
5
|
+
require_relative 'select_players'
|
6
|
+
require_relative 'cli_debug'
|
7
|
+
|
8
|
+
#Monkey patching the CLI UI into the game.
|
9
|
+
require_relative 'cli_rack'
|
10
|
+
require_relative 'cli_human'
|
11
|
+
|
12
|
+
module ConnectNGame
|
13
|
+
|
14
|
+
#The Connect N Command Line Interface class.
|
15
|
+
class CLI
|
16
|
+
|
17
|
+
#Set up the command line interface
|
18
|
+
def initialize
|
19
|
+
@players = []
|
20
|
+
@order = 4
|
21
|
+
end
|
22
|
+
|
23
|
+
#The starting point for an interactive, command-line-driven session
|
24
|
+
#of the Connect N Game!
|
25
|
+
def main
|
26
|
+
welcome
|
27
|
+
process_cmd_line
|
28
|
+
top_up_players
|
29
|
+
|
30
|
+
play_game
|
31
|
+
|
32
|
+
rescue Interrupt
|
33
|
+
puts
|
34
|
+
end
|
35
|
+
|
36
|
+
#Play the game
|
37
|
+
def play_game
|
38
|
+
@game = Game.new(@players[0], @players[1], @order)
|
39
|
+
@game.game_initialize
|
40
|
+
|
41
|
+
begin
|
42
|
+
current = @game.current
|
43
|
+
puts
|
44
|
+
result = @game.next_move
|
45
|
+
puts "On turn ##{@game.turn}, " +
|
46
|
+
"player #{current} " +
|
47
|
+
"plays channel #{Utl.channel_to_name(@game.last_move)}."
|
48
|
+
@game.rack.cli_display
|
49
|
+
end while result == :continue
|
50
|
+
|
51
|
+
if result == :victory
|
52
|
+
puts "Player #{@game.current}, #{@game.current_player.name} wins!"
|
53
|
+
puts
|
54
|
+
puts @game.current_player.winners_comments
|
55
|
+
puts @game.previous_player.losers_comments
|
56
|
+
elsif result == :stalemate
|
57
|
+
puts "No winner, it's a tie!"
|
58
|
+
else
|
59
|
+
puts "Result is #{result}"
|
60
|
+
end
|
61
|
+
|
62
|
+
puts
|
63
|
+
end
|
64
|
+
|
65
|
+
#The welcome message.
|
66
|
+
def welcome
|
67
|
+
puts "Welcome to the Connect N Command Line Interface."
|
68
|
+
puts "This is game version: #{VERSION}."
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#Some monkey patching for debugging.
|
4
|
+
class Array
|
5
|
+
|
6
|
+
#A debugging routine. Turned on by the --debug option.
|
7
|
+
def show_weights(msg = "")
|
8
|
+
if $game_debug
|
9
|
+
print msg.ljust(7)
|
10
|
+
self.each do |weight|
|
11
|
+
print " #{Utl.channel_to_name(weight[1])}#{"%5.2f" % weight[0]} "
|
12
|
+
end
|
13
|
+
|
14
|
+
puts
|
15
|
+
end
|
16
|
+
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#\CLI extensions to the \Human class.
|
3
|
+
|
4
|
+
module ConnectNGame
|
5
|
+
|
6
|
+
class Human < Player
|
7
|
+
|
8
|
+
#Make a move. This player moves with DNA and other stuff too.
|
9
|
+
#<br>Parameters
|
10
|
+
#* game - the game being played.
|
11
|
+
#* piece - the piece to be played, 1 or 2.
|
12
|
+
#<br>Returns
|
13
|
+
#* A move, 1 .. rack.width
|
14
|
+
def make_move(game, piece)
|
15
|
+
begin
|
16
|
+
legal = legal_moves(game.rack)
|
17
|
+
puts "Player #{piece} select [#{legal}] "
|
18
|
+
reply = gets[0].upcase
|
19
|
+
channel = Utl.name_to_channel(reply)
|
20
|
+
end until channel && legal.include?(reply)
|
21
|
+
|
22
|
+
channel
|
23
|
+
end
|
24
|
+
|
25
|
+
#Get a string of legal moves.
|
26
|
+
#<br>Parameters
|
27
|
+
#* rack - the playing area.
|
28
|
+
#<br>Returns
|
29
|
+
#* A string with all possible legal moves.
|
30
|
+
def legal_moves(rack)
|
31
|
+
legal = rack.channel_names.reject do |name|
|
32
|
+
channel = Utl.name_to_channel(name)
|
33
|
+
rack.channel_full?(channel)
|
34
|
+
end
|
35
|
+
|
36
|
+
legal.join("")
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/lib/cli/cli_rack.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#\CLI extensions to the \Rack class.
|
3
|
+
|
4
|
+
module ConnectNGame
|
5
|
+
|
6
|
+
#The output conversion hash
|
7
|
+
CLI_MAP = { nil => ' ', 1 => 'X', 2 => 'O'}
|
8
|
+
|
9
|
+
class Rack
|
10
|
+
|
11
|
+
#Display the rack via a command line interface.
|
12
|
+
def cli_display
|
13
|
+
#Show the title line.
|
14
|
+
puts " " + channel_names.join(" ")
|
15
|
+
|
16
|
+
#Show the body
|
17
|
+
(1..depth).reverse_each do |row|
|
18
|
+
(1..width).each do |channel|
|
19
|
+
print "|#{CLI_MAP[get_cell(channel,row)]}"
|
20
|
+
end
|
21
|
+
|
22
|
+
puts "|"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
puts
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# Handle any command line arguments.
|
3
|
+
|
4
|
+
require 'getoptlong'
|
5
|
+
|
6
|
+
module ConnectNGame
|
7
|
+
|
8
|
+
class CLI
|
9
|
+
|
10
|
+
#Handle any command line parameters.
|
11
|
+
def process_cmd_line
|
12
|
+
|
13
|
+
opts = GetoptLong.new(
|
14
|
+
[ "--help", "-h", "-?", GetoptLong::NO_ARGUMENT ],
|
15
|
+
[ "--player", "-p", GetoptLong::REQUIRED_ARGUMENT ],
|
16
|
+
[ "--order", "-o", GetoptLong::REQUIRED_ARGUMENT ],
|
17
|
+
[ "--debug", "-d", GetoptLong::NO_ARGUMENT ])
|
18
|
+
|
19
|
+
# Translate the parsed options into fOOrth.
|
20
|
+
opts.each do |opt, arg|
|
21
|
+
|
22
|
+
case opt
|
23
|
+
when "--player"
|
24
|
+
fail "Error: Too many players!" if @players.length >= 2
|
25
|
+
|
26
|
+
puts "Player ##{@players.length + 1} is #{arg}"
|
27
|
+
fail "Error: Unknown player: #{arg}" unless (player = find_player(arg))
|
28
|
+
@players << player
|
29
|
+
when "--order"
|
30
|
+
@order = arg.to_i
|
31
|
+
fail "Invalid order #{arg}" unless @order.between?(4,8)
|
32
|
+
when "--debug"
|
33
|
+
puts "Debug mode is enabled."
|
34
|
+
$game_debug = true
|
35
|
+
else
|
36
|
+
fail ""
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
rescue => err
|
41
|
+
puts err.message
|
42
|
+
show_help
|
43
|
+
exit
|
44
|
+
end
|
45
|
+
|
46
|
+
#Display the help message.
|
47
|
+
def show_help
|
48
|
+
puts
|
49
|
+
puts "Usage info: connect_n_game <options>"
|
50
|
+
puts
|
51
|
+
puts "--help, -h, -? -- Display this message and quit."
|
52
|
+
puts "--player, -p <name> -- Select player or automaton 'name'"
|
53
|
+
puts " Note: Limit of two players"
|
54
|
+
puts "--order, -o <4..8> -- The winning run length. Default=4"
|
55
|
+
puts "--debug, -d -- Display debug info."
|
56
|
+
|
57
|
+
show_players
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|