gamefic 1.4.0 → 1.4.1
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.
- checksums.yaml +4 -4
- data/lib/gamefic/engine/base.rb +0 -1
- data/lib/gamefic/keywords.rb +23 -16
- data/lib/gamefic/plot.rb +17 -41
- data/lib/gamefic/plot/scene_mount.rb +3 -24
- data/lib/gamefic/query/base.rb +19 -19
- data/lib/gamefic/scene/multiple_scene.rb +2 -2
- data/lib/gamefic/scene_data.rb +1 -0
- data/lib/gamefic/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 148fd56ec0966aee6fe9af25f63b450b64ecdcc3
|
|
4
|
+
data.tar.gz: f0bee28dabd8400c7c350c5c8a8005b67ce01ebf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 913706c95e0814ec1b4d9f39358d5afcb2a09b3a4f9d683684e64e404154e4c5d7735ea837c40dd4433525d3734ad2ba2a312fc23d9376dfb7d5886497a99238
|
|
7
|
+
data.tar.gz: 9ac42568ffb6fc3247dbf386fd42aca1ad0e97d18b195a8ca3154ac8ac634525df10a120d7f28eeb182d8d31a63a9dfb121665640623fc569771b2243a16b0cc
|
data/lib/gamefic/engine/base.rb
CHANGED
data/lib/gamefic/keywords.rb
CHANGED
|
@@ -12,15 +12,14 @@ module Gamefic
|
|
|
12
12
|
end
|
|
13
13
|
self.concat statement.to_s.gsub(/[^a-z0-9]/i, ' ').strip.downcase.split(' ')
|
|
14
14
|
end
|
|
15
|
-
# TODO: This routine is stubbed to allow any combination of letters and
|
|
16
|
-
# numbers as a keyword. Since we're doing this, there's a distinct
|
|
17
|
-
# possibility that the Keywords class can be deprecated.
|
|
18
|
-
#self.delete_if { |w|
|
|
19
|
-
# w.length < 2 or w == 'an' or w == 'the'
|
|
20
|
-
#}
|
|
21
|
-
#self.uniq!
|
|
22
15
|
self
|
|
23
16
|
end
|
|
17
|
+
|
|
18
|
+
# Count the number of matching words in another Keywords array.
|
|
19
|
+
# The total includes partial matches; for example, "gre" is a 0.6 match
|
|
20
|
+
# for "green".
|
|
21
|
+
#
|
|
22
|
+
# @return [Float] The total number of matches
|
|
24
23
|
def found_in(other, fuzzy = false)
|
|
25
24
|
matches = 0.0
|
|
26
25
|
self.each { |my_word|
|
|
@@ -33,14 +32,7 @@ module Gamefic
|
|
|
33
32
|
matches = matches + (my_word.length.to_f / other_word.length.to_f)
|
|
34
33
|
end
|
|
35
34
|
elsif fuzzy
|
|
36
|
-
fuzzy_word = my_word
|
|
37
|
-
if fuzzy_word.end_with?('ies')
|
|
38
|
-
fuzzy_word = fuzzy_word[0..-4]
|
|
39
|
-
elsif fuzzy_word.end_with?('ae')
|
|
40
|
-
fuzzy_word = fuzzy_word[0..-3]
|
|
41
|
-
elsif fuzzy_word.end_with?('s') or fuzzy_word.end_with?('i')
|
|
42
|
-
fuzzy_word = fuzzy_word[0..-2]
|
|
43
|
-
end
|
|
35
|
+
fuzzy_word = fuzzify my_word
|
|
44
36
|
if other_word[0, fuzzy_word.length] == fuzzy_word and fuzzy_word.length > 2
|
|
45
37
|
matches = matches + (fuzzy_word.length.to_f / other_word.length.to_f)
|
|
46
38
|
elsif fuzzy_word[0, other_word.length] == other_word and other_word.length > 2
|
|
@@ -50,11 +42,26 @@ module Gamefic
|
|
|
50
42
|
}
|
|
51
43
|
end
|
|
52
44
|
}
|
|
53
|
-
|
|
45
|
+
matches
|
|
54
46
|
end
|
|
47
|
+
|
|
55
48
|
def to_s
|
|
56
49
|
self.join(' ')
|
|
57
50
|
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def fuzzify word
|
|
55
|
+
if word.end_with?('ies')
|
|
56
|
+
word[0..-4]
|
|
57
|
+
elsif word.end_with?('ae')
|
|
58
|
+
word[0..-3]
|
|
59
|
+
elsif word.end_with?('s') or word.end_with?('i')
|
|
60
|
+
word[0..-2]
|
|
61
|
+
else
|
|
62
|
+
word
|
|
63
|
+
end
|
|
64
|
+
end
|
|
58
65
|
end
|
|
59
66
|
|
|
60
67
|
end
|
data/lib/gamefic/plot.rb
CHANGED
|
@@ -28,7 +28,7 @@ module Gamefic
|
|
|
28
28
|
#include Gamefic, Tester, SceneMount, CommandMount, EntityMount, QueryMount, ArticleMount, YouMount, Snapshot
|
|
29
29
|
mount Gamefic, Tester, SceneMount, CommandMount, EntityMount, QueryMount,
|
|
30
30
|
ArticleMount, YouMount, Snapshot, Subplot::Host
|
|
31
|
-
expose :script, :introduction, :assert_action,
|
|
31
|
+
expose :script, :introduction, :assert_action,
|
|
32
32
|
:on_update, :on_player_update, :entities, :on_ready, :on_player_ready,
|
|
33
33
|
:players, :scenes, :metadata
|
|
34
34
|
|
|
@@ -38,7 +38,6 @@ module Gamefic
|
|
|
38
38
|
@commands = {}
|
|
39
39
|
@syntaxes = []
|
|
40
40
|
@ready_procs = []
|
|
41
|
-
@before_player_update_procs = []
|
|
42
41
|
@update_procs = []
|
|
43
42
|
@player_ready = []
|
|
44
43
|
@player_procs = []
|
|
@@ -171,28 +170,20 @@ module Gamefic
|
|
|
171
170
|
# This method is typically called by the Engine that manages game execution.
|
|
172
171
|
def introduce(player)
|
|
173
172
|
player.extend Subplot::Feature
|
|
173
|
+
player.cue :active
|
|
174
174
|
@players.push player
|
|
175
|
-
|
|
176
|
-
@introduction.call(player)
|
|
177
|
-
end
|
|
178
|
-
# TODO: There should probably be a default state specified
|
|
179
|
-
# by the plot, which would be :active by default. We could
|
|
180
|
-
# get it like player.cue nil.
|
|
181
|
-
if player.scene.nil?
|
|
182
|
-
player.cue :active
|
|
183
|
-
ready
|
|
184
|
-
update
|
|
185
|
-
end
|
|
175
|
+
@introduction.call(player) unless @introduction.nil?
|
|
186
176
|
end
|
|
187
177
|
|
|
188
178
|
# Prepare the Plot for the next turn of gameplay.
|
|
189
179
|
# This method is typically called by the Engine that manages game execution.
|
|
190
180
|
def ready
|
|
191
|
-
@ready_procs.each { |p|
|
|
192
|
-
p.call
|
|
193
|
-
}
|
|
181
|
+
@ready_procs.each { |p| p.call }
|
|
194
182
|
# Prepare player scenes for the update.
|
|
195
183
|
@players.each { |player|
|
|
184
|
+
this_scene = player.next_scene || player.scene
|
|
185
|
+
player.prepare nil
|
|
186
|
+
player.cue this_scene unless player.scene == this_scene
|
|
196
187
|
@player_ready.each { |block|
|
|
197
188
|
block.call player
|
|
198
189
|
}
|
|
@@ -202,17 +193,7 @@ module Gamefic
|
|
|
202
193
|
# Update the Plot's current turn of gameplay.
|
|
203
194
|
# This method is typically called by the Engine that manages game execution.
|
|
204
195
|
def update
|
|
205
|
-
@players.each { |
|
|
206
|
-
@before_player_update_procs.each { |p| p.call player }
|
|
207
|
-
this_scene = player.next_scene || player.scene
|
|
208
|
-
player.prepare nil
|
|
209
|
-
if this_scene != player.scene
|
|
210
|
-
player.cue this_scene
|
|
211
|
-
player.queue.shift
|
|
212
|
-
else
|
|
213
|
-
process_input player
|
|
214
|
-
end
|
|
215
|
-
}
|
|
196
|
+
@players.each { |p| process_input p }
|
|
216
197
|
@entities.each { |e| e.update }
|
|
217
198
|
@players.each { |player| update_player player }
|
|
218
199
|
@update_procs.each { |p| p.call }
|
|
@@ -262,36 +243,26 @@ module Gamefic
|
|
|
262
243
|
@player_procs.push block
|
|
263
244
|
end
|
|
264
245
|
|
|
265
|
-
# Add a block to be executed for each player before the turn's update is
|
|
266
|
-
# performed.
|
|
267
|
-
#
|
|
268
|
-
# @yieldparam [Character]
|
|
269
|
-
def before_player_update &block
|
|
270
|
-
@before_player_update_procs.push block
|
|
271
|
-
end
|
|
272
|
-
|
|
273
246
|
private
|
|
247
|
+
|
|
274
248
|
def process_input player
|
|
275
249
|
line = player.queue.shift
|
|
276
250
|
if !line.nil?
|
|
277
251
|
scenes[player.scene].finish player, line
|
|
278
252
|
end
|
|
279
253
|
end
|
|
254
|
+
|
|
280
255
|
def update_player player
|
|
281
256
|
@player_procs.each { |proc|
|
|
282
257
|
proc.call player
|
|
283
258
|
}
|
|
284
259
|
end
|
|
260
|
+
|
|
285
261
|
def rem_entity(entity)
|
|
286
262
|
@entities.delete(entity)
|
|
287
263
|
@players.delete(entity)
|
|
288
264
|
end
|
|
289
|
-
|
|
290
|
-
entity.update
|
|
291
|
-
entity.children.each { |e|
|
|
292
|
-
recursive_update e
|
|
293
|
-
}
|
|
294
|
-
end
|
|
265
|
+
|
|
295
266
|
def add_syntax syntax
|
|
296
267
|
if @commands[syntax.verb] == nil
|
|
297
268
|
raise "Action \"#{syntax.verb}\" does not exist."
|
|
@@ -310,6 +281,7 @@ module Gamefic
|
|
|
310
281
|
end
|
|
311
282
|
}
|
|
312
283
|
end
|
|
284
|
+
|
|
313
285
|
def add_action(action)
|
|
314
286
|
@commands[action.verb] ||= []
|
|
315
287
|
@commands[action.verb].unshift action
|
|
@@ -324,6 +296,7 @@ module Gamefic
|
|
|
324
296
|
}
|
|
325
297
|
generate_default_syntax action
|
|
326
298
|
end
|
|
299
|
+
|
|
327
300
|
def generate_default_syntax action
|
|
328
301
|
user_friendly = action.verb.to_s.gsub(/_/, ' ')
|
|
329
302
|
args = []
|
|
@@ -341,12 +314,15 @@ module Gamefic
|
|
|
341
314
|
}
|
|
342
315
|
add_syntax Syntax.new(user_friendly.strip, "#{action.verb} #{args.join(' ')}")
|
|
343
316
|
end
|
|
317
|
+
|
|
344
318
|
def rem_action(action)
|
|
345
319
|
@commands[action.verb].delete(action)
|
|
346
320
|
end
|
|
321
|
+
|
|
347
322
|
def rem_syntax(syntax)
|
|
348
323
|
@syntaxes.delete syntax
|
|
349
324
|
end
|
|
325
|
+
|
|
350
326
|
def add_entity(entity)
|
|
351
327
|
@entities.push entity
|
|
352
328
|
end
|
|
@@ -14,10 +14,7 @@ module Gamefic
|
|
|
14
14
|
scenes[key].on_start do |actor, data|
|
|
15
15
|
data.options.push *choices
|
|
16
16
|
end
|
|
17
|
-
scenes[key].on_finish
|
|
18
|
-
block.call actor, data unless block.nil?
|
|
19
|
-
actor.cue :active if actor.scene == key and actor.next_scene.nil?
|
|
20
|
-
end
|
|
17
|
+
scenes[key].on_finish &block
|
|
21
18
|
end
|
|
22
19
|
|
|
23
20
|
# Create a yes-or-no scene.
|
|
@@ -40,10 +37,7 @@ module Gamefic
|
|
|
40
37
|
scenes[key].on_start do |actor, data|
|
|
41
38
|
data.prompt = prompt
|
|
42
39
|
end
|
|
43
|
-
scenes[key].on_finish
|
|
44
|
-
block.call actor, data unless block.nil?
|
|
45
|
-
actor.cue :active if actor.scene == key and actor.next_scene.nil?
|
|
46
|
-
end
|
|
40
|
+
scenes[key].on_finish &block
|
|
47
41
|
end
|
|
48
42
|
|
|
49
43
|
# Create a scene that pauses the game.
|
|
@@ -77,21 +71,6 @@ module Gamefic
|
|
|
77
71
|
scenes[key].on_start &block
|
|
78
72
|
end
|
|
79
73
|
|
|
80
|
-
# Create a passive scene.
|
|
81
|
-
# Passive scenes will cue the active scene if another scene
|
|
82
|
-
# has not been prepared or cued.
|
|
83
|
-
#
|
|
84
|
-
# @param [Symbol] A unique name for the scene.
|
|
85
|
-
# @yieldparam [Character]
|
|
86
|
-
# @yieldparam [Scene::Data::Base]
|
|
87
|
-
def passive key, &block
|
|
88
|
-
scenes[key] = Scene::Custom.new
|
|
89
|
-
scenes[key].on_start do |actor, data|
|
|
90
|
-
block.call actor, data
|
|
91
|
-
actor.cue :active if actor.scene == key and actor.next_scene.nil?
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
74
|
# Create a custom scene.
|
|
96
75
|
#
|
|
97
76
|
# Custom scenes should always specify the next scene to be cued or
|
|
@@ -152,7 +131,7 @@ module Gamefic
|
|
|
152
131
|
# @param key [Symbol] A unique name for the scene.
|
|
153
132
|
# @param map [Hash] A Hash of options and associated scene keys.
|
|
154
133
|
def multiple_scene key, map
|
|
155
|
-
scenes[key] = Scene::
|
|
134
|
+
scenes[key] = Scene::MultipleScene.new
|
|
156
135
|
scenes[key].on_start do |actor, data|
|
|
157
136
|
map.each { |k, v|
|
|
158
137
|
data.map k, v
|
data/lib/gamefic/query/base.rb
CHANGED
|
@@ -141,23 +141,7 @@ module Gamefic::Query
|
|
|
141
141
|
}
|
|
142
142
|
end
|
|
143
143
|
def match(description, array)
|
|
144
|
-
|
|
145
|
-
tmp = description.split(',', -1)
|
|
146
|
-
keywords = []
|
|
147
|
-
first = tmp.shift
|
|
148
|
-
if first.strip != ''
|
|
149
|
-
keywords.push first.strip
|
|
150
|
-
end
|
|
151
|
-
tmp.each { |t|
|
|
152
|
-
keywords.push ','
|
|
153
|
-
if t.strip != ''
|
|
154
|
-
keywords += t.strip.split_words
|
|
155
|
-
end
|
|
156
|
-
}
|
|
157
|
-
keywords = keywords.join(' ').split_words
|
|
158
|
-
else
|
|
159
|
-
keywords = description.split_words
|
|
160
|
-
end
|
|
144
|
+
keywords = get_keywords(description)
|
|
161
145
|
array.each { |e|
|
|
162
146
|
if e.uid == keywords[0]
|
|
163
147
|
return Matches.new([e], keywords.shift, keywords.join(' '))
|
|
@@ -193,14 +177,12 @@ module Gamefic::Query
|
|
|
193
177
|
end
|
|
194
178
|
used.push next_word
|
|
195
179
|
new_results = []
|
|
196
|
-
most_matches = 0.0
|
|
197
180
|
possibilities.each { |p|
|
|
198
181
|
words = Keywords.new(used.last)
|
|
199
182
|
if words.length > 0
|
|
200
183
|
matches = words.found_in(p.keywords, (allow_many? or allow_ambiguous?))
|
|
201
184
|
if matches > 0
|
|
202
185
|
new_results.push p
|
|
203
|
-
most_matches = matches
|
|
204
186
|
end
|
|
205
187
|
end
|
|
206
188
|
}
|
|
@@ -263,5 +245,23 @@ module Gamefic::Query
|
|
|
263
245
|
return Matches.new([], '', description)
|
|
264
246
|
end
|
|
265
247
|
end
|
|
248
|
+
|
|
249
|
+
private
|
|
250
|
+
|
|
251
|
+
def get_keywords text
|
|
252
|
+
if text.include?(',')
|
|
253
|
+
tmp = text.split(',', -1)
|
|
254
|
+
keywords = []
|
|
255
|
+
first = tmp.shift
|
|
256
|
+
keywords.push first.strip unless first.strip == ''
|
|
257
|
+
tmp.each { |t|
|
|
258
|
+
keywords.push ','
|
|
259
|
+
keywords += t.strip.split_words unless t.strip == ''
|
|
260
|
+
}
|
|
261
|
+
keywords.join(' ').split_words
|
|
262
|
+
else
|
|
263
|
+
text.split_words
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
266
|
end
|
|
267
267
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module Gamefic
|
|
2
2
|
|
|
3
|
-
class Scene::MultipleScene < Scene::
|
|
3
|
+
class Scene::MultipleScene < Scene::MultipleChoice
|
|
4
4
|
def data_class
|
|
5
5
|
SceneData::MultipleScene
|
|
6
6
|
end
|
|
@@ -8,7 +8,7 @@ module Gamefic
|
|
|
8
8
|
def finish actor, input
|
|
9
9
|
data = super
|
|
10
10
|
unless data.selection.nil?
|
|
11
|
-
actor.cue data.scene_for(selection)
|
|
11
|
+
actor.cue data.scene_for(data.selection)
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
end
|
data/lib/gamefic/scene_data.rb
CHANGED
data/lib/gamefic/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gamefic
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.4.
|
|
4
|
+
version: 1.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Fred Snyder
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-02-
|
|
11
|
+
date: 2017-02-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: thor
|