gamefic 0.1.1 → 0.2.0

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