bridge 0.0.4 → 0.0.5

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.5
data/bridge.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{bridge}
8
- s.version = "0.0.4"
8
+ s.version = "0.0.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jakub Kuźma"]
12
- s.date = %q{2010-02-22}
12
+ s.date = %q{2010-02-23}
13
13
  s.description = %q{Useful contract bridge utilities - deal generator, id to deal and deal to id conversion}
14
14
  s.email = %q{qoobaa+github@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -25,8 +25,12 @@ Gem::Specification.new do |s|
25
25
  "VERSION",
26
26
  "bridge.gemspec",
27
27
  "lib/bridge.rb",
28
+ "lib/bridge/contract.rb",
29
+ "lib/bridge/deal.rb",
28
30
  "test/helper.rb",
29
- "test/test_bridge.rb"
31
+ "test/test_bridge.rb",
32
+ "test/test_contract.rb",
33
+ "test/test_deal.rb"
30
34
  ]
31
35
  s.homepage = %q{http://github.com/qoobaa/bridge}
32
36
  s.rdoc_options = ["--charset=UTF-8"]
@@ -34,8 +38,10 @@ Gem::Specification.new do |s|
34
38
  s.rubygems_version = %q{1.3.5}
35
39
  s.summary = %q{Contract bridge utilities}
36
40
  s.test_files = [
37
- "test/helper.rb",
38
- "test/test_bridge.rb"
41
+ "test/test_bridge.rb",
42
+ "test/test_deal.rb",
43
+ "test/helper.rb",
44
+ "test/test_contract.rb"
39
45
  ]
40
46
 
41
47
  if s.respond_to? :specification_version then
@@ -0,0 +1,23 @@
1
+ module Bridge
2
+ module Contract
3
+ def self.contracts_compare(first, second)
4
+ CONTRACTS.index(first) <=> CONTRACTS.index(second)
5
+ end
6
+
7
+ def self.contract?(contract)
8
+ CONTRACTS.include?(value)
9
+ end
10
+
11
+ def self.pass?(value)
12
+ value == PASS
13
+ end
14
+
15
+ def self.double?(value)
16
+ value == DOUBLE
17
+ end
18
+
19
+ def self.redouble?(value)
20
+ value == REDOUBLE
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,116 @@
1
+ module Bridge
2
+
3
+ # Class representing bridge deal
4
+ class Deal
5
+ include Comparable
6
+
7
+ attr_reader :n, :e, :s, :w
8
+
9
+ # Returns cards of given direction
10
+ def [](direction)
11
+ must_be_direction!(direction)
12
+ send("#{direction.to_s.downcase}")
13
+ end
14
+
15
+ # Compares the deal with given deal
16
+ def <=>(other)
17
+ id <=> other.id
18
+ end
19
+
20
+ # Creates new deal object with cards given in hash of directions
21
+ #
22
+ # ==== Example
23
+ # Bridge::Deal.new(:n => ["HA", ...], :s => ["SA"], ...)
24
+ def initialize(hands)
25
+ hands.each { |hand, cards| self[hand] = cards }
26
+ end
27
+
28
+ # Converts given id to deal
29
+ def self.from_id(id)
30
+ raise ArgumentError, "invalid deal id: #{id}" unless Bridge.deal_id?(id)
31
+ n = []; e = []; s = []; w = []; k = DEALS
32
+ DECK.each_with_index do |card, i|
33
+ x = k * (13 - n.size) / (52 - i)
34
+ if id < x
35
+ n << card
36
+ else
37
+ id -= x
38
+ x = k * (13 - e.size) / (52 - i)
39
+ if id < x
40
+ e << card
41
+ else
42
+ id -= x
43
+ x = k * (13 - s.size) / (52 - i)
44
+ if id < x
45
+ s << card
46
+ else
47
+ id -= x
48
+ x = k * (13 - w.size) / (52 - i)
49
+ w << card
50
+ end
51
+ end
52
+ end
53
+ k = x
54
+ end
55
+ new(:n => n, :e => e, :s => s, :w => w)
56
+ end
57
+
58
+ # Converts given deal (hash) to id
59
+ def id
60
+ k = DEALS; id = 0; n = self.n.dup; e = self.e.dup; s = self.s.dup; w = self.w.dup
61
+ DECK.each_with_index do |card, i|
62
+ x = k * n.size / (52 - i)
63
+ unless n.delete(card)
64
+ id += x
65
+ x = k * e.size / (52 - i)
66
+ unless e.delete(card)
67
+ id += x
68
+ x = k * s.size / (52 - i)
69
+ unless s.delete(card)
70
+ id += x
71
+ x = k * w.size / (52 - i)
72
+ w.delete(card)
73
+ end
74
+ end
75
+ end
76
+ k = x
77
+ end
78
+ id
79
+ end
80
+
81
+ # Returns a random deal id
82
+ def self.random_id
83
+ rand(DEALS)
84
+ end
85
+
86
+ # Returns a random deal
87
+ def self.random
88
+ from_id(random_id)
89
+ end
90
+
91
+ # Checks if the deal is a valid deal
92
+ def valid?
93
+ if DIRECTIONS.all? { |d| self[d] && self[d].size == 13 }
94
+ cards = (n + e + s + w).uniq
95
+ if cards.size == 52
96
+ cards.all? { |card| Bridge.card?(card) }
97
+ else
98
+ false
99
+ end
100
+ else
101
+ false
102
+ end
103
+ end
104
+
105
+ private
106
+
107
+ def must_be_direction!(string)
108
+ raise ArgumentError, "invalid direction: #{string}" unless Bridge.direction?(string.to_s.upcase)
109
+ end
110
+
111
+ def []=(direction, cards)
112
+ must_be_direction!(direction)
113
+ instance_variable_set("@#{direction.to_s.downcase}", cards)
114
+ end
115
+ end
116
+ end
data/lib/bridge.rb CHANGED
@@ -1,94 +1,47 @@
1
- module Bridge
1
+ require "bridge/deal"
2
2
 
3
+ module Bridge
3
4
  # Number of possible deals in bridge
4
5
  DEALS = 53_644_737_765_488_792_839_237_440_000
5
6
 
6
- # Array with cards in the bridge deck (AKQJT98765432, four suits)
7
+ # Array with card strings in the bridge deck (AKQJT98765432, four
8
+ # suits). Contains "SA", "HT", etc.
7
9
  DECK = %w(S H D C).inject([]) do |d, s|
8
10
  d += %w(A K Q J T 9 8 7 6 5 4 3 2).map { |c| s + c }
9
11
  end
10
12
 
11
- # Converts given id to deal (hash)
12
- def self.id_to_deal(id)
13
- deal = { :n => [], :e => [], :s => [], :w => [] }
14
- k = DEALS
15
- DECK.each_with_index do |card, i|
16
- x = k * (13 - deal[:n].size) / (52 - i)
17
- if id < x
18
- deal[:n] << card
19
- else
20
- id -= x
21
- x = k * (13 - deal[:e].size) / (52 - i)
22
- if id < x
23
- deal[:e] << card
24
- else
25
- id -= x
26
- x = k * (13 - deal[:s].size) / (52 - i)
27
- if id < x
28
- deal[:s] << card
29
- else
30
- id -= x
31
- x = k * (13 - deal[:w].size) / (52 - i)
32
- deal[:w] << card
33
- end
34
- end
35
- end
36
- k = x
37
- end
38
- deal
39
- end
13
+ # Direction strings "N", "E", "S" and "W"
14
+ DIRECTIONS = %w(N E S W)
40
15
 
41
- # Converts given deal (hash) to id
42
- def self.deal_to_id(d)
43
- k = DEALS; id = 0
44
- deal = { :n => d[:n].dup, :e => d[:e].dup, :s => d[:s].dup, :w => d[:w].dup }
45
- DECK.each_with_index do |card, i|
46
- x = k * deal[:n].size / (52 - i)
47
- unless deal[:n].delete(card)
48
- id += x
49
- x = k * deal[:e].size / (52 - i)
50
- unless deal[:e].delete(card)
51
- id += x
52
- x = k * deal[:s].size / (52 - i)
53
- unless deal[:s].delete(card)
54
- id += x
55
- x = k * deal[:w].size / (52 - i)
56
- deal[:w].delete(card)
57
- end
58
- end
59
- end
60
- k = x
61
- end
62
- id
16
+ # Possible contracts in ascending order. Contains "1C", "6NT", etc.
17
+ CONTRACTS = %w(1 2 3 4 5 6 7).inject([]) do |b, l|
18
+ b += %w(C D H S NT).map { |s| l + s }
63
19
  end
64
20
 
65
- # Returns a random deal id
66
- def self.random_deal_id
67
- rand(DEALS)
68
- end
21
+ # Pass string
22
+ PASS = "PASS"
69
23
 
70
- # Returns a random deal
71
- def self.random_deal
72
- id_to_deal(random_deal_id)
73
- end
24
+ # Double string
25
+ DOUBLE = "X"
74
26
 
75
- # Checks if the given number is valid deal id
76
- def self.deal_id?(n)
77
- (0..DEALS - 1).include?(n)
27
+ # Redouble string
28
+ REDOUBLE = "XX"
29
+
30
+ # Modifier bids (double and redouble)
31
+ MODIFIERS = [DOUBLE, REDOUBLE]
32
+
33
+ # All possible bids (including contracts, modifiers and pass)
34
+ BIDS = CONTRACTS + MODIFIERS + [PASS]
35
+
36
+ def self.direction?(string)
37
+ DIRECTIONS.include?(string)
78
38
  end
79
39
 
80
- # Checks if the given hash is valid deal
81
- def self.deal?(h)
82
- if [:n, :e, :s, :w].all? { |s| h[s] && h[s].size == 13 }
83
- cards = (h[:n] + h[:e] + h[:s] + h[:w]).uniq
84
- if cards.size == 52
85
- cards.all? { |card| DECK.include?(card) }
86
- else
87
- false
88
- end
89
- else
90
- false
91
- end
40
+ def self.deal_id?(integer)
41
+ (0..DEALS - 1).include?(integer)
92
42
  end
93
43
 
44
+ def self.card?(string)
45
+ DECK.include?(string)
46
+ end
94
47
  end
data/test/test_bridge.rb CHANGED
@@ -1,67 +1,6 @@
1
- require 'helper'
1
+ require "helper"
2
2
 
3
3
  class TestBridge < Test::Unit::TestCase
4
- test "first deal conversion" do
5
- id = 0
6
- deal = Bridge.id_to_deal(id)
7
- assert Bridge.deal?(deal)
8
- assert_equal %w(AS KS QS JS TS 9S 8S 7S 6S 5S 4S 3S 2S), deal[:n]
9
- assert_equal %w(AH KH QH JH TH 9H 8H 7H 6H 5H 4H 3H 2H), deal[:e]
10
- assert_equal %w(AD KD QD JD TD 9D 8D 7D 6D 5D 4D 3D 2D), deal[:s]
11
- assert_equal %w(AC KC QC JC TC 9C 8C 7C 6C 5C 4C 3C 2C), deal[:w]
12
- assert_equal id, Bridge.deal_to_id(deal)
13
- end
14
-
15
- test "last deal conversion" do
16
- id = Bridge::DEALS - 1
17
- deal = Bridge.id_to_deal(id)
18
- assert Bridge.deal?(deal)
19
- assert_equal %w(AC KC QC JC TC 9C 8C 7C 6C 5C 4C 3C 2C), deal[:n]
20
- assert_equal %w(AD KD QD JD TD 9D 8D 7D 6D 5D 4D 3D 2D), deal[:e]
21
- assert_equal %w(AH KH QH JH TH 9H 8H 7H 6H 5H 4H 3H 2H), deal[:s]
22
- assert_equal %w(AS KS QS JS TS 9S 8S 7S 6S 5S 4S 3S 2S), deal[:w]
23
- assert_equal id, Bridge.deal_to_id(deal)
24
- end
25
-
26
- test "deal no 1 000 000 000" do
27
- id = 1_000_000_000
28
- deal = Bridge.id_to_deal(id)
29
- assert Bridge.deal?(deal)
30
- assert_equal id, Bridge.deal_to_id(deal)
31
- end
32
-
33
- test "sample deal to id conversion" do
34
- deal = {
35
- :n => %w(AS KS QS JS AH KH QH AD KD QD AC KC QC),
36
- :e => %w(TS 9S 8S 7S 6S 5S 4S 3S 2S JH TH 9H 8H),
37
- :s => %w(7H 6H 5H 4H 3H 2H JD TD 9D 8D 7D 6D 5D),
38
- :w => %w(4D 3D 2D JC TC 9C 8C 7C 6C 5C 4C 3C 2C)
39
- }
40
- assert Bridge.deal?(deal)
41
- id = Bridge.deal_to_id(deal)
42
- assert_equal deal, Bridge.id_to_deal(id)
43
- end
44
-
45
- test "deal with doubled cards is not valid deal" do
46
- deal = {
47
- :n => %w(AS AS QS JS AH KH QH AD KD QD AC KC QC),
48
- :e => %w(TS 9S 8S 7S 6S 5S 4S 3S 2S JH TH 9H 8H),
49
- :s => %w(7H 6H 5H 4H 3H 2H JD TD 9D 8D 7D 6D 5D),
50
- :w => %w(4D 3D 2D JC TC 9C 8C 7C 6C 5C 4C 3C 2C)
51
- }
52
- assert_false Bridge.deal?(deal)
53
- end
54
-
55
- test "deal with different length hands is not valid deal" do
56
- deal = {
57
- :n => %w(AS KS QS JS AH KH QH AD KD QD AC KC QC TS),
58
- :e => %w(9S 8S 7S 6S 5S 4S 3S 2S JH TH 9H 8H),
59
- :s => %w(7H 6H 5H 4H 3H 2H JD TD 9D 8D 7D 6D 5D),
60
- :w => %w(4D 3D 2D JC TC 9C 8C 7C 6C 5C 4C 3C 2C)
61
- }
62
- assert_false Bridge.deal?(deal)
63
- end
64
-
65
4
  test "negative number is not valid deal id" do
66
5
  assert_false Bridge.deal_id?(-1)
67
6
  end
@@ -69,14 +8,4 @@ class TestBridge < Test::Unit::TestCase
69
8
  test "number of possible bridge deals is not valid deal id" do
70
9
  assert_false Bridge.deal_id?(Bridge::DEALS)
71
10
  end
72
-
73
- test "random deal id is valid deal id" do
74
- id = Bridge.random_deal_id
75
- assert Bridge.deal_id?(id)
76
- end
77
-
78
- test "random deal is valid deal" do
79
- deal = Bridge.random_deal
80
- assert Bridge.deal?(deal)
81
- end
82
11
  end
@@ -0,0 +1,5 @@
1
+ require "helper"
2
+
3
+ class TestContract < Test::Unit::TestCase
4
+
5
+ end
data/test/test_deal.rb ADDED
@@ -0,0 +1,87 @@
1
+ require "helper"
2
+
3
+ class TestDeal < Test::Unit::TestCase
4
+ test "first deal conversion" do
5
+ id = 0
6
+ deal = Bridge::Deal.from_id(id)
7
+ assert deal.valid?
8
+ assert_equal %w(SA SK SQ SJ ST S9 S8 S7 S6 S5 S4 S3 S2), deal.n
9
+ assert_equal %w(HA HK HQ HJ HT H9 H8 H7 H6 H5 H4 H3 H2), deal.e
10
+ assert_equal %w(DA DK DQ DJ DT D9 D8 D7 D6 D5 D4 D3 D2), deal.s
11
+ assert_equal %w(CA CK CQ CJ CT C9 C8 C7 C6 C5 C4 C3 C2), deal.w
12
+ assert_equal id, deal.id
13
+ end
14
+
15
+ test "last deal conversion" do
16
+ id = Bridge::DEALS - 1
17
+ deal = Bridge::Deal.from_id(id)
18
+ assert deal.valid?
19
+ assert_equal %w(CA CK CQ CJ CT C9 C8 C7 C6 C5 C4 C3 C2), deal.n
20
+ assert_equal %w(DA DK DQ DJ DT D9 D8 D7 D6 D5 D4 D3 D2), deal.e
21
+ assert_equal %w(HA HK HQ HJ HT H9 H8 H7 H6 H5 H4 H3 H2), deal.s
22
+ assert_equal %w(SA SK SQ SJ ST S9 S8 S7 S6 S5 S4 S3 S2), deal.w
23
+ assert_equal id, deal.id
24
+ end
25
+
26
+ test "deal no 1 000 000 000 000" do
27
+ id = 1_000_000_000_000
28
+ deal = Bridge::Deal.from_id(id)
29
+ assert deal.valid?
30
+ assert_equal id, deal.id
31
+ end
32
+
33
+ test "sample deal to id conversion" do
34
+ deal = Bridge::Deal.new("N" => %w(SA SK SQ SJ HA HK HQ DA DK DQ CA CK CQ),
35
+ "E" => %w(ST S9 S8 S7 S6 S5 S4 S3 S2 HJ HT H9 H8),
36
+ "S" => %w(H7 H6 H5 H4 H3 H2 DJ DT D9 D8 D7 D6 D5),
37
+ "W" => %w(D4 D3 D2 CJ CT C9 C8 C7 C6 C5 C4 C3 C2))
38
+ assert deal.valid?
39
+ id = deal.id
40
+ assert_equal deal, Bridge::Deal.from_id(id)
41
+ end
42
+
43
+ test "deal with doubled cards is not valid deal" do
44
+ deal = Bridge::Deal.new("N" => %w(SA SA SQ SJ HA HK HQ DA DK DQ CA CK CQ),
45
+ "E" => %w(ST S9 S8 S7 S6 S5 S4 S3 S2 HJ HT H9 H8),
46
+ "S" => %w(H7 H6 H5 H4 H3 H2 DJ DT D9 D8 D7 D6 D5),
47
+ "W" => %w(D4 D3 D2 CJ CT C9 C8 C7 C6 C5 C4 C3 C2))
48
+ assert_false deal.valid?
49
+ end
50
+
51
+ test "deal with different length hands is not valid deal" do
52
+ deal = Bridge::Deal.new("N" => %w(SA SK SQ SJ HA HK HQ DA DK DQ CA CK CQ ST),
53
+ "E" => %w(S9 S8 S7 S6 S5 S4 S3 S2 HJ HT H9 H8),
54
+ "S" => %w(H7 H6 H5 H4 H3 H2 DJ DT D9 D8 D7 D6 D5),
55
+ "W" => %w(D4 D3 D2 CJ CT C9 C8 C7 C6 C5 C4 C3 C2))
56
+ assert_false deal.valid?
57
+ end
58
+
59
+ test "random deal id is valid deal id" do
60
+ id = Bridge::Deal.random_id
61
+ assert Bridge.deal_id?(id)
62
+ end
63
+
64
+ test "random deal is valid deal" do
65
+ deal = Bridge::Deal.random
66
+ assert deal.valid?
67
+ end
68
+
69
+ test "comparison of two deals" do
70
+ deal1 = Bridge::Deal.from_id(1_000_000_000_000_000)
71
+ deal2 = Bridge::Deal.from_id(9_000_000_000_000_000)
72
+ assert deal1 < deal2
73
+ end
74
+
75
+ test "fetching wrong direction raises an error" do
76
+ deal = Bridge::Deal.random
77
+ assert_raises(ArgumentError) do
78
+ deal[:h]
79
+ end
80
+ end
81
+
82
+ test "passing incorrect id to from_id raises an error" do
83
+ assert_raises(ArgumentError) do
84
+ Bridge::Deal.from_id(-1)
85
+ end
86
+ end
87
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bridge
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Jakub Ku\xC5\xBAma"
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-02-22 00:00:00 +01:00
12
+ date: 2010-02-23 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -40,8 +40,12 @@ files:
40
40
  - VERSION
41
41
  - bridge.gemspec
42
42
  - lib/bridge.rb
43
+ - lib/bridge/contract.rb
44
+ - lib/bridge/deal.rb
43
45
  - test/helper.rb
44
46
  - test/test_bridge.rb
47
+ - test/test_contract.rb
48
+ - test/test_deal.rb
45
49
  has_rdoc: true
46
50
  homepage: http://github.com/qoobaa/bridge
47
51
  licenses: []
@@ -71,5 +75,7 @@ signing_key:
71
75
  specification_version: 3
72
76
  summary: Contract bridge utilities
73
77
  test_files:
74
- - test/helper.rb
75
78
  - test/test_bridge.rb
79
+ - test/test_deal.rb
80
+ - test/helper.rb
81
+ - test/test_contract.rb