srs_game 0.Alexis

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