bridge 0.0.26 → 0.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.
- data/Gemfile +1 -1
- data/README.rdoc +10 -0
- data/bridge.gemspec +3 -3
- data/lib/bridge.rb +3 -52
- data/lib/bridge/constants.rb +109 -0
- data/lib/bridge/imp.rb +40 -0
- data/lib/bridge/score.rb +1 -4
- data/lib/bridge/version.rb +1 -1
- data/test/test_imp.rb +39 -0
- metadata +8 -7
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
@@ -35,6 +35,16 @@ You can use regexp to check if contract with result is valid:
|
|
35
35
|
will match i.e.
|
36
36
|
"1NT=", "2SX+1", "6NTXX-2"
|
37
37
|
|
38
|
+
== Imp
|
39
|
+
|
40
|
+
You can calculate how many IMP points you won by:
|
41
|
+
Bridge::Imp.new(:hcp => 25, :points => 420, :vulnerable => false).imps
|
42
|
+
|
43
|
+
Arguments:
|
44
|
+
* :hcp -- Integer (range between 20 and 40), which means how many honour card points has side
|
45
|
+
* :vulnerable -- Boolean, side with given hcp is vulnerable?
|
46
|
+
* :points -- Integer, the result at the end of board (can be calculated by Bridge::Score)
|
47
|
+
|
38
48
|
== Note on Patches/Pull Requests
|
39
49
|
|
40
50
|
* Fork the project.
|
data/bridge.gemspec
CHANGED
@@ -15,9 +15,9 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.required_rubygems_version = ">= 1.3.6"
|
16
16
|
s.rubyforge_project = "bridge"
|
17
17
|
|
18
|
-
s.add_development_dependency "bundler", ">= 1.0.0
|
18
|
+
s.add_development_dependency "bundler", ">= 1.0.0"
|
19
19
|
|
20
20
|
s.files = `git ls-files`.split("\n")
|
21
|
-
s.executables = `git ls-files`.split("\n").
|
22
|
-
s.require_path =
|
21
|
+
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
22
|
+
s.require_path = 'lib'
|
23
23
|
end
|
data/lib/bridge.rb
CHANGED
@@ -1,68 +1,19 @@
|
|
1
1
|
require "bridge/bid"
|
2
2
|
require "bridge/card"
|
3
|
+
require "bridge/constants"
|
3
4
|
require "bridge/deal"
|
5
|
+
require "bridge/imp"
|
4
6
|
require "bridge/score"
|
5
7
|
require "bridge/trick"
|
6
8
|
require "bridge/version"
|
7
9
|
|
8
10
|
module Bridge
|
9
|
-
# Number of possible deals in bridge
|
10
|
-
DEALS = 53_644_737_765_488_792_839_237_440_000
|
11
|
-
|
12
|
-
# Card values - from A to 2
|
13
|
-
CARD_VALUES = %w(A K Q J T 9 8 7 6 5 4 3 2)
|
14
|
-
|
15
|
-
MAJORS = %w(S H)
|
16
|
-
|
17
|
-
MINORS = %w(D C)
|
18
|
-
|
19
|
-
# Trumps
|
20
|
-
TRUMPS = MAJORS + MINORS
|
21
|
-
|
22
|
-
# No trump string
|
23
|
-
NO_TRUMP = "NT"
|
24
|
-
|
25
|
-
# Array with card strings in the bridge deck (AKQJT98765432, four
|
26
|
-
# suits). Contains "SA", "HT", etc.
|
27
|
-
DECK = TRUMPS.inject([]) do |d, s|
|
28
|
-
d += CARD_VALUES.map { |c| s + c }
|
29
|
-
end
|
30
|
-
|
31
|
-
# Direction strings "N", "E", "S" and "W"
|
32
|
-
DIRECTIONS = %w(N E S W)
|
33
|
-
|
34
|
-
# Possible contracts in ascending order. Contains "1C", "6NT", etc.
|
35
|
-
CONTRACTS = %w(1 2 3 4 5 6 7).inject([]) do |b, l|
|
36
|
-
b += (TRUMPS.reverse + [NO_TRUMP]).map { |s| l + s }
|
37
|
-
end
|
38
|
-
|
39
|
-
# Pass string
|
40
|
-
PASS = "PASS"
|
41
|
-
|
42
|
-
# Double string
|
43
|
-
DOUBLE = "X"
|
44
|
-
|
45
|
-
# Redouble string
|
46
|
-
REDOUBLE = "XX"
|
47
|
-
|
48
|
-
# Modifier bids (double and redouble)
|
49
|
-
MODIFIERS = [DOUBLE, REDOUBLE]
|
50
|
-
|
51
|
-
# All possible bids (including contracts, modifiers and pass)
|
52
|
-
BIDS = CONTRACTS + MODIFIERS + [PASS]
|
53
|
-
|
54
|
-
# 2 sides
|
55
|
-
SIDES = %w{NS EW}
|
56
|
-
|
57
|
-
# All possible vullnerabilites
|
58
|
-
VULNERABILITIES = ["NONE", SIDES, "BOTH"].flatten
|
59
|
-
|
60
11
|
def self.direction?(string)
|
61
12
|
DIRECTIONS.include?(string)
|
62
13
|
end
|
63
14
|
|
64
15
|
def self.deal_id?(integer)
|
65
|
-
(0
|
16
|
+
(0...DEALS).include?(integer)
|
66
17
|
end
|
67
18
|
|
68
19
|
def self.card?(string)
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module Bridge
|
2
|
+
# Number of possible deals in bridge
|
3
|
+
DEALS = 53_644_737_765_488_792_839_237_440_000
|
4
|
+
|
5
|
+
# Card values - from A to 2
|
6
|
+
CARD_VALUES = %w(A K Q J T 9 8 7 6 5 4 3 2)
|
7
|
+
|
8
|
+
MAJORS = %w(S H)
|
9
|
+
|
10
|
+
MINORS = %w(D C)
|
11
|
+
|
12
|
+
# Trumps
|
13
|
+
TRUMPS = MAJORS + MINORS
|
14
|
+
|
15
|
+
# No trump string
|
16
|
+
NO_TRUMP = "NT"
|
17
|
+
|
18
|
+
# Array with card strings in the bridge deck (AKQJT98765432, four
|
19
|
+
# suits). Contains "SA", "HT", etc.
|
20
|
+
DECK = TRUMPS.map do |suit|
|
21
|
+
CARD_VALUES.map { |card| suit + card }
|
22
|
+
end.flatten
|
23
|
+
|
24
|
+
# Direction strings "N", "E", "S" and "W"
|
25
|
+
DIRECTIONS = %w(N E S W)
|
26
|
+
|
27
|
+
# Possible contracts in ascending order. Contains "1C", "6NT", etc.
|
28
|
+
CONTRACTS = %w(1 2 3 4 5 6 7).map do |level|
|
29
|
+
(TRUMPS.reverse + [NO_TRUMP]).map { |suit| level + suit }
|
30
|
+
end.flatten
|
31
|
+
|
32
|
+
# Pass string
|
33
|
+
PASS = "PASS"
|
34
|
+
|
35
|
+
# Double string
|
36
|
+
DOUBLE = "X"
|
37
|
+
|
38
|
+
# Redouble string
|
39
|
+
REDOUBLE = "XX"
|
40
|
+
|
41
|
+
# Modifier bids (double and redouble)
|
42
|
+
MODIFIERS = [DOUBLE, REDOUBLE]
|
43
|
+
|
44
|
+
# All possible bids (including contracts, modifiers and pass)
|
45
|
+
BIDS = CONTRACTS + MODIFIERS + [PASS]
|
46
|
+
|
47
|
+
# 2 sides
|
48
|
+
SIDES = %w{NS EW}
|
49
|
+
|
50
|
+
# All possible vullnerabilites
|
51
|
+
VULNERABILITIES = ["NONE", SIDES, "BOTH"].flatten
|
52
|
+
|
53
|
+
class Imp
|
54
|
+
# values in array: [not-vulnerable, vulnerable]
|
55
|
+
POINTS =
|
56
|
+
{
|
57
|
+
"20" => [0, 0],
|
58
|
+
"21" => [50, 50],
|
59
|
+
"22" => [70, 70],
|
60
|
+
"23" => [110, 110],
|
61
|
+
"24" => [200, 290],
|
62
|
+
"25" => [300, 440],
|
63
|
+
"26" => [350, 520],
|
64
|
+
"27" => [400, 600],
|
65
|
+
"28" => [430, 630],
|
66
|
+
"29" => [460, 660],
|
67
|
+
"30" => [490, 690],
|
68
|
+
"31" => [600, 900],
|
69
|
+
"32" => [700, 1050],
|
70
|
+
"33" => [900, 1350],
|
71
|
+
"34" => [1000, 1500],
|
72
|
+
"35" => [1100, 1650],
|
73
|
+
"36" => [1200, 1800],
|
74
|
+
"37" => [1300, 1950],
|
75
|
+
"38" => [1300, 1950],
|
76
|
+
"39" => [1300, 1950],
|
77
|
+
"40" => [1300, 1950]
|
78
|
+
}
|
79
|
+
|
80
|
+
IMPS =
|
81
|
+
{
|
82
|
+
"0...10" => 0,
|
83
|
+
"20...40" => 1,
|
84
|
+
"50...80" => 2,
|
85
|
+
"90...120" => 3,
|
86
|
+
"130...160" => 4,
|
87
|
+
"170...210" => 5,
|
88
|
+
"220...260" => 6,
|
89
|
+
"270...310" => 7,
|
90
|
+
"320...360" => 8,
|
91
|
+
"370...420" => 9,
|
92
|
+
"430...490" => 10,
|
93
|
+
"500...590" => 11,
|
94
|
+
"600...740" => 12,
|
95
|
+
"750...890" => 13,
|
96
|
+
"900...1090" => 14,
|
97
|
+
"1100...1290" => 15,
|
98
|
+
"1300...1490" => 16,
|
99
|
+
"1500...1740" => 17,
|
100
|
+
"1750...1990" => 18,
|
101
|
+
"2000...2240" => 19,
|
102
|
+
"2250...2490" => 20,
|
103
|
+
"2500...2990" => 21,
|
104
|
+
"3000...3490" => 22,
|
105
|
+
"3500...3990" => 23,
|
106
|
+
"4000...7600" => 24
|
107
|
+
}
|
108
|
+
end
|
109
|
+
end
|
data/lib/bridge/imp.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
module Bridge
|
2
|
+
class Imp
|
3
|
+
attr_reader :hcp, :points, :vulnerable
|
4
|
+
alias :vulnerable? :vulnerable
|
5
|
+
|
6
|
+
# Creates new Imp object
|
7
|
+
#
|
8
|
+
# ==== Example
|
9
|
+
# Bridge::Imp.new(:hcp => 25, :points => 420, :vulnerable => true)
|
10
|
+
def initialize(options = {})
|
11
|
+
@hcp = options[:hcp]
|
12
|
+
raise ArgumentError, "Invalid hcp: #{hcp} - value should be between 20 and 40" unless (20..40).include?(hcp)
|
13
|
+
@points = options[:points]
|
14
|
+
@vulnerable = options[:vulnerable] || false
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns points that side should make with given hcp
|
18
|
+
def points_to_make
|
19
|
+
POINTS[hcp.to_s][vulnerable? ? 1 : 0]
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns points score relative to hcp
|
23
|
+
def points_difference
|
24
|
+
points - points_to_make
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns imps (negative or positive) based on given points
|
28
|
+
def imps
|
29
|
+
IMPS.each do |range, imps|
|
30
|
+
return (imps * sign) if eval(range).include?(points_difference.abs)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def sign
|
37
|
+
points >= 0 ? 1 : -1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/bridge/score.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Bridge
|
2
2
|
class Score
|
3
3
|
attr_reader :tricks, :contract, :vulnerable
|
4
|
+
alias :vulnerable? :vulnerable
|
4
5
|
|
5
6
|
# Checks contract with result, i.e. "1NTX-1", "2S=", "6SXX+1"
|
6
7
|
# on Ruby >= 1.9 there are named groups :contract and :result
|
@@ -56,10 +57,6 @@ module Bridge
|
|
56
57
|
|
57
58
|
# private
|
58
59
|
|
59
|
-
def vulnerable?
|
60
|
-
@vulnerable == true
|
61
|
-
end
|
62
|
-
|
63
60
|
def tricks_to_make_contract
|
64
61
|
contract.level.to_i + 6
|
65
62
|
end
|
data/lib/bridge/version.rb
CHANGED
data/test/test_imp.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
class TestImp < Test::Unit::TestCase
|
4
|
+
test "raises ArgumentError when invalid honour card points provided" do
|
5
|
+
assert_raises(ArgumentError) do
|
6
|
+
Bridge::Imp.new(:hcp => 15, :points => 100)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
test "set default vulnerable to false" do
|
11
|
+
imp = Bridge::Imp.new(:hcp => 40, :points => -100)
|
12
|
+
assert_false imp.vulnerable
|
13
|
+
end
|
14
|
+
|
15
|
+
test "return vulnerable boolean" do
|
16
|
+
imp = Bridge::Imp.new(:hcp => 20, :points => 100, :vulnerable => true)
|
17
|
+
assert imp.vulnerable?
|
18
|
+
end
|
19
|
+
|
20
|
+
test "return points to make when vulnerable" do
|
21
|
+
imp = Bridge::Imp.new(:hcp => 23, :points => 100, :vulnerable => true)
|
22
|
+
assert_equal 110, imp.points_to_make
|
23
|
+
end
|
24
|
+
|
25
|
+
test "return points to make when not vulnerable" do
|
26
|
+
imp = Bridge::Imp.new(:hcp => 23, :points => 100, :vulnerable => false)
|
27
|
+
assert_equal 110, imp.points_to_make
|
28
|
+
end
|
29
|
+
|
30
|
+
test "return positive imps" do
|
31
|
+
imp = Bridge::Imp.new(:hcp => 21, :points => 100)
|
32
|
+
assert_equal 2, imp.imps
|
33
|
+
end
|
34
|
+
|
35
|
+
test "return negative imps" do
|
36
|
+
imp = Bridge::Imp.new(:hcp => 21, :points => -100)
|
37
|
+
assert_equal -4, imp.imps
|
38
|
+
end
|
39
|
+
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
+
- 1
|
7
8
|
- 0
|
8
|
-
|
9
|
-
version: 0.0.26
|
9
|
+
version: 0.1.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- "Jakub Ku\xC5\xBAma"
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-09-13 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -29,9 +29,7 @@ dependencies:
|
|
29
29
|
- 1
|
30
30
|
- 0
|
31
31
|
- 0
|
32
|
-
|
33
|
-
- 5
|
34
|
-
version: 1.0.0.rc.5
|
32
|
+
version: 1.0.0
|
35
33
|
type: :development
|
36
34
|
prerelease: false
|
37
35
|
version_requirements: *id001
|
@@ -54,7 +52,9 @@ files:
|
|
54
52
|
- lib/bridge.rb
|
55
53
|
- lib/bridge/bid.rb
|
56
54
|
- lib/bridge/card.rb
|
55
|
+
- lib/bridge/constants.rb
|
57
56
|
- lib/bridge/deal.rb
|
57
|
+
- lib/bridge/imp.rb
|
58
58
|
- lib/bridge/score.rb
|
59
59
|
- lib/bridge/trick.rb
|
60
60
|
- lib/bridge/version.rb
|
@@ -63,6 +63,7 @@ files:
|
|
63
63
|
- test/test_bridge.rb
|
64
64
|
- test/test_card.rb
|
65
65
|
- test/test_deal.rb
|
66
|
+
- test/test_imp.rb
|
66
67
|
- test/test_score.rb
|
67
68
|
- test/test_trick.rb
|
68
69
|
has_rdoc: true
|
@@ -79,7 +80,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
79
80
|
requirements:
|
80
81
|
- - ">="
|
81
82
|
- !ruby/object:Gem::Version
|
82
|
-
hash:
|
83
|
+
hash: 2761440476130499620
|
83
84
|
segments:
|
84
85
|
- 0
|
85
86
|
version: "0"
|