bridge 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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