Class: Human

Inherits:
Actor show all
Defined in:
lib/zombie-chaser/human.rb

Direct Known Subclasses

MockHuman, Zombie

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Actor

#calculate_x, #calculate_y, #draw, #image, sprites, window, #window, window=, #x, #y, #z

Constructor Details

#initialize(test_handler, world) ⇒ Human

Returns a new instance of Human.



14
15
16
17
18
19
20
21
22
# File 'lib/zombie-chaser/human.rb', line 14

def initialize(test_handler, world)
  @status = nil #Currently only used by zombie
  @world = world
  @successful_step_count = 0
  @health = :alive
  @test_handler = test_handler
  @view_queue = Queue.new
  @angle = Math::PI * rand * 2.0
end

Instance Attribute Details

#successful_step_countObject (readonly)

Returns the value of attribute successful_step_count.



6
7
8
# File 'lib/zombie-chaser/human.rb', line 6

def successful_step_count
  @successful_step_count
end

Class Method Details

.new_using_test_unit_handler(test_pattern, world) ⇒ Object



8
9
10
11
12
# File 'lib/zombie-chaser/human.rb', line 8

def self.new_using_test_unit_handler(test_pattern, world)
  test_handler = TestUnitHandler.new(test_pattern)
  human = new(test_handler, world)
  human
end

Instance Method Details

#actor_directionObject



107
108
109
# File 'lib/zombie-chaser/human.rb', line 107

def actor_direction
  @angle * -360.0 / (2 * Math::PI)
end

#actor_stateObject



95
96
97
98
99
100
101
102
103
104
105
# File 'lib/zombie-chaser/human.rb', line 95

def actor_state
  return "attacking" if @status == :attacking
  case @health
  when :alive
    "moving"
  when :dying
    "dying"
  when :dead
    "dead"
  end
end

#actor_typeObject



91
92
93
# File 'lib/zombie-chaser/human.rb', line 91

def actor_type
  'robot'
end

#build_view_queueObject



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/zombie-chaser/human.rb', line 43

def build_view_queue
  while true
    result = @test_handler.result_queue.deq #Slight law of demeter violation
    case result
    when :pass
      @view_queue.enq(:passing_step)
    when :failure
      @view_queue.enq(:start_dying)
      @view_queue.enq(:finish_dying)
    when :end_of_work
      @view_queue.enq(:end_of_work)
      break
    else raise "Unknown result!"
    end
  end
  @view_queue.enq(:end_of_work)
end

#current_symbolObject



80
81
82
83
84
85
86
87
88
89
# File 'lib/zombie-chaser/human.rb', line 80

def current_symbol
  case @health
  when :alive
    "@"
  when :dying
    "*"
  when :dead
    "+"
  end
end

#dead?Boolean

Returns:

  • (Boolean)


145
146
147
# File 'lib/zombie-chaser/human.rb', line 145

def dead?
  @health == :dead
end

#get_eatenObject



165
166
167
# File 'lib/zombie-chaser/human.rb', line 165

def get_eaten
  @health = :dead unless dead?
end

#no_other_living_zombies_in?(desired_step_count) ⇒ Boolean

Returns:

  • (Boolean)


130
131
132
# File 'lib/zombie-chaser/human.rb', line 130

def no_other_living_zombies_in?(desired_step_count)
  @world.no_living_zombies_apart_from_me?(desired_step_count, self)
end

#notify_finish_dyingObject



149
150
151
152
153
154
155
# File 'lib/zombie-chaser/human.rb', line 149

def notify_finish_dying
  sleep 0.5
  raise "I'm not dead yet!" unless dying?
  @health = :dead
  notify_world
  sleep 0.5
end

#notify_finishedObject



157
158
159
# File 'lib/zombie-chaser/human.rb', line 157

def notify_finished
  #Do nothing in humans
end

#notify_passing_stepObject



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/zombie-chaser/human.rb', line 111

def notify_passing_step
  break_out_of_loop = false
  while true
    # This synchronization doesn't actually work. The unit test dont_test_zombies_do_not_collide seem to pass on 1.8 and fail on 1.9, though it could be coincidence.
    # Fixme Find out why my use of synchronization doesn't work, while remembering that select is not broken.
    @world.synchronize_for_collision_detection do
      if no_other_living_zombies_in?(@successful_step_count + 1)
        @successful_step_count += 1
        break_out_of_loop = true
      end
    end
    break if break_out_of_loop
    shuffle_in_one_place
  end
  increase_angle_by(13) if defined?(@lurch_offset)
  sleep([0.1, 2.0 / test_suite_size].min)
  notify_world
end

#notify_start_dyingObject



134
135
136
137
138
# File 'lib/zombie-chaser/human.rb', line 134

def notify_start_dying
  @health = :dying
  sleep 0.5
  notify_world
end

#notify_worldObject



161
162
163
# File 'lib/zombie-chaser/human.rb', line 161

def notify_world
  @world.something_happened
end

#runObject



24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/zombie-chaser/human.rb', line 24

def run
  test_running_thread = Thread.new do
    run_tests
  end
  view_queue_updating_thread = Thread.new do
    build_view_queue
  end
  status_updating_thread = Thread.new do
    update_view
  end
  status_updating_thread.join
  view_queue_updating_thread.join
  test_running_thread.join
end

#run_testsObject



39
40
41
# File 'lib/zombie-chaser/human.rb', line 39

def run_tests
  @test_handler.run
end

#test_suite_sizeObject



169
170
171
172
173
# File 'lib/zombie-chaser/human.rb', line 169

def test_suite_size
  #This is valid from when @test_handler is initialized
  #And that is done when human is initialized
  @test_handler.test_suite_size
end

#update_viewObject



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/zombie-chaser/human.rb', line 61

def update_view
  notify_world
  while true
    result = @view_queue.deq
    case result
    when :passing_step
      notify_passing_step
    when :start_dying
      notify_start_dying
    when :finish_dying
      notify_finish_dying
    when :end_of_work
      notify_finished
      break
    else raise "Unknown result!"
    end
  end
end