zyps 0.5.1 → 0.5.2

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