gambit 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.
Files changed (111) hide show
  1. data/AUTHORS +2 -0
  2. data/CHANGELOG +7 -0
  3. data/COPYING +340 -0
  4. data/INSTALL +23 -0
  5. data/LICENSE +7 -0
  6. data/README +25 -0
  7. data/Rakefile +87 -0
  8. data/TODO +6 -0
  9. data/examples/bird_wars/game.rb +434 -0
  10. data/examples/bird_wars/html/chest.rhtml +37 -0
  11. data/examples/bird_wars/html/combat.rhtml +38 -0
  12. data/examples/bird_wars/html/fight.rhtml +71 -0
  13. data/examples/bird_wars/html/fridge.rhtml +31 -0
  14. data/examples/bird_wars/html/help.rhtml +30 -0
  15. data/examples/bird_wars/html/house.rhtml +36 -0
  16. data/examples/bird_wars/html/images/albatross.jpg +0 -0
  17. data/examples/bird_wars/html/images/alka_seltzer_small.png +0 -0
  18. data/examples/bird_wars/html/images/bazooka_small.png +0 -0
  19. data/examples/bird_wars/html/images/bb_gun_small.png +0 -0
  20. data/examples/bird_wars/html/images/cat_small.png +0 -0
  21. data/examples/bird_wars/html/images/combat.png +0 -0
  22. data/examples/bird_wars/html/images/crossbow_small.png +0 -0
  23. data/examples/bird_wars/html/images/cuckoo.jpg +0 -0
  24. data/examples/bird_wars/html/images/fridge.png +0 -0
  25. data/examples/bird_wars/html/images/gull.jpg +0 -0
  26. data/examples/bird_wars/html/images/house.jpg +0 -0
  27. data/examples/bird_wars/html/images/items.png +0 -0
  28. data/examples/bird_wars/html/images/not_found.png +0 -0
  29. data/examples/bird_wars/html/images/note.jpg +0 -0
  30. data/examples/bird_wars/html/images/oil_small.png +0 -0
  31. data/examples/bird_wars/html/images/one_stone_small.png +0 -0
  32. data/examples/bird_wars/html/images/owl.jpg +0 -0
  33. data/examples/bird_wars/html/images/poisoned_seeds_small.png +0 -0
  34. data/examples/bird_wars/html/images/rice_small.png +0 -0
  35. data/examples/bird_wars/html/images/shotgun_small.png +0 -0
  36. data/examples/bird_wars/html/images/slingshot_small.png +0 -0
  37. data/examples/bird_wars/html/images/soda_rings_small.png +0 -0
  38. data/examples/bird_wars/html/images/spear_small.png +0 -0
  39. data/examples/bird_wars/html/images/stork.jpg +0 -0
  40. data/examples/bird_wars/html/images/weapons.png +0 -0
  41. data/examples/bird_wars/html/images/woodpecker.jpg +0 -0
  42. data/examples/bird_wars/html/images/you.jpg +0 -0
  43. data/examples/bird_wars/html/index.rhtml +13 -0
  44. data/examples/bird_wars/html/weapons.rhtml +35 -0
  45. data/examples/cli/blackjack.rb +86 -0
  46. data/examples/cli/go.rb +93 -0
  47. data/examples/cli/space_trader2/planet_data +12280 -0
  48. data/examples/cli/space_trader2/space_trader2.rb +248 -0
  49. data/examples/cli/space_trader2/world.rb +127 -0
  50. data/examples/cli/spacetrader.rb +262 -0
  51. data/examples/cli/yahtzee.rb +161 -0
  52. data/examples/galactic_courier/Rakefile +9 -0
  53. data/examples/galactic_courier/bin/galactic_courier.rb +44 -0
  54. data/examples/galactic_courier/html/console.rhtml +15 -0
  55. data/examples/galactic_courier/html/images/barren.jpg +0 -0
  56. data/examples/galactic_courier/html/images/industrial.jpg +0 -0
  57. data/examples/galactic_courier/html/images/jungle.jpg +0 -0
  58. data/examples/galactic_courier/html/images/oceanic.jpg +0 -0
  59. data/examples/galactic_courier/html/images/tundra.jpg +0 -0
  60. data/examples/galactic_courier/html/images/volcanic.jpg +0 -0
  61. data/examples/galactic_courier/lib/galaxy.rb +64 -0
  62. data/examples/galactic_courier/lib/planet.rb +30 -0
  63. data/examples/galactic_courier/lib/sector.rb +84 -0
  64. data/examples/galactic_courier/lib/station.rb +18 -0
  65. data/examples/galactic_courier/test/tc_galaxy.rb +24 -0
  66. data/examples/galactic_courier/test/tc_planet.rb +22 -0
  67. data/examples/galactic_courier/test/tc_sector.rb +55 -0
  68. data/examples/galactic_courier/test/ts_all.rb +12 -0
  69. data/examples/gambit_mail/html/compose.rhtml +39 -0
  70. data/examples/gambit_mail/html/index.rhtml +3 -0
  71. data/examples/gambit_mail/html/mailbox.rhtml +47 -0
  72. data/examples/gambit_mail/html/message.rhtml +34 -0
  73. data/examples/gambit_mail/mail.rb +75 -0
  74. data/lib/gambit.rb +10 -0
  75. data/lib/gambit/server.rb +269 -0
  76. data/lib/gambit/server/gambiterror.rb +28 -0
  77. data/lib/gambit/server/game.rb +185 -0
  78. data/lib/gambit/server/game/eventform.rb +174 -0
  79. data/lib/gambit/server/message.rb +85 -0
  80. data/lib/gambit/server/player.rb +40 -0
  81. data/lib/gambit/tools.rb +13 -0
  82. data/lib/gambit/tools/board.rb +275 -0
  83. data/lib/gambit/tools/cards.rb +11 -0
  84. data/lib/gambit/tools/cards/card.rb +158 -0
  85. data/lib/gambit/tools/cards/deck.rb +99 -0
  86. data/lib/gambit/tools/cards/hand.rb +86 -0
  87. data/lib/gambit/tools/cards/pile.rb +107 -0
  88. data/lib/gambit/tools/currency.rb +148 -0
  89. data/lib/gambit/tools/dice.rb +219 -0
  90. data/lib/gambit/tools/movehistory.rb +164 -0
  91. data/lib/gambit/tools/scorecard.rb +333 -0
  92. data/lib/gambit/viewable.rb +71 -0
  93. data/setup.rb +1360 -0
  94. data/test/tc_board.rb +167 -0
  95. data/test/tc_cards.rb +182 -0
  96. data/test/tc_currency.rb +99 -0
  97. data/test/tc_dice.rb +83 -0
  98. data/test/tc_error.rb +34 -0
  99. data/test/tc_event.rb +367 -0
  100. data/test/tc_game.rb +29 -0
  101. data/test/tc_message.rb +35 -0
  102. data/test/tc_movehistory.rb +38 -0
  103. data/test/tc_player.rb +60 -0
  104. data/test/tc_scorecard.rb +112 -0
  105. data/test/tc_views.rb +353 -0
  106. data/test/test_game.rb +19 -0
  107. data/test/test_view.rhtml +2 -0
  108. data/test/ts_all.rb +12 -0
  109. data/test/ts_server.rb +14 -0
  110. data/test/ts_tools.rb +14 -0
  111. 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
@@ -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