leonardo-bridge 0.4.3 → 0.6.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.
- checksums.yaml +5 -13
- data/LICENSE.txt +1 -1
- data/README.md +10 -7
- data/bin/leo-console +1 -0
- data/bin/leo-play +23 -4
- data/bridge.gemspec +2 -6
- data/lib/bridge.rb +2 -1
- data/lib/bridge/auction.rb +0 -1
- data/lib/bridge/board.rb +0 -1
- data/lib/bridge/call.rb +0 -1
- data/lib/bridge/contract.rb +0 -3
- data/lib/bridge/deal.rb +9 -6
- data/lib/bridge/deck.rb +13 -2
- data/lib/bridge/game.rb +55 -7
- data/lib/bridge/hand.rb +1 -1
- data/lib/bridge/player.rb +1 -3
- data/lib/bridge/result.rb +5 -5
- data/lib/bridge/trick_play.rb +0 -1
- data/lib/bridge/version.rb +1 -1
- data/spec/auction_spec.rb +23 -23
- data/spec/board_spec.rb +8 -8
- data/spec/bridge_spec.rb +16 -16
- data/spec/call_spec.rb +19 -19
- data/spec/card_spec.rb +21 -21
- data/spec/deck_spec.rb +2 -2
- data/spec/enum_spec.rb +7 -7
- data/spec/game_spec.rb +169 -85
- data/spec/hand_spec.rb +3 -3
- data/spec/player_spec.rb +3 -3
- data/spec/result_spec.rb +5 -5
- data/spec/spec_helper.rb +0 -7
- data/spec/support/auction_helper.rb +3 -3
- data/spec/trick_play_spec.rb +44 -45
- data/spec/trick_spec.rb +4 -4
- metadata +18 -83
- data/lib/bridge/db.rb +0 -27
- data/lib/redis_model.rb +0 -137
- data/lib/uuid.rb +0 -280
- data/spec/db_spec.rb +0 -19
- data/spec/redis_model_spec.rb +0 -50
- data/spec/support/test_model.rb +0 -3
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
OGI1YTBkY2QwZjI0NjcwMDIyMzYxMDE1NzQzZDRkOTYzYTdmYTU5Ng==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9be6e3140176b3db2048e72737b9f3e2a4530b38
|
4
|
+
data.tar.gz: 7c9fe92ceab4462a2aebf9ae3c6d5937cf347f80
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
ZDNjOWMzYzA0ZWY0NjY5MDM0NWZmODllZjM0NmU5NzEwZGI3MjhjMjBkYWQy
|
11
|
-
YmZhYjdmZWQ0NzdhZmZkNjlhMGM3MTE4MzZmM2FiOTk2YWQ2MmE=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
OGY2OGRiOGIzYTJkMzg5MGZhNzcxODdjMWRhMGQwYmU5NTYyMWVkYTU3NjIz
|
14
|
-
MjhlNDU5NjRiZTk5ZjcyNzA1YzE5ODZiZjcwN2RjMTEzYmM1MDEwM2YwZmMz
|
15
|
-
NjgzNjM3MzcyNTU2OGVmY2Y3OGI1NjQzMjRlODE2MjFjZGE5MjI=
|
6
|
+
metadata.gz: df553f217643aad19ae9253be133c5a38b308544cf3e0438284d19af649d7b4f0a681d7128340b04d26f48d05c0e6c4553d453660e03cbda433cd350bde5e771
|
7
|
+
data.tar.gz: 7422db23f08aeba5d8df54f5da27318664bacafa06bc77461f77552319ef4de518e3e67ffe5182914116f76e0dbb25865d62a3eacfa30a3018199f3ba924a0c5
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
# Bridge
|
2
|
+
Bridge is the bridge playing engine sitting behind [Leo Bridge](https://leobridge.net/) this is the first version initially built in 2013 and is shared here as a working game engine example.
|
2
3
|
|
3
|
-
|
4
|
-
Large portions of this gem have been ported from [pybridge](http://sourceforge.net/projects/pybridge/)
|
4
|
+
You can use it to experiment with building a card game UI, or however else you wish.
|
5
5
|
|
6
|
-
|
6
|
+
Large portions of this gem have been ported from [pybridge](http://sourceforge.net/projects/pybridge/)
|
7
7
|
|
8
8
|
## Installation
|
9
9
|
|
10
10
|
Add this line to your application's Gemfile:
|
11
11
|
|
12
12
|
#!ruby
|
13
|
-
gem 'bridge'
|
13
|
+
gem 'leonardo-bridge', require: 'bridge'
|
14
14
|
|
15
15
|
And then execute:
|
16
16
|
|
@@ -18,11 +18,14 @@ And then execute:
|
|
18
18
|
|
19
19
|
Or install it yourself as:
|
20
20
|
|
21
|
-
$ gem install bridge
|
21
|
+
$ gem install leonardo-bridge
|
22
22
|
|
23
23
|
## Usage
|
24
24
|
|
25
|
-
You can have a look at `bin/play` for an example of interaction with the Bridge::Game class.
|
25
|
+
You can have a look at `bin/leo-play` for an example of interaction with the Bridge::Game class (type `help` for available commands).
|
26
|
+
|
27
|
+
IF you clone the source, you can also run `./bin/leo-play` to try out a rudimentary interactive game (meant as a demo, this is NOT a full bridge game).
|
28
|
+
|
26
29
|
|
27
30
|
Here's a quick run-through:
|
28
31
|
|
@@ -43,4 +46,4 @@ Here's a quick run-through:
|
|
43
46
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
44
47
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
45
48
|
4. Push to the branch (`git push origin my-new-feature`)
|
46
|
-
5. Create new Pull Request
|
49
|
+
5. Create new Pull Request
|
data/bin/leo-console
CHANGED
data/bin/leo-play
CHANGED
@@ -78,6 +78,15 @@ end
|
|
78
78
|
|
79
79
|
while cmd = gets.strip
|
80
80
|
case cmd
|
81
|
+
when 'help'
|
82
|
+
puts "* Available Commands".green
|
83
|
+
puts "`hand` show current player hand"
|
84
|
+
puts "`bid [valid bid]` make an auction bid (e.g. `bid one spade`)"
|
85
|
+
puts "`[card]` play a card while in play (e.g. `AH` or `10S`)"
|
86
|
+
puts "`rush [auction|trick]` fast-forward auction or trick stage"
|
87
|
+
puts "`history` display move history"
|
88
|
+
puts "`undo` undo last auction or trick stage move"
|
89
|
+
print cursor
|
81
90
|
when 'bye','exit','leave'
|
82
91
|
break
|
83
92
|
when 'rush trick' # play an automatic trick
|
@@ -85,12 +94,18 @@ while cmd = gets.strip
|
|
85
94
|
rush_trick
|
86
95
|
when 'rush auction' # play a canned auction
|
87
96
|
rush_auction
|
97
|
+
when 'undo'
|
98
|
+
if @game.undo!
|
99
|
+
put 'OK'.green
|
100
|
+
else
|
101
|
+
put 'Undo unavailable'.yellow
|
102
|
+
end
|
88
103
|
when 'history'
|
89
104
|
put 'Move history:'.yellow
|
90
105
|
put @history.join("\n")
|
91
106
|
|
92
107
|
when 'hand'
|
93
|
-
put @game.get_hand(@game.get_turn).
|
108
|
+
put @game.get_hand(@game.get_turn).to_s
|
94
109
|
print cursor
|
95
110
|
|
96
111
|
else
|
@@ -111,10 +126,14 @@ while cmd = gets.strip
|
|
111
126
|
else
|
112
127
|
card = Card.from_string(ary.first)
|
113
128
|
end
|
114
|
-
|
115
|
-
|
129
|
+
player = if @game.get_turn == @game.play.dummy
|
130
|
+
@players[@game.play.declarer]
|
131
|
+
else
|
132
|
+
@players[position_i]
|
133
|
+
end
|
134
|
+
player.play_card(card)
|
116
135
|
print "#{position.white} plays #{card.to_s.magenta} ~> "
|
117
|
-
puts @game.play.get_current_trick.cards.compact.
|
136
|
+
puts @game.play.get_current_trick.cards.map(&:to_s).compact.join(' ').white
|
118
137
|
rescue Exception => e
|
119
138
|
put e.message.red
|
120
139
|
end
|
data/bridge.gemspec
CHANGED
@@ -7,23 +7,19 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "leonardo-bridge"
|
8
8
|
spec.version = Bridge::VERSION
|
9
9
|
spec.authors = ["Achilles Charmpilas"]
|
10
|
-
spec.email = ["
|
10
|
+
spec.email = ["achilles@clickitmedia.eu"]
|
11
11
|
spec.description = %q{A lean mean bridge playing machine}
|
12
12
|
spec.summary = %q{Encapsulates all the necessary logic that allows 4 players to play a bridge game. Also supports rubber scoring.}
|
13
|
-
spec.homepage = "
|
13
|
+
spec.homepage = "https://leobridge.net"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
|
-
spec.add_dependency "redis"
|
21
20
|
spec.add_dependency "nutrun-string"
|
22
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
23
22
|
spec.add_development_dependency "rspec"
|
24
|
-
spec.add_development_dependency "fuubar"
|
25
|
-
spec.add_development_dependency "geminabox"
|
26
|
-
spec.add_development_dependency "gem-release"
|
27
23
|
spec.add_development_dependency "rake"
|
28
24
|
spec.add_development_dependency "simplecov"
|
29
25
|
end
|
data/lib/bridge.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'ostruct'
|
3
3
|
require 'pathname'
|
4
|
+
require 'json'
|
4
5
|
require 'nutrun-string'
|
5
6
|
|
6
7
|
root = File.dirname(__FILE__)
|
7
8
|
|
8
|
-
%W{
|
9
|
+
%W{ enum }.each { |r| require File.join(root,r) }
|
9
10
|
|
10
11
|
module Bridge
|
11
12
|
DEBUG = false
|
data/lib/bridge/auction.rb
CHANGED
@@ -4,7 +4,6 @@ module Bridge
|
|
4
4
|
class InvalidCallClassError < StandardError; end
|
5
5
|
|
6
6
|
# The auction (bidding phase) of a game of bridge.
|
7
|
-
# Swiped from: https://pybridge.svn.sourceforge.net/svnroot/pybridge/trunk/pybridge/pybridge/games/bridge/auction.py
|
8
7
|
class Auction
|
9
8
|
attr_accessor :dealer, :calls, :contract
|
10
9
|
|
data/lib/bridge/board.rb
CHANGED
data/lib/bridge/call.rb
CHANGED
data/lib/bridge/contract.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
module Bridge
|
2
2
|
class InvalidAuctionError < StandardError; end
|
3
|
-
|
4
|
-
# Represents the result of an auction.
|
5
|
-
# Swiped from: https://pybridge.svn.sourceforge.net/svnroot/pybridge/trunk/pybridge/pybridge/games/bridge/auction.py
|
6
3
|
class Contract
|
7
4
|
attr_accessor :redouble_by, :double_by, :bid, :declarer
|
8
5
|
|
data/lib/bridge/deal.rb
CHANGED
@@ -1,9 +1,4 @@
|
|
1
1
|
module Bridge
|
2
|
-
# deal, not game
|
3
|
-
# bidding create the contract
|
4
|
-
# bidding is also persistent
|
5
|
-
# bidding finishes after 3 passes
|
6
|
-
|
7
2
|
class Deal
|
8
3
|
attr_accessor :hands, :deck
|
9
4
|
|
@@ -16,12 +11,20 @@ module Bridge
|
|
16
11
|
deal!
|
17
12
|
self
|
18
13
|
end
|
19
|
-
|
14
|
+
|
20
15
|
# deals one card per hand on a cycle until we run out of cards
|
21
16
|
def deal!
|
22
17
|
hands.cycle(deck.size/hands.size) { |hand| hand << deck.shift }
|
23
18
|
end
|
24
19
|
|
20
|
+
def to_page
|
21
|
+
# returns HEX bridge book page value
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.from_page
|
25
|
+
# create deal and hands based on HEX bridge book page number
|
26
|
+
end
|
27
|
+
|
25
28
|
def method_missing(m, *args, &block)
|
26
29
|
if hands.respond_to?(m)
|
27
30
|
hands.send(m, *args, &block)
|
data/lib/bridge/deck.rb
CHANGED
@@ -1,12 +1,23 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
1
3
|
module Bridge
|
2
4
|
class Deck
|
3
5
|
attr_accessor :cards
|
4
6
|
|
5
7
|
def initialize
|
6
8
|
@cards = Card::RANKS.product(Card::SUITS).map { |a| Card.new(a[0],a[1]) }
|
7
|
-
@cards.shuffle!
|
9
|
+
@cards.shuffle!(random: SecureRandom)
|
8
10
|
end
|
9
|
-
|
11
|
+
|
12
|
+
# make sure shuffling is as random as possible
|
13
|
+
def shuffle!
|
14
|
+
@cards.shuffle!(random: SecureRandom)
|
15
|
+
end
|
16
|
+
|
17
|
+
def shuffle
|
18
|
+
@cards.shuffle(random: SecureRandom)
|
19
|
+
end
|
20
|
+
|
10
21
|
def inspect
|
11
22
|
cards.inspect
|
12
23
|
end
|
data/lib/bridge/game.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
#require File.join(File.dirname(__FILE__),'result')
|
2
2
|
|
3
3
|
module Bridge
|
4
|
-
# Raised by game in response to an unsatisfiable or erroneous request.
|
5
|
-
# ref: https://pybridge.svn.sourceforge.net/svnroot/pybridge/trunk/pybridge/pybridge/network/error.py
|
6
4
|
class GameError < StandardError
|
7
5
|
end
|
8
6
|
|
@@ -12,9 +10,7 @@ module Bridge
|
|
12
10
|
# Modifications to the state are typically made through BridgePlayer objects.
|
13
11
|
# Methods which change the game state (make_call, playCard) require a player
|
14
12
|
# argument as "authentication".
|
15
|
-
class Game
|
16
|
-
use_timestamps
|
17
|
-
|
13
|
+
class Game
|
18
14
|
attr_accessor :auction, :play, :players, :options, :number
|
19
15
|
attr_accessor :board, :board_queue, :results, :visible_hands
|
20
16
|
attr_accessor :trump_suit, :result, :contract, :state
|
@@ -105,7 +101,22 @@ module Bridge
|
|
105
101
|
self.state = :auction
|
106
102
|
true
|
107
103
|
end
|
108
|
-
|
104
|
+
|
105
|
+
def in_play?
|
106
|
+
if !self.play.nil?
|
107
|
+
!self.play.complete?
|
108
|
+
else
|
109
|
+
false
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def in_auction?
|
114
|
+
if !self.auction.nil?
|
115
|
+
!self.auction.passed_out?
|
116
|
+
else
|
117
|
+
false
|
118
|
+
end
|
119
|
+
end
|
109
120
|
|
110
121
|
def in_progress?
|
111
122
|
if !self.play.nil?
|
@@ -168,7 +179,44 @@ module Bridge
|
|
168
179
|
|
169
180
|
self.players.reject! { |player,pos| pos == position }
|
170
181
|
end
|
171
|
-
|
182
|
+
|
183
|
+
# Send undo message to either auction or trick play
|
184
|
+
# this is only available while there is an auction or trick_play
|
185
|
+
def undo!
|
186
|
+
case self.state
|
187
|
+
when :auction
|
188
|
+
if self.auction.complete?
|
189
|
+
false # can't undo if auction is complete yo.
|
190
|
+
else
|
191
|
+
card = self.auction.calls.pop # remove the last undo
|
192
|
+
if card
|
193
|
+
true
|
194
|
+
else
|
195
|
+
false
|
196
|
+
end
|
197
|
+
end
|
198
|
+
when :playing
|
199
|
+
# remove the last card from everywhere
|
200
|
+
card = self.play.history.pop
|
201
|
+
if card
|
202
|
+
trick = self.play.get_current_trick
|
203
|
+
player = self.play.who_played?(card)
|
204
|
+
# this was a completed trick, we need to remove it from the winner queue
|
205
|
+
if trick.cards.compact.size == 4
|
206
|
+
winner = self.play.who_played?(self.play.winning_card(trick))
|
207
|
+
self.play.winners.pop if self.play.winners.last == winner
|
208
|
+
end
|
209
|
+
self.play.get_current_trick.cards.delete(card)
|
210
|
+
self.play.played.each { |k,h| h.delete(card) }
|
211
|
+
self.board.deal.hands[player] << card
|
212
|
+
true
|
213
|
+
else
|
214
|
+
false
|
215
|
+
end
|
216
|
+
else
|
217
|
+
false
|
218
|
+
end
|
219
|
+
end
|
172
220
|
|
173
221
|
# Bridge-specific methods.
|
174
222
|
|
data/lib/bridge/hand.rb
CHANGED
data/lib/bridge/player.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
module Bridge
|
2
|
-
|
3
|
-
# ref: https://pybridge.svn.sourceforge.net/svnroot/pybridge/trunk/pybridge/pybridge/games/bridge/game.py
|
4
|
-
class Player < RedisModel
|
2
|
+
class Player
|
5
3
|
def initialize(game)
|
6
4
|
@game = game # Access to game is private to this object.
|
7
5
|
end
|
data/lib/bridge/result.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
|
2
2
|
module Bridge
|
3
|
-
# Represents the result of a completed round of bridge.
|
4
|
-
# Swiped from: https://svn.code.sf.net/p/pybridge/code/trunk/pybridge/pybridge/games/bridge/result.py
|
5
3
|
class Result
|
6
4
|
VULN_MAP = {
|
7
5
|
Vulnerability.none => [],
|
@@ -127,17 +125,19 @@ module Bridge
|
|
127
125
|
else
|
128
126
|
components['slambonus'] = 500
|
129
127
|
end
|
130
|
-
|
128
|
+
end
|
129
|
+
|
130
|
+
if components['odd'] >= 100 # Game contract (non-slam).
|
131
131
|
# 500 for game if vulnerable, 300 if not.
|
132
132
|
if is_vulnerable
|
133
133
|
components['gamebonus'] = 500
|
134
134
|
else
|
135
135
|
components['gamebonus'] = 300
|
136
136
|
end
|
137
|
-
else
|
137
|
+
else # Non-game contract.
|
138
138
|
components['partscore'] = 50
|
139
139
|
end
|
140
|
-
|
140
|
+
|
141
141
|
#### Insult bonus ####
|
142
142
|
if is_redoubled
|
143
143
|
components['insultbonus'] = 100
|
data/lib/bridge/trick_play.rb
CHANGED
@@ -2,7 +2,6 @@ module Bridge
|
|
2
2
|
# This class models the trick-taking phase of a game of bridge.
|
3
3
|
# This code is generalised, and could easily be adapted to support a
|
4
4
|
# variety of trick-taking card games.
|
5
|
-
# Swiped from: https://pybridge.svn.sourceforge.net/svnroot/pybridge/trunk/pybridge/pybridge/games/bridge/auction.py
|
6
5
|
class TrickPlay
|
7
6
|
attr_accessor :trumps, :declarer, :dummy, :lho, :rho, :played, :winners, :history
|
8
7
|
|
data/lib/bridge/version.rb
CHANGED
data/spec/auction_spec.rb
CHANGED
@@ -13,30 +13,30 @@ describe Auction do
|
|
13
13
|
|
14
14
|
subject(:instance) { Auction.new(dealer) }
|
15
15
|
|
16
|
-
it { subject.contract.
|
17
|
-
it { subject.get_contract.
|
18
|
-
it { subject.calls.size.
|
19
|
-
it { subject.dealer.
|
16
|
+
it { expect(subject.contract).to be_a(NilClass) }
|
17
|
+
it { expect(subject.get_contract).to be_a(NilClass) }
|
18
|
+
it { expect(subject.calls.size).to eq(0) }
|
19
|
+
it { expect(subject.dealer).to eq(dealer) }
|
20
20
|
|
21
21
|
it 'should pass out on 4 passes only' do
|
22
|
-
subject.passed_out
|
22
|
+
expect(subject.passed_out?).to eq(false)
|
23
23
|
3.times do
|
24
|
-
subject.make_call(Pass.new).
|
25
|
-
subject.passed_out
|
24
|
+
expect(subject.make_call(Pass.new)).to eq(true)
|
25
|
+
expect(subject.passed_out?).to eq(false)
|
26
26
|
end
|
27
27
|
|
28
|
-
subject.make_call(Pass.new).
|
29
|
-
subject.passed_out
|
28
|
+
expect(subject.make_call(Pass.new)).to eq(true)
|
29
|
+
expect(subject.passed_out?).to eq(true)
|
30
30
|
end
|
31
31
|
|
32
32
|
describe 'when finished' do
|
33
33
|
before { calls.each { |call| subject.make_call(call) } }
|
34
34
|
|
35
|
-
it { subject.calls.
|
36
|
-
it { subject.contract.
|
37
|
-
it { subject.contract.
|
38
|
-
it { subject.get_contract.
|
39
|
-
it { subject.get_contract.
|
35
|
+
it { expect(subject.calls).to eq(calls) }
|
36
|
+
it { expect(subject.contract).to_not be_a(NilClass) }
|
37
|
+
it { expect(subject.contract).to be_a(Contract) }
|
38
|
+
it { expect(subject.get_contract).to be_a(Hash) }
|
39
|
+
it { expect(subject.get_contract).to eq(subject.contract.to_hash) }
|
40
40
|
end
|
41
41
|
|
42
42
|
describe 'current call' do
|
@@ -57,35 +57,35 @@ describe Auction do
|
|
57
57
|
|
58
58
|
it 'does not allow invalid calls' do
|
59
59
|
subject.make_call(Bid.new(Level.two, Strain.club))
|
60
|
-
expect { subject.make_call(Bid.new(Level.one, Strain.club)) }.to raise_error
|
60
|
+
expect { subject.make_call(Bid.new(Level.one, Strain.club)) }.to raise_error(Bridge::InvalidCallError)
|
61
61
|
expect { subject.make_call(Bid.new(Level.three, Strain.club)) }.to_not raise_error
|
62
|
-
expect { subject.make_call(Bid.new(Level.two, Strain.heart)) }.to raise_error
|
62
|
+
expect { subject.make_call(Bid.new(Level.two, Strain.heart)) }.to raise_error(Bridge::InvalidCallError)
|
63
63
|
expect { subject.make_call(Bid.new(Level.three, Strain.heart)) }.to_not raise_error
|
64
64
|
end
|
65
65
|
|
66
66
|
it 'knows whose turn it is' do
|
67
67
|
turn = dealer
|
68
|
-
subject.whose_turn.
|
68
|
+
expect(subject.whose_turn).to eq(turn)
|
69
69
|
|
70
70
|
calls.each_index do |i|
|
71
71
|
subject.make_call(calls[i])
|
72
72
|
if i == calls.size - 1
|
73
|
-
subject.whose_turn.
|
73
|
+
expect(subject.whose_turn).to eq(nil)
|
74
74
|
else
|
75
75
|
turn = Direction[(turn + 1) % 4] # Turn moves clockwise.
|
76
|
-
subject.whose_turn.
|
76
|
+
expect(subject.whose_turn).to eq(turn)
|
77
77
|
end
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
81
|
it 'only marks an auction as complete if it is' do
|
82
|
-
subject.complete
|
82
|
+
expect(subject.complete?).to eq(false)
|
83
83
|
calls.each_index do |i|
|
84
84
|
subject.make_call(calls[i])
|
85
85
|
if i == calls.size - 1
|
86
|
-
subject.complete
|
86
|
+
expect(subject.complete?).to eq(true)
|
87
87
|
else
|
88
|
-
subject.complete
|
88
|
+
expect(subject.complete?).to eq(false)
|
89
89
|
end
|
90
90
|
end
|
91
91
|
end
|
@@ -94,7 +94,7 @@ describe Auction do
|
|
94
94
|
calls.each_index do |i|
|
95
95
|
subject.make_call(calls[i])
|
96
96
|
next_call = calls[i+1]
|
97
|
-
subject.valid_call?(next_call).
|
97
|
+
expect(subject.valid_call?(next_call)).to eq(true) unless next_call.nil?
|
98
98
|
end
|
99
99
|
end
|
100
100
|
end
|