zyps 0.5.1 → 0.5.2

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/bin/zyps CHANGED
@@ -46,6 +46,7 @@ class Application
46
46
 
47
47
  #Create a window, and set GTK up to quit when it is closed.
48
48
  window = Gtk::Window.new
49
+ window.resizable = false
49
50
  window.signal_connect("delete_event") {false}
50
51
  window.signal_connect("destroy") {Gtk.main_quit}
51
52
 
@@ -77,6 +78,9 @@ class Application
77
78
 
78
79
  #Keep all objects under a certain speed.
79
80
  @environment.environmental_factors << SpeedLimit.new(100)
81
+
82
+ #Set up a creature generator.
83
+ @generator = CreatureGenerator.new(@environment)
80
84
 
81
85
  #Create thread to update environment.
82
86
  thread = Thread.new do
@@ -126,65 +130,34 @@ class Application
126
130
  #Add view to interface.
127
131
  @view = TrailsView.new(width, height)
128
132
  interface.pack_start(@view.canvas, expand, fill, padding)
129
- #Get mouse events on view.
133
+
134
+ #When mouse button pressed, record location for use in release event handler.
130
135
  @view.canvas.add_events(Gdk::Event::BUTTON_PRESS_MASK)
131
136
  @view.canvas.signal_connect("button-press-event") do |canvas, event|
132
137
  @press_location = Location.new(event.x, event.y)
133
138
  end
139
+
140
+ #Create a creature on button release.
134
141
  @view.canvas.add_events(Gdk::Event::BUTTON_RELEASE_MASK)
135
142
  @view.canvas.signal_connect("button-release-event") do |canvas, event|
136
143
  @release_location = Location.new(event.x, event.y)
137
- creature = Creature.new(
138
- '',
139
- @release_location,
140
- Color.new(@red_slider.value, @green_slider.value, @blue_slider.value),
141
- Vector.new(
142
- Utility.find_distance(@press_location, @release_location) * 2, #Use distance dragged as speed.
143
- Utility.find_angle(@press_location, @release_location) #Move in direction of drag.
144
- ),
145
- 0,
146
- 1
144
+ @generator.create_creature(
145
+ :x => event.x,
146
+ :y => event.y,
147
+ :speed => Utility.find_distance(@press_location, @release_location) * 2, #Use distance dragged as speed.
148
+ :pitch => Utility.find_angle(@press_location, @release_location), #Move in direction of drag.
149
+ :accelerate => @accelerate_flag.active?,
150
+ :turn => @turn_flag.active?,
151
+ :approach => @approach_flag.active?,
152
+ :flee => @flee_flag.active?,
153
+ :push => @push_flag.active?,
154
+ :pull => @pull_flag.active?,
155
+ :eat => @eat_flag.active?
147
156
  )
148
- behavior = Behavior.new
149
- behavior.conditions << ProximityCondition.new(200)
150
- behavior.actions << AccelerateAction.new(1) if @accelerate_flag.active?
151
- behavior.actions << TurnAction.new(90) if @turn_flag.active?
152
- behavior.actions << ApproachAction.new(creature.vector, 720) if @approach_flag.active?
153
- behavior.actions << FleeAction.new(creature.vector) if @flee_flag.active?
154
- behavior.actions << PushAction.new(1000) if @push_flag.active?
155
- behavior.actions << PullAction.new(1000) if @pull_flag.active?
156
- behavior.actions << BlendAction.new(creature.color) if @paint_flag.active?
157
- creature.behaviors << behavior
158
- if @eat_flag.active?
159
- behavior = Behavior.new
160
- behavior.actions << EatAction.new(@environment)
161
- behavior.conditions << ProximityCondition.new(10)
162
- creature.behaviors << behavior
163
- end
164
- @environment.objects << creature
165
157
  end
166
158
 
167
159
  #Create a VBox for all controls.
168
160
  control_panel = Gtk::VBox.new(homogeneous, spacing)
169
-
170
- #Create a group for the new object's attributes.
171
- attribute_controls = Gtk::VBox.new(homogeneous, spacing)
172
-
173
- #Add sliders for the color components.
174
- attribute_controls.pack_start(Gtk::Label.new("Color"), expand, fill, padding)
175
- attribute_controls.pack_start(Gtk::Label.new("R"), expand, fill, padding)
176
- @red_slider = Gtk::HScale.new(0, 1, 0.1)
177
- attribute_controls.pack_start(@red_slider, expand, fill, padding)
178
- attribute_controls.pack_start(Gtk::Label.new("G"), expand, fill, padding)
179
- @green_slider = Gtk::HScale.new(0, 1, 0.1)
180
- attribute_controls.pack_start(@green_slider, expand, fill, padding)
181
- attribute_controls.pack_start(Gtk::Label.new("B"), expand, fill, padding)
182
- @blue_slider = Gtk::HScale.new(0, 1, 0.1)
183
- attribute_controls.pack_start(@blue_slider, expand, fill, padding)
184
- @red_slider.value, @green_slider.value, @blue_slider.value = 1, 1, 1
185
-
186
- #Add the attribute controls to the panel.
187
- control_panel.pack_start(attribute_controls, expand, fill, padding)
188
161
 
189
162
  #Create a group for the actions.
190
163
  action_controls = Gtk::VBox.new(homogeneous, spacing)
@@ -203,8 +176,6 @@ class Application
203
176
  action_controls.pack_start(@pull_flag, expand, fill, padding)
204
177
  @eat_flag = Gtk::CheckButton.new("Eat")
205
178
  action_controls.pack_start(@eat_flag, expand, fill, padding)
206
- @paint_flag = Gtk::CheckButton.new("Paint")
207
- action_controls.pack_start(@paint_flag, expand, fill, padding)
208
179
  #Add the action controls to the panel.
209
180
  control_panel.pack_start(action_controls, expand, fill, padding)
210
181
 
@@ -219,6 +190,121 @@ class Application
219
190
  end
220
191
 
221
192
 
193
+
194
+ class CreatureGenerator
195
+
196
+ #Environment creatures will be added to.
197
+ attr_accessor :environment
198
+ #Default required proximity for actions.
199
+ attr_accessor :action_proximity
200
+ #Speed of new AccelerateActions.
201
+ attr_accessor :acceleration_rate
202
+ #Rate of new TurnActions.
203
+ attr_accessor :turn_rate
204
+ #Turn rate of new ApproachActions.
205
+ attr_accessor :approach_turn_rate
206
+ #Turn rate of new FleeActions.
207
+ attr_accessor :flee_turn_rate
208
+ #Strength of new PullActions.
209
+ attr_accessor :pull_strength
210
+ #Strength of new PushActions.
211
+ attr_accessor :push_strength
212
+
213
+ def initialize(environment)
214
+
215
+ @environment = environment
216
+
217
+ #Set up defaults for attributes.
218
+ @action_proximity = 200
219
+ @acceleration_rate = 1
220
+ @turn_rate = 90
221
+ @approach_turn_rate = 720
222
+ @flee_turn_rate = @approach_turn_rate
223
+ @pull_strength = 1000
224
+ @push_strength = @pull_strength
225
+
226
+ end
227
+
228
+
229
+ #Create a creature and add it to the environment.
230
+ def create_creature(options = {})
231
+
232
+ {
233
+ :x => 0,
234
+ :y => 0,
235
+ :speed => 1,
236
+ :pitch => 0,
237
+ :action_proximity => @action_proximity,
238
+ :accelerate => false,
239
+ :turn => false,
240
+ :approach => false,
241
+ :flee => false,
242
+ :push => false,
243
+ :pull => false,
244
+ :eat => false,
245
+ }.merge!(options)
246
+
247
+ #Set up the creature's vector.
248
+ vector = Vector.new(options[:speed], options[:pitch])
249
+
250
+ #Set up actions and merge colors according to selected behaviors.
251
+ behavior = Behavior.new
252
+ behavior.conditions << ProximityCondition.new(@action_proximity)
253
+ color = Color.new(0.25, 0.25, 0.25)
254
+ if options[:accelerate]
255
+ color.red += 0.25
256
+ color.green += 0.25
257
+ color.blue += 0.25
258
+ behavior.actions << AccelerateAction.new(@acceleration_rate)
259
+ end
260
+ if options[:turn]
261
+ color.blue += 1
262
+ behavior.actions << TurnAction.new(@turn_rate)
263
+ end
264
+ if options[:approach]
265
+ color.red += 1
266
+ behavior.actions << ApproachAction.new(vector, @approach_turn_rate)
267
+ end
268
+ if options[:flee]
269
+ color.red += 0.5; color.green += 0.5 #Yellow.
270
+ behavior.actions << FleeAction.new(vector, @flee_turn_rate)
271
+ end
272
+ if options[:push]
273
+ color.red += 0.5; color.blue += 0.5 #Purple.
274
+ behavior.actions << PushAction.new(@push_strength)
275
+ end
276
+ if options[:pull]
277
+ color.blue += 0.75; color.green += 0.75 #Aqua.
278
+ behavior.actions << PullAction.new(@pull_strength)
279
+ end
280
+
281
+ #Create a creature.
282
+ creature = Creature.new(
283
+ '',
284
+ Location.new(options[:x], options[:y]),
285
+ color,
286
+ vector,
287
+ 0,
288
+ 5
289
+ )
290
+ creature.behaviors << behavior
291
+
292
+ #Special handling for eat action, which needs a CollisionCondition.
293
+ if options[:eat]
294
+ creature.color.green += 1
295
+ behavior = Behavior.new
296
+ behavior.actions << EatAction.new(@environment)
297
+ behavior.conditions << CollisionCondition.new
298
+ creature.behaviors << behavior
299
+ end
300
+
301
+ @environment.objects << creature
302
+
303
+ end
304
+ end
305
+
306
+
307
+
222
308
  begin
223
309
  #The view width.
224
310
  WIDTH = 500
@@ -26,7 +26,7 @@ class TagCondition < Condition
26
26
  self.tag = tag
27
27
  end
28
28
  #True if the target has the assigned tag.
29
- def test(actor, target)
29
+ def met?(actor, target)
30
30
  target.tags.include?(@tag)
31
31
  end
32
32
  end
@@ -40,7 +40,7 @@ class AgeCondition < Condition
40
40
  self.age = age
41
41
  end
42
42
  #True if the target is older than the assigned age.
43
- def test(actor, target)
43
+ def met?(actor, target)
44
44
  target.age > @age
45
45
  end
46
46
  end
@@ -54,7 +54,7 @@ class ProximityCondition < Condition
54
54
  self.distance = distance
55
55
  end
56
56
  #True if the actor and target are equal to or closer than the given distance.
57
- def test(actor, target)
57
+ def met?(actor, target)
58
58
  Utility.find_distance(actor.location, target.location) <= @distance
59
59
  end
60
60
  end
@@ -63,7 +63,7 @@ end
63
63
  #True only if collided with target.
64
64
  class CollisionCondition < Condition
65
65
  #True if the objects have collided.
66
- def test(actor, target)
66
+ def met?(actor, target)
67
67
  Utility.collided?(actor, target)
68
68
  end
69
69
  end
data/lib/zyps.rb CHANGED
@@ -229,7 +229,7 @@ class Behavior
229
229
  #Select a target that matches all conditions.
230
230
  def select_target(actor, targets)
231
231
  #If a target is already active, still present in the environment, and all conditions are true for it, simply re-select it.
232
- if @active_target and targets.include?(@active_target) and conditions.all?{|condition| condition.test(actor, @active_target)}
232
+ if @active_target and targets.include?(@active_target) and conditions.all?{|condition| condition.met?(actor, @active_target)}
233
233
  return @active_target
234
234
  end
235
235
  #For each object in environment:
@@ -237,7 +237,7 @@ class Behavior
237
237
  #Don't let actor target itself.
238
238
  next if target == actor
239
239
  #If all conditions match (or there are no conditions), select the object.
240
- if conditions.all?{|condition| condition.test(actor, target)}
240
+ if conditions.all?{|condition| condition.met?(actor, target)}
241
241
  @active_target = target
242
242
  return target
243
243
  end
data/test/test_zyps.rb CHANGED
@@ -196,7 +196,7 @@ class TestEnvironment < Test::Unit::TestCase
196
196
 
197
197
  #A condition that is false unless actor and target have specific names.
198
198
  class NameCondition < Condition
199
- def test(actor, target)
199
+ def met?(actor, target)
200
200
  return true if actor.name == '1' and target.name == '2'
201
201
  end
202
202
  end
@@ -478,13 +478,13 @@ class TestBehavior < Test::Unit::TestCase
478
478
 
479
479
  #Always true.
480
480
  class TrueCondition < Condition
481
- def test(actor, target)
481
+ def met?(actor, target)
482
482
  true
483
483
  end
484
484
  end
485
485
  #Always false.
486
486
  class FalseCondition < Condition
487
- def test(actor, target)
487
+ def met?(actor, target)
488
488
  false
489
489
  end
490
490
  end
@@ -21,6 +21,10 @@ require 'zyps/actions'
21
21
  require 'test/unit'
22
22
 
23
23
 
24
+ #Allowed deviation for assert_in_delta.
25
+ REQUIRED_ACCURACY = 0.001
26
+
27
+
24
28
  #Redefine Clock to return a predictable time.
25
29
  class Clock
26
30
  def elapsed_time; 0.1; end
@@ -53,7 +57,7 @@ class TestActions < Test::Unit::TestCase
53
57
  def test_face_action
54
58
  add_action(FaceAction.new, @actor)
55
59
  @environment.interact
56
- assert_equal(45, @actor.vector.pitch)
60
+ assert_in_delta(45, @actor.vector.pitch, REQUIRED_ACCURACY)
57
61
  end
58
62
 
59
63
 
@@ -63,7 +67,7 @@ class TestActions < Test::Unit::TestCase
63
67
  add_action(AccelerateAction.new(1), @actor)
64
68
  @environment.interact
65
69
  #Clock always returns 0.1 seconds, so actor should be moving 0.1 unit/second faster.
66
- assert_equal(0.1, @actor.vector.speed)
70
+ assert_in_delta(0.1, @actor.vector.speed, REQUIRED_ACCURACY)
67
71
  end
68
72
 
69
73
 
@@ -73,7 +77,7 @@ class TestActions < Test::Unit::TestCase
73
77
  add_action(TurnAction.new(1), @actor)
74
78
  @environment.interact
75
79
  #Clock always returns 0.1 seconds, so actor should be turned 0.1 degrees.
76
- assert_equal(0.1, @actor.vector.pitch)
80
+ assert_in_delta(0.1, @actor.vector.pitch, REQUIRED_ACCURACY)
77
81
  end
78
82
 
79
83
 
@@ -87,11 +91,11 @@ class TestActions < Test::Unit::TestCase
87
91
  #Act.
88
92
  @environment.interact
89
93
  #Ensure action's thrust vector is correct for 0.1 seconds.
90
- assert_equal(1.0, action.heading.speed)
91
- assert_equal(4.0, action.heading.pitch)
94
+ assert_in_delta(1.0, action.heading.speed, REQUIRED_ACCURACY)
95
+ assert_in_delta(4.0, action.heading.pitch, REQUIRED_ACCURACY)
92
96
  #Ensure actor's resulting vector is correct.
93
- assert_in_delta(0.997, @actor.vector.x, 0.001)
94
- assert_in_delta(0.069, @actor.vector.y, 0.001)
97
+ assert_in_delta(0.997, @actor.vector.x, REQUIRED_ACCURACY)
98
+ assert_in_delta(0.069, @actor.vector.y, REQUIRED_ACCURACY)
95
99
 
96
100
  end
97
101
 
@@ -107,11 +111,11 @@ class TestActions < Test::Unit::TestCase
107
111
  @environment.interact
108
112
 
109
113
  #Ensure actor is approaching target directly.
110
- assert_equal(1.0, action.heading.speed)
111
- assert_equal(45, action.heading.pitch)
114
+ assert_in_delta(1.0, action.heading.speed, REQUIRED_ACCURACY)
115
+ assert_in_delta(45, action.heading.pitch, REQUIRED_ACCURACY)
112
116
  #Ensure actor's resulting vector is correct.
113
- assert_in_delta(0.707, @actor.vector.x, 0.001)
114
- assert_in_delta(0.707, @actor.vector.y, 0.001)
117
+ assert_in_delta(0.707, @actor.vector.x, REQUIRED_ACCURACY)
118
+ assert_in_delta(0.707, @actor.vector.y, REQUIRED_ACCURACY)
115
119
 
116
120
  end
117
121
 
@@ -126,11 +130,11 @@ class TestActions < Test::Unit::TestCase
126
130
  #Act.
127
131
  @environment.interact
128
132
  #Ensure action's thrust vector is correct for 0.1 seconds.
129
- assert_equal(1.0, action.heading.speed)
130
- assert_equal(356.0, action.heading.pitch) #Should be heading away.
133
+ assert_in_delta(1.0, action.heading.speed, REQUIRED_ACCURACY)
134
+ assert_in_delta(356.0, action.heading.pitch, REQUIRED_ACCURACY) #Should be heading away.
131
135
  #Ensure actor's resulting vector is correct.
132
- assert_in_delta(0.997, @actor.vector.x, 0.001)
133
- assert_in_delta(-0.069, @actor.vector.y, 0.001)
136
+ assert_in_delta(0.997, @actor.vector.x, REQUIRED_ACCURACY)
137
+ assert_in_delta(-0.069, @actor.vector.y, REQUIRED_ACCURACY)
134
138
  end
135
139
 
136
140
  #Ensure flee action doesn't oversteer.
@@ -144,11 +148,11 @@ class TestActions < Test::Unit::TestCase
144
148
  #Act.
145
149
  @environment.interact
146
150
  #Ensure actor is fleeing directly away from target.
147
- assert_equal(1.0, action.heading.speed)
148
- assert_equal(225, action.heading.pitch)
151
+ assert_in_delta(1.0, action.heading.speed, REQUIRED_ACCURACY)
152
+ assert_in_delta(225, action.heading.pitch, REQUIRED_ACCURACY)
149
153
  #Ensure actor's resulting vector is correct.
150
- assert_in_delta(-0.707, @actor.vector.x, 0.001)
151
- assert_in_delta(-0.707, @actor.vector.y, 0.001)
154
+ assert_in_delta(-0.707, @actor.vector.x, REQUIRED_ACCURACY)
155
+ assert_in_delta(-0.707, @actor.vector.y, REQUIRED_ACCURACY)
152
156
 
153
157
  end
154
158
 
@@ -181,7 +185,7 @@ class TestActions < Test::Unit::TestCase
181
185
  #Verify target is removed from environment.
182
186
  assert(! @environment.objects.include?(@target1))
183
187
  #Verify creature has grown by the appropriate amount.
184
- assert_equal(2, @actor.size)
188
+ assert_in_delta(2, @actor.size, REQUIRED_ACCURACY)
185
189
  end
186
190
 
187
191
 
@@ -204,9 +208,9 @@ class TestActions < Test::Unit::TestCase
204
208
  #Act.
205
209
  @environment.interact
206
210
  #Verify the target's new color.
207
- assert_equal(0.25, @target1.color.red)
208
- assert_equal(0.25, @target1.color.green)
209
- assert_equal(0.25, @target1.color.blue)
211
+ assert_in_delta(0.25, @target1.color.red, REQUIRED_ACCURACY)
212
+ assert_in_delta(0.25, @target1.color.green, REQUIRED_ACCURACY)
213
+ assert_in_delta(0.25, @target1.color.blue, REQUIRED_ACCURACY)
210
214
  end
211
215
 
212
216
  #Test shifting colors toward white.
@@ -218,9 +222,9 @@ class TestActions < Test::Unit::TestCase
218
222
  #Act.
219
223
  @environment.interact
220
224
  #Verify the target's new color.
221
- assert_equal(0.75, @target1.color.red)
222
- assert_equal(0.75, @target1.color.green)
223
- assert_equal(0.75, @target1.color.blue)
225
+ assert_in_delta(0.75, @target1.color.red, REQUIRED_ACCURACY)
226
+ assert_in_delta(0.75, @target1.color.green, REQUIRED_ACCURACY)
227
+ assert_in_delta(0.75, @target1.color.blue, REQUIRED_ACCURACY)
224
228
  end
225
229
 
226
230
 
@@ -230,8 +234,8 @@ class TestActions < Test::Unit::TestCase
230
234
  add_action(PushAction.new(1), @actor)
231
235
  @environment.interact
232
236
  #Verify target's speed and direction are correct.
233
- assert_equal(0.1, @target1.vector.speed, "@target1 should have been pushed away from @actor.")
234
- assert_equal(45.0, @target1.vector.pitch, "@target1's angle should be facing away from @actor.")
237
+ assert_in_delta(0.1, @target1.vector.speed, REQUIRED_ACCURACY, "@target1 should have been pushed away from @actor.")
238
+ assert_in_delta(45.0, @target1.vector.pitch, REQUIRED_ACCURACY, "@target1's angle should be facing away from @actor.")
235
239
  end
236
240
 
237
241
 
@@ -241,8 +245,8 @@ class TestActions < Test::Unit::TestCase
241
245
  add_action(PullAction.new(1), @actor)
242
246
  @environment.interact
243
247
  #Verify target's speed and direction are correct.
244
- assert_equal(0.1, @target1.vector.speed, "@target1 should have been pulled toward @actor.")
245
- assert_equal(225.0, @target1.vector.pitch, "@target1's angle should be facing toward @actor.")
248
+ assert_in_delta(0.1, @target1.vector.speed, REQUIRED_ACCURACY, "@target1 should have been pulled toward @actor.")
249
+ assert_in_delta(225.0, @target1.vector.pitch, REQUIRED_ACCURACY, "@target1's angle should be facing toward @actor.")
246
250
  end
247
251
 
248
252
  end
@@ -39,10 +39,10 @@ class TestConditions < Test::Unit::TestCase
39
39
  def test_tag_condition
40
40
  condition = TagCondition.new("tag")
41
41
  #Test for falsehood.
42
- assert(! condition.test(@actor, @target))
42
+ assert(! condition.met?(@actor, @target))
43
43
  #Test for truth.
44
44
  @target.tags << "tag"
45
- assert(condition.test(@actor, @target))
45
+ assert(condition.met?(@actor, @target))
46
46
  end
47
47
 
48
48
 
@@ -50,22 +50,22 @@ class TestConditions < Test::Unit::TestCase
50
50
  condition = AgeCondition.new(0.2)
51
51
  #Test for falsehood.
52
52
  @target.age = 0.1
53
- assert(! condition.test(@actor, @target))
53
+ assert(! condition.met?(@actor, @target))
54
54
  #Test for truth.
55
55
  @target.age = 0.2
56
- assert(condition.test(@actor, @target))
56
+ assert(condition.met?(@actor, @target))
57
57
  @target.age = 0.3
58
- assert(condition.test(@actor, @target))
58
+ assert(condition.met?(@actor, @target))
59
59
  end
60
60
 
61
61
 
62
62
  def test_proximity_condition
63
63
  condition = ProximityCondition.new(1)
64
64
  #Test for falsehood.
65
- assert(! condition.test(@actor, @target))
65
+ assert(! condition.met?(@actor, @target))
66
66
  #Test for truth.
67
67
  @target.location = Location.new(0.5, 0.5)
68
- assert(condition.test(@actor, @target))
68
+ assert(condition.met?(@actor, @target))
69
69
  end
70
70
 
71
71
 
@@ -73,10 +73,10 @@ class TestConditions < Test::Unit::TestCase
73
73
  condition = CollisionCondition.new
74
74
  #Test for falsehood.
75
75
  @actor.size, @target.size = 0.196, 0.196 #Radius = 0.25
76
- assert(! condition.test(@actor, @target))
76
+ assert(! condition.met?(@actor, @target))
77
77
  #Test for truth.
78
78
  @actor.size, @target.size = 1.766, 1.766 #Radius = 0.75
79
- assert(condition.test(@actor, @target))
79
+ assert(condition.met?(@actor, @target))
80
80
  end
81
81
 
82
82
 
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: zyps
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.5.1
7
- date: 2007-09-23 00:00:00 -07:00
6
+ version: 0.5.2
7
+ date: 2007-09-24 00:00:00 -07:00
8
8
  summary: A game library for Ruby
9
9
  require_paths:
10
10
  - lib