gamefic 0.1.1 → 0.2.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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/lib/gamefic/action.rb +7 -6
  3. data/lib/gamefic/before.rb +12 -0
  4. data/lib/gamefic/character.rb +1 -1
  5. data/lib/gamefic/core_ext/array.rb +4 -0
  6. data/lib/gamefic/core_ext/string.rb +0 -31
  7. data/lib/gamefic/describable.rb +68 -8
  8. data/lib/gamefic/director.rb +108 -75
  9. data/lib/gamefic/engine.rb +74 -10
  10. data/lib/gamefic/entity.rb +3 -3
  11. data/lib/gamefic/import/basics/actions/close.rb +16 -0
  12. data/lib/gamefic/import/basics/actions/commands.rb +3 -0
  13. data/lib/gamefic/import/basics/actions/drop-in.rb +17 -0
  14. data/lib/gamefic/import/basics/actions/drop-on.rb +16 -0
  15. data/lib/gamefic/import/basics/actions/drop.rb +30 -0
  16. data/lib/gamefic/import/basics/actions/enter.rb +16 -0
  17. data/lib/gamefic/import/basics/actions/{traversal.rb → go.rb} +35 -35
  18. data/lib/gamefic/import/basics/actions/inventory.rb +8 -49
  19. data/lib/gamefic/import/basics/actions/leave.rb +29 -0
  20. data/lib/gamefic/import/basics/actions/look-in-at.rb +27 -0
  21. data/lib/gamefic/import/basics/actions/look-under.rb +3 -0
  22. data/lib/gamefic/import/basics/actions/look.rb +71 -67
  23. data/lib/gamefic/import/basics/actions/nil.rb +25 -0
  24. data/lib/gamefic/import/basics/actions/open.rb +23 -0
  25. data/lib/gamefic/import/basics/actions/quit.rb +3 -0
  26. data/lib/gamefic/import/basics/actions/take.rb +107 -0
  27. data/lib/gamefic/import/basics/entities/container.rb +8 -24
  28. data/lib/gamefic/import/basics/entities/entity.rb +11 -0
  29. data/lib/gamefic/import/basics/entities/fixture.rb +5 -5
  30. data/lib/gamefic/import/basics/entities/item.rb +5 -7
  31. data/lib/gamefic/import/basics/entities/portal.rb +40 -43
  32. data/lib/gamefic/import/basics/entities/room.rb +30 -24
  33. data/lib/gamefic/import/basics/entities/scenery.rb +5 -3
  34. data/lib/gamefic/import/basics/entities/supporter.rb +6 -0
  35. data/lib/gamefic/import/basics/entities/thing.rb +16 -0
  36. data/lib/gamefic/import/basics/queries/reachable.rb +38 -0
  37. data/lib/gamefic/import/basics/queries/room.rb +8 -0
  38. data/lib/gamefic/import/basics/queries/visible.rb +32 -0
  39. data/lib/gamefic/import/basics/rules/has-enough-light.rb +14 -0
  40. data/lib/gamefic/import/{basics → basics.old}/actions/container.rb +13 -12
  41. data/lib/gamefic/import/basics.old/actions/inventory.rb +50 -0
  42. data/lib/gamefic/import/basics.old/actions/look.rb +53 -0
  43. data/lib/gamefic/import/basics.old/actions/meta.rb +6 -0
  44. data/lib/gamefic/import/basics.old/actions/traversal.rb +35 -0
  45. data/lib/gamefic/import/{basics → basics.old}/actions.rb +0 -0
  46. data/lib/gamefic/import/basics.old/entities/container.rb +3 -0
  47. data/lib/gamefic/import/basics.old/entities/fixture.rb +3 -0
  48. data/lib/gamefic/import/basics.old/entities/item.rb +3 -0
  49. data/lib/gamefic/import/basics.old/entities/portal.rb +43 -0
  50. data/lib/gamefic/import/basics.old/entities/room.rb +27 -0
  51. data/lib/gamefic/import/basics.old/entities/scenery.rb +3 -0
  52. data/lib/gamefic/import/basics.old/entities/supporter.rb +3 -0
  53. data/lib/gamefic/import/{basics → basics.old}/entities.rb +0 -0
  54. data/lib/gamefic/import/basics.old/room_modes.rb +48 -0
  55. data/lib/gamefic/import/basics.rb +6 -2
  56. data/lib/gamefic/import/{basics/room_modes.rb → room_modes.rb} +6 -6
  57. data/lib/gamefic/import/standard.rb +1 -0
  58. data/lib/gamefic/meta.rb +12 -0
  59. data/lib/gamefic/optionset.rb +114 -0
  60. data/lib/gamefic/plot.rb +54 -21
  61. data/lib/gamefic/query.rb +214 -188
  62. data/lib/gamefic/requirement.rb +14 -0
  63. data/lib/gamefic/shell.rb +7 -4
  64. data/lib/gamefic/syntax.rb +35 -18
  65. data/lib/gamefic/thing.rb +7 -0
  66. data/lib/gamefic.rb +5 -1
  67. metadata +46 -12
  68. data/lib/gamefic/import/basics/actions/meta.rb +0 -6
  69. data/lib/gamefic/import/basics/entities/itemized.rb +0 -3
  70. data/lib/gamefic/import/basics/entities/portable.rb +0 -3
  71. data/lib/gamefic/user.rb +0 -66
data/lib/gamefic/query.rb CHANGED
@@ -1,188 +1,214 @@
1
- require "gamefic/keywords"
2
-
3
- module Gamefic
4
-
5
- class Query
6
- FAMILY = :family
7
- CHILDREN = :children
8
- SIBLINGS = :siblings
9
- PARENT = :parent
10
- SELF = :self
11
- PLOT = :plot
12
- STRING = :string
13
- def initialize(context, *arguments)
14
- if context != :family and context != :children and context != :siblings and context != :parent and context != :self and context != :plot and context != :string
15
- #if self.class.constants.include?(context.to_sym) == false
16
- raise "Invalid Query context '#{context.to_sym}'"
17
- end
18
- #if context == :string and arguments.length > 0
19
- # raise "Query with :string context cannot take additional arguments."
20
- #end
21
- @context = context
22
- @arguments = arguments
23
- end
24
- def execute(subject, description)
25
- case context
26
- when :self
27
- array = [subject]
28
- when :parent
29
- array = [subject.parent]
30
- when :plot
31
- array = subject.plot.entities
32
- when :children
33
- array = subject.children
34
- when :siblings
35
- array = subject.parent.children
36
- when :family
37
- array = subject.children + subject.parent.children
38
- when :string
39
- if @arguments.length == 0
40
- return Matches.new([description], description, '')
41
- end
42
- keywords = Keywords.new(description)
43
- args = Keywords.new(@arguments)
44
- found = Array.new
45
- remainder = Array.new
46
- keywords.each { |key|
47
- if args.include?(key)
48
- found.push key
49
- else
50
- remainder.push key
51
- end
52
- }
53
- if found.length > 0
54
- return Matches.new([description], found.join(' '), remainder.join(' '))
55
- else
56
- return Matches.new([], '', description)
57
- end
58
- else
59
- raise "Unrecognized: #{context}"
60
- end
61
- @arguments.each { |arg|
62
- if arg.kind_of?(Class) or arg.kind_of?(Module)
63
- array.delete_if { |entity| entity.kind_of?(arg) == false }
64
- else
65
- if array.include?(arg)
66
- array = Array.new
67
- array.push(arg)
68
- else
69
- array.clear
70
- end
71
- end
72
- }
73
- return Query.match(description, array)
74
- end
75
- def context
76
- @context
77
- end
78
- def Query.match(description, array)
79
- array.each {|e|
80
- if e.uid == description
81
- return Matches.new([e], description, '')
82
- end
83
- }
84
- keywords = description.split_words
85
- results = array
86
- used = Array.new
87
- if results.length > 0
88
- previous_match = false
89
- while keywords.length > 0
90
- used.push keywords.shift
91
- new_results = Array.new
92
- mostMatches = 0.0
93
- results.each { |r|
94
- words = Keywords.new(used.join(' '))
95
- if words.length > 0
96
- matches = words.found_in r.keywords
97
- if matches >= mostMatches and matches > 0
98
- if matches - mostMatches > 0.5
99
- new_results = Array.new
100
- end
101
- new_results.push r
102
- mostMatches = matches
103
- end
104
- end
105
- }
106
- if new_results.length == 0
107
- if previous_match == true
108
- keywords.unshift used.pop
109
- if used.length == 0
110
- results = new_results
111
- end
112
- break
113
- end
114
- else
115
- previous_match = true
116
- results = new_results
117
- if results.length == 1
118
- break
119
- end
120
- end
121
- end
122
- if previous_match == false
123
- # Scrolled through every word and not a single thing matched
124
- results = Array.new
125
- end
126
- end
127
- return Matches.new(results, used.join(' '), keywords.join(' '))
128
- end
129
- def Query.match_one(description, array)
130
- result = self.match(description, array)
131
- if result.objects.length == 1
132
- return result.objects[0]
133
- end
134
- return nil
135
- end
136
- def specificity
137
- if @specificity == nil
138
- @specificity = 0
139
- case @context
140
- when :children
141
- @specificity += 50
142
- when :siblings
143
- @specificity += 40
144
- when :family
145
- @specificity += 30
146
- when :parent
147
- @specificity += 20
148
- when :self
149
- @specificity += 10
150
- when :string
151
- @specificity = 1
152
- #return @specificity
153
- end
154
- magnitude = 1
155
- @arguments.each { |item|
156
- if item.kind_of?(Entity)
157
- @specificity += (magnitude * 10)
158
- item = item.class
159
- end
160
- if item.kind_of?(Class)
161
- s = item
162
- while s != nil
163
- @specificity += magnitude
164
- s = s.superclass
165
- end
166
- else
167
- @specificity += magnitude
168
- end
169
- magnitude = magnitude * 10
170
- }
171
- end
172
- @specificity
173
- end
174
- class Matches
175
- attr_reader :objects, :matching_text, :remainder
176
- def initialize(objects, matching_text, remainder)
177
- @objects = objects
178
- @matching_text = matching_text
179
- @remainder = remainder
180
- end
181
- end
182
- end
183
-
184
- class Subquery < Query
185
-
186
- end
187
-
188
- end
1
+ require "gamefic/keywords"
2
+
3
+ module Gamefic
4
+
5
+ module Query
6
+
7
+ class Base
8
+ attr_accessor :arguments
9
+ def initialize *arguments
10
+ @optional = false
11
+ if arguments.include?(:optional)
12
+ @optional = true
13
+ arguments.delete :optional
14
+ end
15
+ @arguments = arguments
16
+ end
17
+ def optional?
18
+ @optional
19
+ end
20
+ def context_from(subject)
21
+ subject
22
+ end
23
+ def execute(subject, description)
24
+ array = context_from(subject)
25
+ @arguments.each { |arg|
26
+ array = array.that_are(arg)
27
+ }
28
+ return Query.match(description, array)
29
+ end
30
+ def base_specificity
31
+ 0
32
+ end
33
+ def specificity
34
+ if @specificity == nil
35
+ @specificity = base_specificity
36
+ magnitude = 1
37
+ @arguments.each { |item|
38
+ if item.kind_of?(Entity)
39
+ @specificity += (magnitude * 10)
40
+ item = item.class
41
+ end
42
+ if item.kind_of?(Class)
43
+ s = item
44
+ while s != nil
45
+ @specificity += magnitude
46
+ s = s.superclass
47
+ end
48
+ else
49
+ @specificity += magnitude
50
+ end
51
+ #magnitude = magnitude * 10
52
+ }
53
+ end
54
+ @specificity
55
+ end
56
+ end
57
+
58
+ class Text < Base
59
+ def base_specificity
60
+ 10
61
+ end
62
+ def execute(subject, description)
63
+ if @arguments.length == 0
64
+ return Matches.new([description], description, '')
65
+ end
66
+ keywords = Keywords.new(description)
67
+ args = Keywords.new(@arguments)
68
+ found = Array.new
69
+ remainder = Array.new
70
+ keywords.each { |key|
71
+ if args.include?(key)
72
+ found.push key
73
+ else
74
+ remainder.push key
75
+ end
76
+ }
77
+ if found.length > 0
78
+ return Matches.new([description], found.join(' '), remainder.join(' '))
79
+ else
80
+ return Matches.new([], '', description)
81
+ end
82
+ end
83
+ end
84
+
85
+ class Self < Base
86
+ def base_specificity
87
+ 30
88
+ end
89
+ def context_from(subject)
90
+ [subject]
91
+ end
92
+ end
93
+
94
+ class Parent < Base
95
+ def base_specificity
96
+ 30
97
+ end
98
+ def context_from(subject)
99
+ [subject.parent]
100
+ end
101
+ end
102
+
103
+ class Children < Base
104
+ def base_specificity
105
+ 50
106
+ end
107
+ def context_from(subject)
108
+ subject.children
109
+ end
110
+ end
111
+
112
+ class Siblings < Base
113
+ def base_specificity
114
+ 40
115
+ end
116
+ def context_from(subject)
117
+ (subject.parent.children - [subject])
118
+ end
119
+ end
120
+
121
+ class Family < Base
122
+ def base_specificity
123
+ 40
124
+ end
125
+ def context_from(subject)
126
+ subject.children + subject.parent.children #+ [subject.parent]
127
+ end
128
+ end
129
+
130
+ def self.match(description, array)
131
+ array.each {|e|
132
+ if e.uid == description
133
+ return Matches.new([e], description, '')
134
+ end
135
+ }
136
+ keywords = description.split_words
137
+ results = array
138
+ used = Array.new
139
+ if results.length > 0
140
+ previous_match = false
141
+ while keywords.length > 0
142
+ used.push keywords.shift
143
+ new_results = Array.new
144
+ mostMatches = 0.0
145
+ results.each { |r|
146
+ words = Keywords.new(used.join(' '))
147
+ if words.length > 0
148
+ matches = words.found_in r.keywords
149
+ if matches >= mostMatches and matches > 0
150
+ if matches - mostMatches > 0.5
151
+ new_results = Array.new
152
+ end
153
+ new_results.push r
154
+ mostMatches = matches
155
+ end
156
+ end
157
+ }
158
+ if new_results.length == 0
159
+ if previous_match == true
160
+ keywords.unshift used.pop
161
+ if used.length == 0
162
+ results = new_results
163
+ end
164
+ break
165
+ end
166
+ else
167
+ previous_match = true
168
+ results = new_results
169
+ # TODO: Uncommenting this code results in "lazy" word matching
170
+ #if results.length == 1
171
+ # break
172
+ #end
173
+ end
174
+ end
175
+ if previous_match == false
176
+ # Scrolled through every word and not a single thing matched
177
+ results = Array.new
178
+ end
179
+ end
180
+ return Matches.new(results, used.join(' '), keywords.join(' '))
181
+ end
182
+
183
+ class Subquery < Base
184
+ def base_specificity
185
+ 40
186
+ end
187
+ def context_from(subject)
188
+ last = Matches.last_match
189
+ return [] if last.nil?
190
+ last.children
191
+ end
192
+ end
193
+
194
+ class Matches
195
+ @@last_match = nil
196
+ attr_reader :objects, :matching_text, :remainder
197
+ def initialize(objects, matching_text, remainder)
198
+ @objects = objects
199
+ @matching_text = matching_text
200
+ @remainder = remainder
201
+ @@last_match = self
202
+ end
203
+ def self.last_match
204
+ return nil if @@last_match.nil?
205
+ if @@last_match.objects.length == 1
206
+ return @@last_match.objects[0]
207
+ end
208
+ return nil
209
+ end
210
+ end
211
+
212
+ end
213
+
214
+ end
@@ -0,0 +1,14 @@
1
+ module Gamefic
2
+
3
+ class Requirement
4
+ def initialize plot, name, &proc
5
+ @plot = plot
6
+ @name = name
7
+ @proc = proc
8
+ end
9
+ def test actor
10
+ return @proc.call actor
11
+ end
12
+ end
13
+
14
+ end
data/lib/gamefic/shell.rb CHANGED
@@ -1,7 +1,9 @@
1
+ require 'rubygems'
1
2
  require 'rubygems/package'
2
3
  require 'zlib'
3
4
  require 'tmpdir'
4
5
  require 'getoptlong'
6
+ require 'gamefic/engine/tty'
5
7
 
6
8
  # Crazy hack to set file mtimes in tar file
7
9
  class Gem::Package::TarHeader
@@ -66,7 +68,7 @@ module Gamefic
66
68
  exit 1
67
69
  end
68
70
  story.load dir + '/main.rb'
69
- engine = Engine.new story
71
+ engine = Tty::Engine.new story
70
72
  puts "\n"
71
73
  engine.run
72
74
  end
@@ -88,7 +90,8 @@ module Gamefic
88
90
  # puts "#{e.inspect}"
89
91
  # exit 1
90
92
  #end
91
- engine = Engine.new story
93
+ engine = Tty::Engine.new story
94
+ puts "\n"
92
95
  engine.run
93
96
  end
94
97
  def init directory
@@ -112,7 +115,7 @@ module Gamefic
112
115
  Dir.mkdir(directory + '/import')
113
116
  main_rb = File.new(directory + '/main.rb', 'w')
114
117
  main_rb.write <<EOS
115
- import 'basics'
118
+ import 'standard'
116
119
 
117
120
  room = make Room, :name => 'room'
118
121
 
@@ -122,7 +125,7 @@ introduction do |player|
122
125
  end
123
126
  EOS
124
127
  main_rb.close
125
- fetch directory
128
+ #fetch directory
126
129
  puts "Game directory '#{directory}' initialized."
127
130
  end
128
131
  def fetch directory
@@ -7,37 +7,54 @@ module Gamefic
7
7
  if arguments.length < 2
8
8
  raise "Syntax.new requires at least two arguments (template and command)"
9
9
  end
10
- @template = arguments.shift
11
- @command = arguments.shift
12
- @arguments = arguments
13
- if story == nil
14
- @@defaults.push self
15
- else
16
- story.send :add_syntax, self
17
- @story = story
18
- end
10
+ if arguments.length == 2 and arguments[0].kind_of?(Array) and arguments[1].kind_of?(Array)
11
+ @template = arguments[0]
12
+ @command = arguments[1].shift
13
+ @arguments = arguments[1]
14
+ else
15
+ @template = []
16
+ string = arguments.shift
17
+ string.split_words.each { |word|
18
+ if word[0,1] == ":"
19
+ @template.push word[1..-1].to_sym
20
+ else
21
+ @template.push word
22
+ end
23
+ }
24
+ #@template = arguments.shift
25
+ @command = arguments.shift
26
+ @arguments = arguments
27
+ if story == nil
28
+ #@@defaults.push self
29
+ raise "Default syntaxes are deprecated"
30
+ else
31
+ story.send :add_syntax, self
32
+ @story = story
33
+ end
34
+ end
19
35
  end
20
36
  def self.defaults
21
37
  @@defaults.clone
22
38
  end
23
- def self.match(input, syntaxes)
39
+ def self.match(input, context)
24
40
  # Given the input, return all the syntaxes that potentially match it.
41
+ syntaxes = (context.kind_of?(Plot) ? context.syntaxes : context)
25
42
  matches = Array.new
26
43
  words = input.split_words
27
44
  syntaxes.each { |syntax|
28
45
  input_words = words.clone
29
46
  tokens = Hash.new
30
- syntax_words = syntax.template.split_words
47
+ syntax_words = syntax.template.clone
31
48
  while syntax_words.length > 0
32
49
  if input_words.length == 0
33
50
  # No more input. Break with an imbalance.
34
51
  break
35
52
  end
36
53
  symbol = syntax_words.shift
37
- if symbol[0, 1] == ":"
54
+ if symbol.kind_of?(Symbol)
38
55
  if syntax_words.length == 0
39
56
  # Last syntax word.
40
- tokens[symbol[1..-1].to_sym] = input_words.join(' ')
57
+ tokens[symbol] = input_words.join(' ')
41
58
  input_words.clear
42
59
  break
43
60
  elsif input_words.length == 0
@@ -45,11 +62,11 @@ module Gamefic
45
62
  break
46
63
  else
47
64
  non_vars = syntax_words.clone.delete_if { |w|
48
- w[0, 1] == ':'
65
+ w.kind_of?(Symbol)
49
66
  }
50
67
  if non_vars.length == 0
51
68
  # All remaining words in the syntax are variables. Dump everything now.
52
- tokens[symbol[1..-1].to_sym] = input_words.join(' ')
69
+ tokens[symbol] = input_words.join(' ')
53
70
  syntax_words.clear
54
71
  input_words.clear
55
72
  else
@@ -58,7 +75,7 @@ module Gamefic
58
75
  if syntax_words.length == 0
59
76
  last_input_word = input_words.pop
60
77
  if last_input_word == next_syntax_word
61
- tokens[symbol[1..-1].to_sym] = input_words.join(' ')
78
+ tokens[symbol] = input_words.join(' ')
62
79
  input_words.clear
63
80
  end
64
81
  break
@@ -71,7 +88,7 @@ module Gamefic
71
88
  if input_words.length == 0 and syntax_words.length > 0
72
89
  break
73
90
  else
74
- tokens[symbol[1..-1].to_sym] = token.strip
91
+ tokens[symbol] = token.strip
75
92
  end
76
93
  end
77
94
  end
@@ -93,7 +110,7 @@ module Gamefic
93
110
  else
94
111
  if a != nil and a != ''
95
112
  arguments.push(a)
96
- end
113
+ end
97
114
  end
98
115
  }
99
116
  if syntax.arguments.length == arguments.length
@@ -0,0 +1,7 @@
1
+ module Gamefic
2
+
3
+ class Thing < Entity
4
+
5
+ end
6
+
7
+ end
data/lib/gamefic.rb CHANGED
@@ -1,13 +1,17 @@
1
1
  require "gamefic/core_ext/array"
2
2
  require "gamefic/core_ext/string"
3
+ require "gamefic/optionset"
3
4
  require "gamefic/keywords"
4
5
  require "gamefic/entity"
6
+ require "gamefic/thing"
5
7
  require "gamefic/character"
6
8
  require "gamefic/action"
9
+ require "gamefic/before"
10
+ require "gamefic/meta"
11
+ require "gamefic/requirement"
7
12
  require "gamefic/syntax"
8
13
  require "gamefic/query"
9
14
  require "gamefic/director"
10
15
  require "gamefic/plot"
11
16
  require "gamefic/story"
12
17
  require "gamefic/engine"
13
- require "gamefic/user"