srs_game 0.Alexis

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.
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ doc
2
+ tmp
3
+ *~
4
+ *.save
5
+ .rbx
6
+ .yardoc
7
+ Gemfile.lock
8
+ coverage
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm: ["1.9.3", "1.9.2"]
3
+ branches: { "only" : [ "master", "development" ] }
data/.yardopts ADDED
@@ -0,0 +1,2 @@
1
+ lib/srs_game.rb
2
+ *.md
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "rake", "~> 0.9.2.2"
4
+ gem "term-ansicolor", "~> 1.0.7"
5
+ gem "rspec", "~> 2.9.0", :group => :test
6
+ gem "simplecov", "~> 0.6.1", :require => false, :group => :test
data/LICENSE ADDED
@@ -0,0 +1,12 @@
1
+ Copyright (c) 2012 Jackson Willis
2
+
3
+ This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
4
+
5
+ Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
6
+
7
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
8
+ If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
9
+
10
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
11
+
12
+ 3. This notice may not be removed or altered from any source distribution.
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ SRS GAME
2
+ ========
3
+
4
+ [![Build Status](https://secure.travis-ci.org/jacksonwillis/srs_game.png?branch=master)](https://secure.travis-ci.org/jacksonwillis/srs_game)
5
+ [![Dependency Status](https://gemnasium.com/jacksonwillis/srs_game.png)](https://gemnasium.com/jacksonwillis/srs_game)
6
+
7
+ ![SRS GAME logo](https://github.com/downloads/jacksonwillis/srs_game/srs_game.png)
8
+
9
+ Welcome
10
+ -------
11
+
12
+ SRS GAME is a framework and a collection of text-based games written in the [Ruby](http://www.ruby-lang.org/) 1.9 programming language.
13
+
14
+ If you find a bug, feel free to [create an issue](https://github.com/jacksonwillis/srs_game/issues/new).
15
+
16
+ Installation
17
+ ------------
18
+
19
+ *Main article: [Installation](https://github.com/jacksonwillis/srs_game/wiki/Installation)*
20
+
21
+ Playing the game
22
+ ----------------
23
+
24
+ $ rake play:tamera # Play as the goddess Tamera
25
+ $ rake play:tia # Play as a follower of the Cult of Tia
26
+
27
+ Running a server
28
+ ----------------
29
+
30
+ $ rake server:tamera HOST=127.0.0.1 PORT=5446 MAX_CONNECTIONS=4
31
+
32
+ Testing
33
+ -------
34
+
35
+ To test, just run `rake`
36
+ or check out the [automated tests](https://secure.travis-ci.org/jacksonwillis/srs_game).
37
+
38
+ API
39
+ ---
40
+
41
+ irb > require "srs_game/tamera"
42
+ => true
43
+ irb > game = Game.new(Tamera, color: false)
44
+ => #<SRSGame::Game:0x000000022f1337>
45
+ irb > game.send "look"
46
+ => "You find yourself in the Main Room.\nItems here are an AM/FM Radio.\nExits are east and west."
47
+ irb > game.send "north"
48
+ => "NOPE. Can't go that way."
49
+ irb > game.send "west"
50
+ => ""
51
+ irb > game.room
52
+ => #<SRSGame::Location "the West Room" @items=[] exits=["east", "west"]>
53
+
54
+ License
55
+ -------
56
+
57
+ SRS GAME is released under the zlib license. See [LICENSE](https://github.com/jacksonwillis/srs_game/blob/master/LICENSE)
data/Rakefile.rb ADDED
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: UTF-8 -*-
3
+ # This file is part of SRS GAME <http://github.com/jacksonwillis/srs_game/>.
4
+
5
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
6
+ require "srs_game"
7
+ require "rake"
8
+
9
+ require "bundler/gem_tasks"
10
+
11
+ namespace :play do
12
+ desc "Play as a follower of the Cult of Tia"
13
+ task :tia do
14
+ require "srs_game/tia"
15
+ Game.new(Tia, color: true).play
16
+ end
17
+
18
+ desc "Play as the goddess Tamera"
19
+ task :tamera do
20
+ require "srs_game/tamera"
21
+ Game.new(Tamera, color: true).play
22
+ end
23
+ end
24
+
25
+ namespace :server do
26
+ desc "Telnet server for Tia"
27
+ task :tia do
28
+ require "srs_game/tia"
29
+ SRServer.play(Tia, ENV["PORT"], ENV["HOST"], ENV["MAX_CONNECTIONS"])
30
+ end
31
+
32
+ desc "Telnet server for Tamera"
33
+ task :tamera do
34
+ require "srs_game/tamera"
35
+ SRServer.play(Tamera, ENV["PORT"], ENV["HOST"], ENV["MAX_CONNECTIONS"])
36
+ end
37
+ end
38
+
39
+ require "rspec/core/rake_task"
40
+ RSpec::Core::RakeTask.new
41
+
42
+ task :default => :spec
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: UTF-8 -*-
3
+ # This file is part of SRS GAME <http://github.com/jacksonwillis/srs_game/>.
4
+
5
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
6
+ require "srs_game"
7
+ include SRSGame
8
+
9
+ module PokemonClone
10
+ class Computer < Item
11
+ interactable_as :computer
12
+ name "red's computer"
13
+ end
14
+
15
+ class Bed < Item
16
+ interactable_as :bed
17
+ name "YOUR BED"
18
+ end
19
+
20
+ def greeting
21
+ " /\"*-.\n" << \
22
+ " / `-.\n" << \
23
+ " / `-.\n" << \
24
+ " / `-.\n" << \
25
+ " `\"*-._ `-.\n" << \
26
+ " \"*-. .-'\n" << \
27
+ " .-' .-'\n" << \
28
+ " <' <'\n" << \
29
+ " `-. `-. .\n" << \
30
+ " .' .-' $\n" << \
31
+ " _ .' .-' bug :$;\n" << \
32
+ " T$bp.L.-*\"\"*-._ d$b\n" << \
33
+ " `TP `-. `-. : T$\n" << \
34
+ " .' `. `. `. ; ;\n" << \
35
+ " / `. \\ _. \\: :\n" << \
36
+ " / `..-\" ; |\n" << \
37
+ " : / ;\n" << \
38
+ " ; \\ / _ :\n" << \
39
+ " /`--'\\ .' $o$ |\n" << \
40
+ "/ / `./-, `\"' _ :\n" << \
41
+ "'-' : ; _ ' $o$ ;\n" << \
42
+ " ;Y\" |\"-. `\"' /\n" << \
43
+ " | `. L.' .-. /`*.\n" << \
44
+ " : `-. ; :' \\\n" << \
45
+ " ; :`*-._L.-'`-. :\n" << \
46
+ " : ; `-.*\n" << \
47
+ " \\ /\n" << \
48
+ " \"\" ~* PokemonClone.rb *~\n"
49
+ end
50
+
51
+ def main_room
52
+ house = L.new(:name => "outside your house")
53
+ house.in = L.new(:name => "in your living room")
54
+ house.in.up = L.new(:name => "at the top of your stairs")
55
+
56
+ room = house.in.up.north = L.new(:name => "at the threshold your room")
57
+ room.north = L.new(:name => "standing in the middle of your room", :items => [Bed.new])
58
+ room.north.west = L.new(:name => "at your computer", :items => [Computer.new])
59
+
60
+ house.south = L.new(:name => "at the Pallet Town plaza")
61
+ house
62
+ end
63
+
64
+ class Commands < SRSGame::Commands
65
+ end
66
+ end
67
+
68
+ SRSGame::Game.new(PokemonClone, color: true).play if __FILE__ == $0
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: UTF-8 -*-
3
+ # This file is part of SRS GAME <http://github.com/jacksonwillis/srs_game/>.
4
+
5
+ $LOAD_PATH.unshift File.expand_path("../../", __FILE__)
6
+ require "srs_game"
7
+ include SRSGame
8
+
9
+ module SRSGame::Basic
10
+ def main_room
11
+ Location.new
12
+ end
13
+ end
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: UTF-8 -*-
3
+ # This file is part of SRS GAME <http://github.com/jacksonwillis/srs_game/>.
4
+
5
+ $LOAD_PATH.unshift File.expand_path("../../", __FILE__)
6
+ require "srs_game"
7
+ include SRSGame
8
+
9
+ # Play as the goddess Tamera
10
+ module SRSGame::Tamera
11
+ class BallaAssSpoon < Item
12
+ name "a Balla Ass Spoon"
13
+ interactable_as :spoon
14
+ end
15
+
16
+ class CrystalBall < Item
17
+ name "a Crystal Ball"
18
+ interactable_as :crystal
19
+ end
20
+
21
+ class Radio < Item
22
+ name "an AM/FM Radio"
23
+ interactable_as :radio
24
+ end
25
+
26
+ # Room where you begin in
27
+ def main_room
28
+ main = L.new do |l|
29
+ l.name = "in the Main Room"
30
+ l.items = [Radio.new]
31
+ end
32
+
33
+ main.east = L.new do |l|
34
+ l.name = "in the East Room"
35
+ l.items = [BallaAssSpoon.new, CrystalBall.new]
36
+ end
37
+
38
+ dungeon = main.east.south = L.new do |l|
39
+ l.name = "a creepy dungeon"
40
+ end
41
+
42
+ dungeon.south = L.new do |l|
43
+ l.name = "Hell"
44
+ end
45
+
46
+ west_room = main.west = L.new do |l|
47
+ l.name = "the West Room"
48
+ end
49
+
50
+ far_west = west_room.west = L.new do |l|
51
+ l.name = "the Far West Room"
52
+ end
53
+
54
+ far_west.north = L.new do |l|
55
+ l.name = "the North West Room"
56
+ end
57
+
58
+ return main
59
+ end
60
+
61
+ # Emitted before the game starts
62
+ def greeting
63
+ "\n ##### ##### ## # #### ######\n # # # # # # # # #\n # # # # # # # #### #####\n ##### ##### ###### # # #\n # # # # # # # # #\n # # # # # # #### ######\n\n\n ##### ######\n # # #\n ##### #####\n # # #\n # # #\n ##### ######\n\n\n ##### ####\n # # #\n # # #\n # # #\n # # #\n # ####\n\n\n ##### ## # # ###### ##### ##\n # # # ## ## # # # # #\n # # # # ## # ##### # # # #\n # ###### # # # ##### ######\n # # # # # # # # # #\n # # # # # ###### # # # #\n\n"
64
+ end
65
+ end
66
+
67
+ SRSGame.play Tamera if __FILE__ == $0
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: UTF-8 -*-
3
+ # This file is part of SRS GAME <http://github.com/jacksonwillis/srs_game/>.
4
+
5
+ # Not yet implemented
6
+ module SRSGame module Tia end end
7
+ raise "SRSGame::Tia is not yet implemented."
@@ -0,0 +1,3 @@
1
+ module SRSGame
2
+ VERSION = "0.Alexis"
3
+ end
data/lib/srs_game.rb ADDED
@@ -0,0 +1,429 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: UTF-8 -*-
3
+ # This file is part of SRS GAME <http://github.com/jacksonwillis/srs_game/>.
4
+
5
+ require "zlib"
6
+ require "base64"
7
+ require "readline"
8
+ require "gserver"
9
+ require "term/ansicolor"
10
+
11
+ include Term::ANSIColor
12
+
13
+ $LOAD_PATH.unshift File.expand_path("./", __FILE__)
14
+ require "srs_game/version"
15
+ require "srs_game/basic"
16
+
17
+ class Object
18
+ def blank?
19
+ if respond_to?(:empty?)
20
+ empty?
21
+ else
22
+ !self
23
+ end
24
+ end
25
+
26
+ def unblank?
27
+ !self.blank?
28
+ end
29
+
30
+ # Removes "_" from beginning of line and downcases it
31
+ def command_pp
32
+ to_s.gsub(/^_/, "").downcase
33
+ end
34
+
35
+ # From ActiveSupport[http://api.rubyonrails.org/classes/Array.html#method-i-to_sentence].
36
+ # Converts the array to a comma-separated sentence where the last element is joined by the connector word. Options:
37
+ # * :words_connector:: - The sign or word used to join the elements in arrays with two or more elements (default: ", ")
38
+ # * :two_words_connector:: - The sign or word used to join the elements in arrays with two elements (default: " and ")
39
+ # * :last_word_connector:: - The sign or word used to join the last element in arrays with three or more elements (default: ", and ")
40
+ # * :bold:: - Bolds the elements being joined. (default: false)
41
+ # @return [String]
42
+ def to_sentence(options = {})
43
+ words_connector = options[:words_connector] || ", "
44
+ two_words_connector = options[:two_words_connector] || " and "
45
+ last_word_connector = options[:last_word_connector] || ", and "
46
+
47
+ if options[:bold]
48
+ return to_sentence Array[self] unless respond_to? :map!
49
+
50
+ map!(&:to_s)
51
+ map!(&:bold)
52
+ end
53
+
54
+ case length
55
+ when 0
56
+ ""
57
+ when 1
58
+ self[0].to_s.dup
59
+ when 2
60
+ "#{self[0]}#{two_words_connector}#{self[1]}"
61
+ else
62
+ "#{self[0...-1].join(words_connector)}#{last_word_connector}#{self[-1]}"
63
+ end
64
+ end
65
+ end
66
+
67
+ class String
68
+ TRUE_WORDS = %w{t true yes y}
69
+ FALSE_WORDS = %w{f false no n}
70
+
71
+ # Convert to boolean value matching TRUE_WORDS or FALSE_WORDS
72
+ # @return [Boolean, nil]
73
+ def to_bool
74
+ dc = to_s.downcase
75
+
76
+ if TRUE_WORDS.include?(dc)
77
+ true
78
+ elsif FALSE_WORDS.include?(dc)
79
+ false
80
+ end
81
+ end
82
+
83
+ # Can the string be converted to a boolean value?
84
+ # @return [Boolean]
85
+ def boolean?
86
+ !to_bool.nil?
87
+ end
88
+
89
+ # Does the string represent a numeral in Ruby?
90
+ # @return [Boolean]
91
+ def numeric?
92
+ !!Float(self) rescue false
93
+ end
94
+
95
+ # Turn the string in to an array of arguments.
96
+ # It tries to convert words into booleans and floats. Example:
97
+ # "3.14 yes gaga false".args #=> [3.14, true, "gaga", false]
98
+ # @return [Array]
99
+ def args
100
+ strip.words.map do |arg|
101
+ next if arg.empty?
102
+
103
+ if arg.boolean?
104
+ arg.to_bool
105
+ elsif arg.numeric?
106
+ Float(arg)
107
+ else
108
+ arg
109
+ end
110
+ end
111
+ end
112
+
113
+ # Scans the string for groups of non-whitespace characters.
114
+ # @return [Array]
115
+ def words
116
+ scan(/\S+/)
117
+ end
118
+ end
119
+
120
+ class IO
121
+ def rainbow_say(str, greeting_speed = 50)
122
+ colors = [:red, :yellow, :green, :cyan, :blue, :magenta].cycle
123
+
124
+ str.each_line do |line|
125
+ print (line =~ /\S/ ? line.__send__(colors.next) : line)
126
+ sleep 1.0 / greeting_speed
127
+ end
128
+ end
129
+ end
130
+
131
+ module SRSGame
132
+ class DirectionError < ::TypeError; end
133
+ class DONE_WITH_SRS_GAME < ::SystemExit; end
134
+
135
+ # From Dwemthy's Array by _why the lucky stiff
136
+ # http://mislav.uniqpath.com/poignant-guide/dwemthy/
137
+ class Traitable
138
+ # Get a metaclass for this class
139
+ def self.metaclass; class << self; self; end; end
140
+
141
+ # Advanced metaprogramming code for nice, clean traits
142
+ def self.traits( *arr )
143
+ return @traits if arr.empty?
144
+
145
+ # 1. Set up accessors for each variable
146
+ attr_accessor *arr
147
+
148
+ # 2. Add a new class method to for each trait.
149
+ arr.each do |a|
150
+ metaclass.instance_eval do
151
+ define_method( a ) do |val|
152
+ @traits ||= {}
153
+ @traits[a] = val
154
+ end # define_method
155
+ end # instance_eval
156
+ end # each
157
+
158
+ # 3. For each traitable object, the `initialize' method
159
+ # should use the default number for each trait.
160
+ class_eval do
161
+ define_method( :initialize ) do
162
+ self.class.traits.each do |k,v|
163
+ instance_variable_set("@#{k}", v)
164
+ end
165
+ end
166
+ end
167
+
168
+ end
169
+ end
170
+
171
+ class Item < Traitable
172
+ traits :interactable_as, # TODO: rename this trait
173
+ :name,
174
+ :description,
175
+ :takeable
176
+
177
+ # Defaults
178
+ interactable_as :item
179
+ name "an Item"
180
+ description ""
181
+ takeable false
182
+
183
+ def to_s
184
+ name
185
+ end
186
+ end
187
+
188
+ class Location; end
189
+ # SRSGame::L is a shortcut for SRSGame::Location
190
+ L = Location
191
+
192
+ class Location
193
+ def self.direction_relationships
194
+ [["north", "south"], ["east", "west"], ["up", "down"], ["in", "out"]]
195
+ end
196
+
197
+ def self.mirrored_directions
198
+ direction_relationships + direction_relationships.map { |a| a.reverse }
199
+ end
200
+
201
+ # All directions available
202
+ def self.directions
203
+ direction_relationships.flatten
204
+ end
205
+
206
+ attr_reader(*L.directions)
207
+ attr_accessor :name, :description, :items
208
+
209
+ def initialize(params = {}, &block)
210
+ @name = params[:name] || "a room"
211
+ @description = params[:description].to_s
212
+ @items = params[:items].to_a
213
+
214
+ block.call(self) if block.respond_to? :call
215
+ end
216
+
217
+ def item_grep(str)
218
+ @items.select { |item| str == item.interactable_as.to_s.downcase }
219
+ end
220
+
221
+ def items_here
222
+ "Items here are #{@items.map(&:to_s).to_sentence(:bold => true)}."
223
+ end
224
+
225
+ # We have to create our own setter methods to do the mirrored direction relationships
226
+ L.mirrored_directions.each do |dir|
227
+ direction, opposite = *dir
228
+ define_method(direction + "=") do |loc|
229
+ # set @direction to loc
230
+ instance_variable_set "@" + direction, loc
231
+ # _direction is @direction
232
+ _direction = instance_variable_get("@" + direction)
233
+ _direction.__send__(opposite + "=", self) unless _direction.__send__(opposite)
234
+ end
235
+ end
236
+
237
+ # Available exits
238
+ # @return [Array]
239
+ def exits
240
+ L.directions.select { |dir| __send__(dir) }
241
+ end
242
+
243
+ # Information displayed when a room is entered.
244
+ def info
245
+ o = "You find yourself #{@name.bold}."
246
+ o << " #{@description}" if @description.unblank?
247
+ o << "\n" << items_here if @items.unblank?
248
+ o << "\nExits are #{exits.to_sentence(:bold => true)}." if exits.unblank?
249
+ o
250
+ end
251
+
252
+ def go(direction)
253
+ if exits.include?(direction.to_s)
254
+ __send__(direction)
255
+ else
256
+ raise DirectionError, "Can't go #{direction} from #{@name}."
257
+ end
258
+ end
259
+
260
+ def use_item(s, &block)
261
+ if (found = item_grep(s)).length == 1
262
+ block.call found[0]
263
+ else
264
+ items_here
265
+ end
266
+ end
267
+
268
+ def to_s
269
+ "#<SRSGame::Location #{@name.inspect} @items=#{@items.inspect} exits=#{exits.inspect}>"
270
+ end
271
+ end
272
+
273
+ # Class methods beginning with `+_+' are available as commands during the game
274
+ class Commands
275
+ # Called when a non-existing command is entered during the game
276
+ def method_missing(m, *a)
277
+ "#{self.class}##{m.downcase}: not found".red
278
+ end
279
+
280
+ # Methods that start with `+_+' and don't end with `+_+'
281
+ def callable_methods
282
+ methods.grep(/^_\w+[^_]$/)
283
+ end
284
+
285
+ def matching_methods(match)
286
+ callable_methods.grep(/^_#{match}/)
287
+ end
288
+
289
+ # Parse input and +__send__+ it
290
+ def parse(input, game)
291
+ method = input.words.first.command_pp
292
+
293
+ arguments = input.words[1..-1]
294
+
295
+ output = __send__("_#{method}", arguments.join(" "), game)
296
+ end
297
+
298
+ #################################
299
+ # Methods available as commands #
300
+ #################################
301
+
302
+ # Define all directions as commands
303
+ L.directions.each do |direction|
304
+ define_method("_#{direction}") do |a, g|
305
+ begin
306
+ g.go!(direction)
307
+ rescue DirectionError => e
308
+ e
309
+ end
310
+ end
311
+ end
312
+
313
+ # Quit the game
314
+ def _exit(a, g)
315
+ raise DONE_WITH_SRS_GAME
316
+ end
317
+
318
+ def _look(a, g)
319
+ if a.args.blank?
320
+ g.room.info
321
+ else # We are looking for an item
322
+ g.room.use_item(a) { |item| "You see #{item.name.bold}." }
323
+ end
324
+ end
325
+
326
+ # Display help text
327
+ def _help(a, g)
328
+ "All available commands:\n#{callable_methods.map(&:command_pp).to_sentence(:bold => true)}"
329
+ end
330
+
331
+ # Alias commands
332
+ alias :_quit :_exit
333
+ alias :_? :_help
334
+ end
335
+
336
+ class Game
337
+ attr_accessor :room, :command
338
+
339
+ def initialize(mod = SRSGame::Basic, options = {})
340
+ raise ArgumentError, "Can't use #{mod} for SRSGame module" unless mod.is_a? Module
341
+ extend mod
342
+
343
+ @options = options
344
+ @room = main_room
345
+ #@travel_path = [@room]
346
+ @command = mod.const_get(:Commands).new
347
+ end
348
+
349
+ def go!(*directions)
350
+ if directions.size >= 2
351
+ directions.each { |dir| go! dir }
352
+ else
353
+ new_room = @room.go(directions[0])
354
+ @room = new_room
355
+ end
356
+ end
357
+
358
+ #def current_room
359
+ # @travel_path[-1]
360
+ #end
361
+
362
+ #def last_room
363
+ # @travel_path[-2]
364
+ #end
365
+
366
+ #def same_room?
367
+ # current_room.eql? last_room
368
+ #end
369
+
370
+ def prompt
371
+ pr = "$ ".bold.blue
372
+ @options[:color] ? pr : pr.uncolored
373
+ end
374
+
375
+ def send(input)
376
+ output = @command.parse(input, self)
377
+ @options[:color] ? output : output.uncolored
378
+ end
379
+
380
+ def play
381
+ Readline.completion_append_character = " "
382
+
383
+ begin
384
+ loop do
385
+ Readline.completion_proc = proc { |match| @command.matching_methods(match).map(&:command_pp) }
386
+ input = Readline.readline(prompt, true)
387
+ puts send(input) unless input.blank?
388
+ end
389
+ rescue DONE_WITH_SRS_GAME
390
+ puts "\nHave a nice day!"
391
+ end
392
+ end
393
+ end
394
+
395
+ class SRServer < GServer
396
+ ## ♫ 54-46 was my number ♫ ##
397
+ DEFAULT_PORT = 54_46
398
+ MAX_CONNECTIONS = 4
399
+
400
+ attr_reader :mod
401
+
402
+ def initialize(mod, port=DEFAULT_PORT, host=DEFAULT_HOST, max_connections=MAX_CONNECTIONS)
403
+ @mod = mod
404
+ super(port, host, max_connections, $stderr, true, true)
405
+ end
406
+
407
+ def serve(io)
408
+ game = Game.new(@mod, direct: false)
409
+
410
+ begin
411
+ loop do
412
+ io.print game.prompt
413
+ input = io.readline
414
+ io.puts game.send(input) unless input.blank?
415
+ end
416
+ rescue DONE_WITH_SRS_GAME
417
+ io.puts "\nHave a nice day!"
418
+ end
419
+ end
420
+
421
+ def self.play(*args)
422
+ server = new(*args)
423
+ server.audit = true
424
+ server.start
425
+ trap(:INT) { server.stop }
426
+ server.join
427
+ end
428
+ end
429
+ end
data/spec/game_spec.rb ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: UTF-8 -*-
3
+ # This file is part of SRS GAME <http://github.com/jacksonwillis/srs_game/>.
4
+
5
+ $LOAD_PATH.unshift File.expand_path("../", __FILE__)
6
+ require "spec_helper"
7
+
8
+ describe SRSGame::Game do
9
+ it "has a room" do
10
+ Game.new.room.should be_instance_of Location
11
+ end
12
+
13
+ describe "#go!" do
14
+ it "travels" do
15
+ game = Game.new
16
+
17
+ kitchen = Location.new
18
+ basement = Location.new { |l| l.up = kitchen }
19
+ sidewalk = Location.new { |l| l.in = kitchen }
20
+ bus_stop = Location.new { |l| l.north = sidewalk }
21
+
22
+ game.room = basement
23
+ ->{game.go! :up, :out, :south}.should change {game.room}.from(basement).to(bus_stop)
24
+ end
25
+ end
26
+
27
+
28
+ describe "#_quit" do
29
+ it "quits" do
30
+ ->{Game.new.send "quit"}.should raise_error DONE_WITH_SRS_GAME
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: UTF-8 -*-
3
+ # This file is part of SRS GAME <http://github.com/jacksonwillis/srs_game/>.
4
+
5
+ $LOAD_PATH.unshift File.expand_path("../", __FILE__)
6
+ require "spec_helper"
7
+
8
+ describe "helpers" do
9
+ it "determines blankness" do
10
+ [].blank?.should be_true
11
+ "".blank?.should be_true
12
+ false.blank?.should be_true
13
+ true.blank?.should be_false
14
+ 3.14.blank?.should be_false
15
+ nil.unblank?.should be_false
16
+ "foo".unblank?.should be_true
17
+ end
18
+
19
+ it "formats commands" do
20
+ "_baz".command_pp.should eq "baz"
21
+ :_Senate.command_pp.should eq "senate"
22
+ end
23
+
24
+ it "converts arrays to sentences" do
25
+ [1,2,3].to_sentence.should eq "1, 2, and 3"
26
+ ["jack", "jill"].to_sentence.should eq "jack and jill"
27
+ ["Something"].to_sentence.should eq "Something"
28
+ [].to_sentence.should eq ""
29
+ ["Kinada", "Dwor", "apple", "green"].to_sentence(bold: true).should eq \
30
+ "\e[1mKinada\e[0m, \e[1mDwor\e[0m, \e[1mapple\e[0m, and \e[1mgreen\e[0m"
31
+ end
32
+
33
+ it "converts string to booleans" do
34
+ "yes".to_bool.should be_true
35
+ "no".to_bool.should be_false
36
+ "f".to_bool.should be_false
37
+ "t".to_bool.should be_true
38
+ "true".to_bool.should be_true
39
+ "foo".to_bool.should be_nil
40
+ end
41
+
42
+ it "identifies if a string represents a boolean" do
43
+ "yes".boolean?.should be_true
44
+ "false".boolean?.should be_true
45
+ "foo".boolean?.should be_false
46
+ end
47
+
48
+ it "identifies if a string represents a numeric" do
49
+ "3.14".numeric?.should be_true
50
+ "42".numeric?.should be_true
51
+ "4.2e2".numeric?.should be_true
52
+ "foo".numeric?.should be_false
53
+ end
54
+
55
+ it "parses a string into arguments" do
56
+ "3.14 yes gaga false".args.should eq [3.14, true, "gaga", false]
57
+ "tia".args.should eq ["tia"]
58
+ "".args.should eq []
59
+ " ".args.should eq []
60
+ end
61
+
62
+ end
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: UTF-8 -*-
3
+ # This file is part of SRS GAME <http://github.com/jacksonwillis/srs_game/>.
4
+
5
+ $LOAD_PATH.unshift File.expand_path("../", __FILE__)
6
+ require "spec_helper"
7
+
8
+ describe SRSGame::Location do
9
+ it "instantiates rooms" do
10
+ name = "some room"
11
+
12
+ location = Location.new do |l|
13
+ l.name = name
14
+ end
15
+
16
+ location.name.should eq name
17
+ location.inspect.should be_an_instance_of(String)
18
+ end
19
+
20
+ describe "#do" do
21
+ it "only lets you occupy reality" do
22
+ location = Location.new # no exits
23
+ ->{location.go("west")}.should raise_error SRSGame::DirectionError
24
+ ->{location.go(:down)}.should raise_error SRSGame::DirectionError
25
+ end
26
+ end
27
+
28
+ describe "#info" do
29
+ it "describes a room" do
30
+ class SomeItem < Item
31
+ name "some item"
32
+ end
33
+
34
+ location = Location.new do |l|
35
+ l.name = "in a room"
36
+ l.description = "A picture hangs on the wall."
37
+ l.items = [SomeItem.new]
38
+ l.south = L.new
39
+ l.out = L.new
40
+ end
41
+
42
+ location.info.uncolored.should eq "You find yourself in a room. A picture hangs on the wall." <<
43
+ "\nItems here are some item.\nExits are south and out."
44
+ end
45
+ end
46
+
47
+ it "looks for items" do
48
+ class FooItem < Item
49
+ interactable_as :foo
50
+ end
51
+
52
+ class BarItem < Item
53
+ interactable_as :bar
54
+ end
55
+
56
+ foo = FooItem.new
57
+ bar = BarItem.new
58
+
59
+ location = Location.new { |l| l.items = [foo, bar] }
60
+
61
+ location.item_grep("foo").should eq [foo]
62
+ location.item_grep("bar").should eq [bar]
63
+ location.item_grep("baz").should eq []
64
+ location.item_grep("").should eq []
65
+ end
66
+
67
+ it "has a prompt" do
68
+ Game.new.prompt.should eq "$ "
69
+ end
70
+ end
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: UTF-8 -*-
3
+ # This file is part of SRS GAME <http://github.com/jacksonwillis/srs_game/>.
4
+
5
+ require "simplecov"
6
+ SimpleCov.start
7
+
8
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
9
+
10
+ require "srs_game/basic"
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: UTF-8 -*-
3
+ # This file is part of SRS GAME <http://github.com/jacksonwillis/srs_game/>.
4
+
5
+ $LOAD_PATH.unshift File.expand_path("../", __FILE__)
6
+ require "spec_helper"
7
+
8
+ describe SRSGame::SRServer do
9
+ describe "::new" do
10
+ it "makes a default server" do
11
+ server = SRServer.new Basic
12
+ server.mod.should eq Basic
13
+ server.host.should eq SRServer::DEFAULT_HOST
14
+ server.port.should eq SRServer::DEFAULT_PORT
15
+ server.maxConnections.should eq SRServer::MAX_CONNECTIONS
16
+ end
17
+ end
18
+ end
data/srs_game.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: UTF-8 -*-
3
+ # This file is part of SRS GAME <http://github.com/jacksonwillis/srs_game/>.
4
+
5
+ $LOAD_PATH.unshift File.expand_path("../lib/", __FILE__)
6
+ require "srs_game/version"
7
+
8
+ Gem::Specification.new do |gem|
9
+ gem.authors = ["Jackson Willis"]
10
+ gem.email = ["jcwillis.school@gmail.com"]
11
+ gem.description = "A framework and collection of text-based games"
12
+ gem.summary = "A framework and collection of text-based games"
13
+ gem.homepage = "http://github.com/jacksonwillis/srs_game"
14
+
15
+ gem.files = `git ls-files`.split($\)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.name = "srs_game"
19
+ gem.require_paths = ["lib"]
20
+ gem.version = SRSGame::VERSION
21
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: srs_game
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.Alexis
5
+ prerelease: 2
6
+ platform: ruby
7
+ authors:
8
+ - Jackson Willis
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-31 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: A framework and collection of text-based games
15
+ email:
16
+ - jcwillis.school@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - .rspec
23
+ - .travis.yml
24
+ - .yardopts
25
+ - Gemfile
26
+ - LICENSE
27
+ - README.md
28
+ - Rakefile.rb
29
+ - examples/pokemon_clone.rb
30
+ - lib/srs_game.rb
31
+ - lib/srs_game/basic.rb
32
+ - lib/srs_game/tamera.rb
33
+ - lib/srs_game/tia.rb
34
+ - lib/srs_game/version.rb
35
+ - spec/game_spec.rb
36
+ - spec/helpers_spec.rb
37
+ - spec/location_spec.rb
38
+ - spec/spec_helper.rb
39
+ - spec/srserver_spec.rb
40
+ - srs_game.gemspec
41
+ homepage: http://github.com/jacksonwillis/srs_game
42
+ licenses: []
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>'
57
+ - !ruby/object:Gem::Version
58
+ version: 1.3.1
59
+ requirements: []
60
+ rubyforge_project:
61
+ rubygems_version: 1.8.10
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: A framework and collection of text-based games
65
+ test_files:
66
+ - spec/game_spec.rb
67
+ - spec/helpers_spec.rb
68
+ - spec/location_spec.rb
69
+ - spec/spec_helper.rb
70
+ - spec/srserver_spec.rb
71
+ has_rdoc: