gambit 0.1.0

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