gambit 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +2 -0
- data/CHANGELOG +7 -0
- data/COPYING +340 -0
- data/INSTALL +23 -0
- data/LICENSE +7 -0
- data/README +25 -0
- data/Rakefile +87 -0
- data/TODO +6 -0
- data/examples/bird_wars/game.rb +434 -0
- data/examples/bird_wars/html/chest.rhtml +37 -0
- data/examples/bird_wars/html/combat.rhtml +38 -0
- data/examples/bird_wars/html/fight.rhtml +71 -0
- data/examples/bird_wars/html/fridge.rhtml +31 -0
- data/examples/bird_wars/html/help.rhtml +30 -0
- data/examples/bird_wars/html/house.rhtml +36 -0
- data/examples/bird_wars/html/images/albatross.jpg +0 -0
- data/examples/bird_wars/html/images/alka_seltzer_small.png +0 -0
- data/examples/bird_wars/html/images/bazooka_small.png +0 -0
- data/examples/bird_wars/html/images/bb_gun_small.png +0 -0
- data/examples/bird_wars/html/images/cat_small.png +0 -0
- data/examples/bird_wars/html/images/combat.png +0 -0
- data/examples/bird_wars/html/images/crossbow_small.png +0 -0
- data/examples/bird_wars/html/images/cuckoo.jpg +0 -0
- data/examples/bird_wars/html/images/fridge.png +0 -0
- data/examples/bird_wars/html/images/gull.jpg +0 -0
- data/examples/bird_wars/html/images/house.jpg +0 -0
- data/examples/bird_wars/html/images/items.png +0 -0
- data/examples/bird_wars/html/images/not_found.png +0 -0
- data/examples/bird_wars/html/images/note.jpg +0 -0
- data/examples/bird_wars/html/images/oil_small.png +0 -0
- data/examples/bird_wars/html/images/one_stone_small.png +0 -0
- data/examples/bird_wars/html/images/owl.jpg +0 -0
- data/examples/bird_wars/html/images/poisoned_seeds_small.png +0 -0
- data/examples/bird_wars/html/images/rice_small.png +0 -0
- data/examples/bird_wars/html/images/shotgun_small.png +0 -0
- data/examples/bird_wars/html/images/slingshot_small.png +0 -0
- data/examples/bird_wars/html/images/soda_rings_small.png +0 -0
- data/examples/bird_wars/html/images/spear_small.png +0 -0
- data/examples/bird_wars/html/images/stork.jpg +0 -0
- data/examples/bird_wars/html/images/weapons.png +0 -0
- data/examples/bird_wars/html/images/woodpecker.jpg +0 -0
- data/examples/bird_wars/html/images/you.jpg +0 -0
- data/examples/bird_wars/html/index.rhtml +13 -0
- data/examples/bird_wars/html/weapons.rhtml +35 -0
- data/examples/cli/blackjack.rb +86 -0
- data/examples/cli/go.rb +93 -0
- data/examples/cli/space_trader2/planet_data +12280 -0
- data/examples/cli/space_trader2/space_trader2.rb +248 -0
- data/examples/cli/space_trader2/world.rb +127 -0
- data/examples/cli/spacetrader.rb +262 -0
- data/examples/cli/yahtzee.rb +161 -0
- data/examples/galactic_courier/Rakefile +9 -0
- data/examples/galactic_courier/bin/galactic_courier.rb +44 -0
- data/examples/galactic_courier/html/console.rhtml +15 -0
- data/examples/galactic_courier/html/images/barren.jpg +0 -0
- data/examples/galactic_courier/html/images/industrial.jpg +0 -0
- data/examples/galactic_courier/html/images/jungle.jpg +0 -0
- data/examples/galactic_courier/html/images/oceanic.jpg +0 -0
- data/examples/galactic_courier/html/images/tundra.jpg +0 -0
- data/examples/galactic_courier/html/images/volcanic.jpg +0 -0
- data/examples/galactic_courier/lib/galaxy.rb +64 -0
- data/examples/galactic_courier/lib/planet.rb +30 -0
- data/examples/galactic_courier/lib/sector.rb +84 -0
- data/examples/galactic_courier/lib/station.rb +18 -0
- data/examples/galactic_courier/test/tc_galaxy.rb +24 -0
- data/examples/galactic_courier/test/tc_planet.rb +22 -0
- data/examples/galactic_courier/test/tc_sector.rb +55 -0
- data/examples/galactic_courier/test/ts_all.rb +12 -0
- data/examples/gambit_mail/html/compose.rhtml +39 -0
- data/examples/gambit_mail/html/index.rhtml +3 -0
- data/examples/gambit_mail/html/mailbox.rhtml +47 -0
- data/examples/gambit_mail/html/message.rhtml +34 -0
- data/examples/gambit_mail/mail.rb +75 -0
- data/lib/gambit.rb +10 -0
- data/lib/gambit/server.rb +269 -0
- data/lib/gambit/server/gambiterror.rb +28 -0
- data/lib/gambit/server/game.rb +185 -0
- data/lib/gambit/server/game/eventform.rb +174 -0
- data/lib/gambit/server/message.rb +85 -0
- data/lib/gambit/server/player.rb +40 -0
- data/lib/gambit/tools.rb +13 -0
- data/lib/gambit/tools/board.rb +275 -0
- data/lib/gambit/tools/cards.rb +11 -0
- data/lib/gambit/tools/cards/card.rb +158 -0
- data/lib/gambit/tools/cards/deck.rb +99 -0
- data/lib/gambit/tools/cards/hand.rb +86 -0
- data/lib/gambit/tools/cards/pile.rb +107 -0
- data/lib/gambit/tools/currency.rb +148 -0
- data/lib/gambit/tools/dice.rb +219 -0
- data/lib/gambit/tools/movehistory.rb +164 -0
- data/lib/gambit/tools/scorecard.rb +333 -0
- data/lib/gambit/viewable.rb +71 -0
- data/setup.rb +1360 -0
- data/test/tc_board.rb +167 -0
- data/test/tc_cards.rb +182 -0
- data/test/tc_currency.rb +99 -0
- data/test/tc_dice.rb +83 -0
- data/test/tc_error.rb +34 -0
- data/test/tc_event.rb +367 -0
- data/test/tc_game.rb +29 -0
- data/test/tc_message.rb +35 -0
- data/test/tc_movehistory.rb +38 -0
- data/test/tc_player.rb +60 -0
- data/test/tc_scorecard.rb +112 -0
- data/test/tc_views.rb +353 -0
- data/test/test_game.rb +19 -0
- data/test/test_view.rhtml +2 -0
- data/test/ts_all.rb +12 -0
- data/test/ts_server.rb +14 -0
- data/test/ts_tools.rb +14 -0
- metadata +183 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
# player.rb
|
4
|
+
#
|
5
|
+
# Created by Gregory Brown on 2005-06-04.
|
6
|
+
# Copyright 2005 smtose.org. All rights reserved.
|
7
|
+
|
8
|
+
require "webrick"
|
9
|
+
require "gambit/viewable"
|
10
|
+
|
11
|
+
module Gambit
|
12
|
+
class Server < WEBrick::HTTPServer
|
13
|
+
class Player
|
14
|
+
def initialize( name, password )
|
15
|
+
@name = name
|
16
|
+
@password = password
|
17
|
+
@mailbox = Array.new
|
18
|
+
@notes = Array.new
|
19
|
+
|
20
|
+
@game_date = Hash.new
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :name
|
24
|
+
attr_reader :mailbox, :notes
|
25
|
+
|
26
|
+
def []( key )
|
27
|
+
@game_date[key]
|
28
|
+
end
|
29
|
+
|
30
|
+
def []=( key, value )
|
31
|
+
@game_date[key] = value
|
32
|
+
end
|
33
|
+
|
34
|
+
def login?( password )
|
35
|
+
@password == password
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/gambit/tools.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
# tools.rb
|
4
|
+
#
|
5
|
+
# Created by James Edward Gray II on 2005-05-30.
|
6
|
+
# Copyright 2005 Gray Productions. All rights reserved.
|
7
|
+
|
8
|
+
require "gambit/tools/board"
|
9
|
+
require "gambit/tools/cards"
|
10
|
+
require "gambit/tools/currency"
|
11
|
+
require "gambit/tools/dice"
|
12
|
+
require "gambit/tools/movehistory"
|
13
|
+
require "gambit/tools/scorecard"
|
@@ -0,0 +1,275 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
# board.rb
|
4
|
+
#
|
5
|
+
# Created by Gregory Brown on May 29, 2004.
|
6
|
+
# Copyright 2005 smtose.org. All rights reserved.
|
7
|
+
|
8
|
+
require "gambit/viewable"
|
9
|
+
|
10
|
+
module Gambit
|
11
|
+
module Tools
|
12
|
+
# A tool for managing a two-dimensional game board.
|
13
|
+
class Board
|
14
|
+
include Gambit::Viewable
|
15
|
+
register_view(:gambit_html, <<-END_HTML_VIEW.gsub(/^\t+/, ""))
|
16
|
+
<table class="board">
|
17
|
+
% each_with_location(true) do |sq, loc|
|
18
|
+
% x, y = parse_location(loc)
|
19
|
+
% if x.zero?
|
20
|
+
<tr id="row<%= loc[/\\d+/] %>">
|
21
|
+
% end
|
22
|
+
<%= "\\t" %><td id="<%= loc %>"><%= sq || "%nbsp;" %></td>
|
23
|
+
% if x == @board.first.size - 1
|
24
|
+
% if y == @board.size - 1
|
25
|
+
<%= "</tr>" %>
|
26
|
+
% else
|
27
|
+
</tr>
|
28
|
+
% end
|
29
|
+
% end
|
30
|
+
% end
|
31
|
+
</table>
|
32
|
+
END_HTML_VIEW
|
33
|
+
register_view(:gambit_text, <<-END_TEXT_VIEW.gsub(/^\t+/, ""))
|
34
|
+
% widths = Array.new
|
35
|
+
% each_with_location do |sq, loc|
|
36
|
+
% i = parse_location(loc).first
|
37
|
+
% w = sq.to_s.length
|
38
|
+
% widths[i] = w if widths[i].nil? or w > widths[i]
|
39
|
+
% end
|
40
|
+
% each_with_location(true) do |sq, loc|
|
41
|
+
% x, y = parse_location(loc)
|
42
|
+
<%= "%\#{widths[x]}s" % sq %>
|
43
|
+
% if x == @board.first.size - 1
|
44
|
+
<%= "\\n" %>
|
45
|
+
% else
|
46
|
+
<%= ' ' %>
|
47
|
+
% end
|
48
|
+
% end
|
49
|
+
END_TEXT_VIEW
|
50
|
+
|
51
|
+
#
|
52
|
+
# Creates a new Board of _x_dim_ by _y_dim_ with an optional _fill_
|
53
|
+
# object at each location. (The _fill_ is dup()ed as it is placed.)
|
54
|
+
#
|
55
|
+
def initialize( x_dim, y_dim, fill = nil )
|
56
|
+
@board = Array.new(x_dim) { Array.new(y_dim) };
|
57
|
+
@include_diagonals = true;
|
58
|
+
unless(fill.nil?)
|
59
|
+
each_location do |loc|
|
60
|
+
self[loc] = fill.dup
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# When set (default), diagonals are considered neighboring squares.
|
66
|
+
attr_accessor :include_diagonals
|
67
|
+
|
68
|
+
# Returns a row count.
|
69
|
+
def rows( )
|
70
|
+
@board[0].length
|
71
|
+
end
|
72
|
+
|
73
|
+
# Returns a column count.
|
74
|
+
def cols( )
|
75
|
+
@board.length
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
# Returns the x and y indices of a given location, as indices or
|
80
|
+
# chess notation.
|
81
|
+
#
|
82
|
+
# :call-seq:
|
83
|
+
# parse_location(chess_notation_str) -> x, y
|
84
|
+
# parse_location(x, y) -> x, y
|
85
|
+
#
|
86
|
+
def parse_location( *location )
|
87
|
+
if location.length == 1
|
88
|
+
letters = location.first[/[a-z]+/].split("").
|
89
|
+
map { |l| l[0] - ?a }.reverse
|
90
|
+
total = 0
|
91
|
+
letters.each_with_index do |letter, index|
|
92
|
+
total += letter + index * 26
|
93
|
+
end
|
94
|
+
x = total
|
95
|
+
y = location.first[1..-1].to_i - 1
|
96
|
+
else
|
97
|
+
x = location[0]
|
98
|
+
y = location[1]
|
99
|
+
end
|
100
|
+
return x, y
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
# Returns the contents of a square. Arguments can be anything
|
105
|
+
# parse_location() understands.
|
106
|
+
#
|
107
|
+
def []( *coordinate )
|
108
|
+
x,y = parse_location(*coordinate)
|
109
|
+
return @board[x][y]
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
# Sets the contents of a square. Arguments can be anything
|
114
|
+
# parse_location() understands.
|
115
|
+
#
|
116
|
+
def []=( *values )
|
117
|
+
item = values.pop
|
118
|
+
x,y = parse_location(*values)
|
119
|
+
@board[x][y] = item
|
120
|
+
end
|
121
|
+
|
122
|
+
#
|
123
|
+
# Returns an Array of neighboring locations, in chess notation.
|
124
|
+
# Arguments can be anything parse_location() understands.
|
125
|
+
#
|
126
|
+
def neighboring_locations( *coordinate )
|
127
|
+
x,y = parse_location(*coordinate);
|
128
|
+
neighbor_locations = []
|
129
|
+
[-1,0,1].each do |xi|
|
130
|
+
[-1,0,1].each do |yi|
|
131
|
+
next if (xi == 0 and yi == 0)
|
132
|
+
next if !@include_diagonals and
|
133
|
+
((xi + yi).abs != 1)
|
134
|
+
if valid?(x + xi, y + yi)
|
135
|
+
neighbor_locations << to_chess(x + xi,y + yi)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
return neighbor_locations
|
140
|
+
end
|
141
|
+
|
142
|
+
#
|
143
|
+
# Returns an Array of neighboring square contents, in chess
|
144
|
+
# notation. Arguments can be anything parse_location() understands.
|
145
|
+
#
|
146
|
+
def neighbors( *coordinate )
|
147
|
+
neighbors = []
|
148
|
+
nl = neighboring_locations(*coordinate)
|
149
|
+
nl.each do |loc|
|
150
|
+
unless self[loc].nil?
|
151
|
+
neighbors << self[loc]
|
152
|
+
end
|
153
|
+
end
|
154
|
+
return neighbors;
|
155
|
+
end
|
156
|
+
|
157
|
+
# Converts _x_ and _y_ to a String of chess notation.
|
158
|
+
def to_chess( x, y )
|
159
|
+
(x + ?a).chr + (y+1).to_s
|
160
|
+
end
|
161
|
+
|
162
|
+
#
|
163
|
+
# Ensures that _coordinate_ is within the bounds of this Board.
|
164
|
+
# Arguments can be anything parse_location() understands.
|
165
|
+
#
|
166
|
+
def valid?( *coordinate )
|
167
|
+
x,y = parse_location(*coordinate);
|
168
|
+
(x >= 0 && x < cols() && y >= 0 && y < rows()) ? true : false
|
169
|
+
end
|
170
|
+
|
171
|
+
#
|
172
|
+
# Moves the contents of the first square, to the second square.
|
173
|
+
# Arguments can be anything parse_location() understands.
|
174
|
+
#
|
175
|
+
def move( *coordinates )
|
176
|
+
if coordinates.length == 2
|
177
|
+
self[coordinates[1]] = self[coordinates[0]].clone
|
178
|
+
self[coordinates[0]] = nil
|
179
|
+
else
|
180
|
+
self[coordinates[2],coordinates[3]].clone =
|
181
|
+
self[coordinates[0],coordinates[1]]
|
182
|
+
self[coordinates[0],coordinates[1]] = nil
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
#
|
187
|
+
# Iterate over the columns of this Board. Pass +true+ to _reverse_
|
188
|
+
# to swap the iteration order.
|
189
|
+
#
|
190
|
+
def each_col( reverse = false, &block )
|
191
|
+
if reverse
|
192
|
+
@board.reverse.each(&block)
|
193
|
+
else
|
194
|
+
@board.each(&block)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
#
|
199
|
+
# Iterate over the rows of this Board. Pass +true+ to _reverse_ to
|
200
|
+
# swap the iteration order.
|
201
|
+
#
|
202
|
+
def each_row( reverse = true )
|
203
|
+
if reverse
|
204
|
+
((0 ... @board[0].length).to_a.reverse).each do |index|
|
205
|
+
yield @board.collect{ |column| column[index] }
|
206
|
+
end
|
207
|
+
else
|
208
|
+
(0 ... @board[0].length).each do |index|
|
209
|
+
yield @board.collect{ |column| column[index] }
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
include Enumerable
|
215
|
+
|
216
|
+
#
|
217
|
+
# Iterate over the squares of this Board. Pass +true+ to _reverse_
|
218
|
+
# to swap the iteration order.
|
219
|
+
#
|
220
|
+
def each( reverse = false, &block )
|
221
|
+
if reverse
|
222
|
+
((0 ... @board[0].length).to_a.reverse).each do |index|
|
223
|
+
@board.collect do |column|
|
224
|
+
column[index]
|
225
|
+
end.each(&block)
|
226
|
+
end
|
227
|
+
else
|
228
|
+
@board[0].each_index do |index|
|
229
|
+
@board.collect{ |column| column[index] }.each(&block)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
#
|
235
|
+
# Iterate over the locations of this Board. Pass +true+ to
|
236
|
+
# _reverse_ to swap the iteration order.
|
237
|
+
#
|
238
|
+
def each_location( reverse = false )
|
239
|
+
if reverse
|
240
|
+
(@board[0].length - 1).downto(0) do |row|
|
241
|
+
0.upto(@board.length-1) do |column|
|
242
|
+
yield to_chess(column,row)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
else
|
246
|
+
0.upto(@board[0].length-1) do |row|
|
247
|
+
0.upto(@board.length-1) do |column|
|
248
|
+
yield to_chess(column,row)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
#
|
255
|
+
# Iterate over the squares and locations of this Board. Pass +true+
|
256
|
+
# to _reverse_ to swap the iteration order.
|
257
|
+
#
|
258
|
+
def each_with_location( reverse = false )
|
259
|
+
if reverse
|
260
|
+
(@board[0].length - 1).downto(0) do |row|
|
261
|
+
0.upto(@board.length-1) do |column|
|
262
|
+
yield(@board[column][row], to_chess(column,row))
|
263
|
+
end
|
264
|
+
end
|
265
|
+
else
|
266
|
+
0.upto(@board[0].length-1) do |row|
|
267
|
+
0.upto(@board.length-1) do |column|
|
268
|
+
yield(@board[column][row], to_chess(column,row))
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
# cards.rb
|
4
|
+
#
|
5
|
+
# Created by James Edward Gray II on 2005-05-30.
|
6
|
+
# Copyright 2005 Gray Productions. All rights reserved.
|
7
|
+
|
8
|
+
require "gambit/tools/cards/card"
|
9
|
+
require "gambit/tools/cards/deck"
|
10
|
+
require "gambit/tools/cards/hand"
|
11
|
+
require "gambit/tools/cards/pile"
|
@@ -0,0 +1,158 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
# card.rb
|
4
|
+
#
|
5
|
+
# Created by James Edward Gray II on 2005-05-30.
|
6
|
+
# Copyright 2005 Gray Productions. All rights reserved.
|
7
|
+
|
8
|
+
require "gambit/viewable"
|
9
|
+
|
10
|
+
# The namespace for all three layers of the Gambit framework.
|
11
|
+
module Gambit
|
12
|
+
#
|
13
|
+
# The namespace for all the game creation tools (model layer) the Gambit
|
14
|
+
# framework.
|
15
|
+
#
|
16
|
+
module Tools
|
17
|
+
# The namespace for all card game tools.
|
18
|
+
module Cards
|
19
|
+
#
|
20
|
+
# The base class for all Card objects using the Gambit tools
|
21
|
+
# framework.
|
22
|
+
#
|
23
|
+
class Card
|
24
|
+
include Gambit::Viewable
|
25
|
+
|
26
|
+
#
|
27
|
+
# Subclasses must provide a creation iterator that will yield
|
28
|
+
# each Card in a Deck.
|
29
|
+
#
|
30
|
+
def self.each( )
|
31
|
+
raise NotImplementedError,
|
32
|
+
"Subclasses must override self.each()."
|
33
|
+
end
|
34
|
+
|
35
|
+
include Comparable
|
36
|
+
|
37
|
+
# Sublclasses must provide a comparator method.
|
38
|
+
def <=>( other )
|
39
|
+
raise NotImplementedError, "Subclasses must override <=>()."
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class StandardCard < Card
|
44
|
+
register_view(:gambit_html, <<-END_HTML_VIEW.gsub(/\t{4}/, ""))
|
45
|
+
<dl class="card">
|
46
|
+
<dt>Value:</dt>
|
47
|
+
<dd><%= @value %></dd>
|
48
|
+
|
49
|
+
<dt>Suit:</dt>
|
50
|
+
<dd><%= @suit %></dd>
|
51
|
+
</dl>
|
52
|
+
END_HTML_VIEW
|
53
|
+
register_view(:gambit_text, "<%= name %>")
|
54
|
+
|
55
|
+
@@suit_order = [:clubs, :diamonds, :hearts, :spades]
|
56
|
+
#
|
57
|
+
# Set a suit order. Default is:
|
58
|
+
#
|
59
|
+
# [:clubs, :diamonds, :hearts, :spades]
|
60
|
+
#
|
61
|
+
def self.suit_order=( suits ) @@suit_order = suits end
|
62
|
+
# Fetch the current suit order.
|
63
|
+
def self.suit_order( ) @@suit_order end
|
64
|
+
|
65
|
+
@@value_order = [ :ace, 2, 3, 4, 5, 6, 7, 8, 9, 10,
|
66
|
+
:jack, :queen, :king ]
|
67
|
+
#
|
68
|
+
# Set a card value order. Default is:
|
69
|
+
#
|
70
|
+
# [ :ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, :jack, :queen, :king ]
|
71
|
+
#
|
72
|
+
def self.value_order=( values ) @@value_order = values end
|
73
|
+
# Fetch the current card value order.
|
74
|
+
def self.value_order( ) @@value_order end
|
75
|
+
|
76
|
+
@@use_jokers = false
|
77
|
+
# When set (not the default), jokers will be used.
|
78
|
+
def self.use_jokers=( use ) @@use_jokers = use end
|
79
|
+
# Determine if jokers are being used.
|
80
|
+
def self.use_jokers( ) @@use_jokers end
|
81
|
+
|
82
|
+
@@jokers_are_high = true
|
83
|
+
#
|
84
|
+
# When set (default), the jokers are considered high cards in
|
85
|
+
# sorting.
|
86
|
+
#
|
87
|
+
def self.jokers_are_high=( high ) @@jokers_are_high = high end
|
88
|
+
# Determine if jokers are high.
|
89
|
+
def self.jokers_are_high( ) @@jokers_are_high end
|
90
|
+
|
91
|
+
# Yields one of each possible card, in turn for Deck creation.
|
92
|
+
def self.each( )
|
93
|
+
@@suit_order.each do |suit|
|
94
|
+
@@value_order.each do |value|
|
95
|
+
yield new(value, suit)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
if @@use_jokers
|
100
|
+
yield new(:joker, :red)
|
101
|
+
yield new(:joker, :black)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Creates a new StandardCard of _value_ and _suit_.
|
106
|
+
def initialize( value, suit )
|
107
|
+
@value, @suit = value, suit
|
108
|
+
end
|
109
|
+
|
110
|
+
# The value or name of this card.
|
111
|
+
attr_reader :value
|
112
|
+
# The suit of this card.
|
113
|
+
attr_reader :suit
|
114
|
+
|
115
|
+
# Support for ranking (and sorting) the cards.
|
116
|
+
def <=>( other )
|
117
|
+
if self == other
|
118
|
+
0
|
119
|
+
elsif @value == :joker or other.value == :joker
|
120
|
+
if @value == :joker and other.value == :joker
|
121
|
+
if @suit == :red then -1 else 1 end
|
122
|
+
elsif @value == :joker
|
123
|
+
if @@jokers_are_high then 1 else -1 end
|
124
|
+
else
|
125
|
+
if @@jokers_are_high then -1 else 1 end
|
126
|
+
end
|
127
|
+
else
|
128
|
+
suit_rank = self.class.suit_order.index(@suit)
|
129
|
+
other_suit_rank =
|
130
|
+
self.class.suit_order.index(other.suit)
|
131
|
+
|
132
|
+
if suit_rank != other_suit_rank
|
133
|
+
suit_rank <=> other_suit_rank
|
134
|
+
else
|
135
|
+
self.class.value_order.index(@value) <=>
|
136
|
+
self.class.value_order.index(other.value)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# Compares this card with _other_ for equality.
|
142
|
+
def ==( other )
|
143
|
+
@value == other.value and @suit == other.suit
|
144
|
+
end
|
145
|
+
|
146
|
+
# Returns the String name of this card (human readable).
|
147
|
+
def name( )
|
148
|
+
if @value == :joker
|
149
|
+
"The #{@suit.to_s.capitalize} #{@value.to_s.capitalize}"
|
150
|
+
else
|
151
|
+
"The #{@value.to_s.capitalize} " +
|
152
|
+
"of #{@suit.to_s.capitalize}"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|