1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
|
class SimModel
include Math
WORLD_VERSION=3
DEFAULT_TIME = Time.gm(2007,"jan",1,0,0,0)
attr_accessor :running
attr_accessor :runOnce
attr_accessor :airports
attr_accessor :planes
attr_accessor :time
attr_accessor :ageBias
attr_accessor :day
attr_accessor :month
attr_accessor :people
attr_accessor :something_happened
attr_accessor :distances
attr_accessor :bearings
attr_accessor :world
attr_accessor :allowed_trips
def initialize(world)
@allowed_trips = 4
@world = world
@version = 2.0
@planes=[]
@airports=[]
@people=[]
@distances = {}
@bearings = {}
@ageBias = 0.05
@day = 0
reset
end
def reset(time=DEFAULT_TIME)
@time = time
@run_start_time = time
@planes.each {|p| p.reset }
@airports.each {|a| a.reset }
@people.each {|p| p.reset }
@day = 0
clearLog
addLog("RESET")
end
def clearPopulation
for a in @airports
a.clear
end
for p in @planes
p.clear
end
@people = []
end
def buildPopulation
while @people.length < MAXIMUM_POPULATION
for a in @airports
a.think_populate(1)
end
end
end
def wind(position)
angle = 90
speed = 15
cosA = Math.cos(angle)
sinA = Math.sin(angle)
x -= (cosA * speed.to_f)
y -= (sinA * speed.to_f)
[x,y]
end
def logText
ret = ""
@logLines.last(300).reverse.each do |line|
puts line
ret += line[0].strftime("%m/%d - %H:%M")
ret += " "
ret += line[1].to_s
ret += "\n"
end
ret
end
def addLog(message)
@logLines << [@time, message]
end
def clearLog
@logLines = []
end
def cost_cities(plane)
routes = []
if plane.landed_airport
costs = {}
for a in @airports
plane.landed_airport.routes(a, plane.range).each {|r| routes << Route.new(r)}
end
for r in routes
if r.airports.length > 2
last = r.airports.first
for a in r.airports[1..-1]
r.distance += distance_to(last, a)
d_affect = plane.range / r.distance
last = a
if plane.room_left
r.weight += a.waiting.length * d_affect
end
if plane.passengers.length > 0
pax = plane.passengers.select{|p| p.target == a}
pax.each {|p| r.weight += (ageBias * p.age) * d_affect}
end
end
end
end
end
routes.sort { |one, other| other.weight <=> one.weight }
end
def dispatch(plane)
if plane.speed > 0
if (plane.landed or plane.target_airport.nil?) and (plane.passengers.length > 0 or total_waiting > 0)
if plane.landed_airport == plane.home
if plane.destination.waiting.length > 0 or plane.passengers.length > 0
target = plane.destination
end
else
if plane.home.waiting.length > 0 or plane.passengers.length > 0
if plane.dayschedule[self.time.strftime("%w").to_i] == 1
target = plane.home
end
end
end
if target
addLog "PICKTARGET #{plane.tail} #{target} [#{plane.passengers.length} pax /#{total_waiting} demand]"
plane.target target
end
end
end
end
def total_waiting
tot = 0
@people.each {|a| tot += 1 if a.waiting}
tot
end
def setVersion
@version = WORLD_VERSION
end
def build_distances
@distances = {}
for a in self.airports
for b in self.airports
if a!=b
@distances[[a,b]] = a.distance_to(b)
@bearings[[a,b]] = a.bearing_to(b)
end
end
end
end
def randomArrivalAirport(exclude = nil)
airports = @airports
if airports.length > 0
airport = (airports - exclude).sort_by{rand}[0]
else
airport = nil
end
addLog "RAA #{airport} (of #{airports.length} choices)"
airport
end
def randomAirport(exclude = nil)
(@airports - exclude).sort_by{rand}[0]
end
def getAirport(index)
@airports[index]
end
def airportCount
@airports.length
end
def delAirport(index)
p = getAirport index
p.name = "Deleted"
@airports.delete p
end
def addAirport(airport)
@airports << airport
build_distances
end
def getPlane(index)
@planes[index]
end
def planeCount
@planes.length
end
def delPlane(index)
p = getPlane index
p.tail = "Deleted"
@planes.delete p
end
def addPlane(plane)
@planes << plane
end
def tick_month
for p in @people
p.tick_month
end
end
def tick_day
for p in @people
p.tick_day
end
end
def tick
@time += 60*6
@planes.sort_by{rand}.each {|plane| plane.think}
@airports.sort_by{rand}.each {|airport| airport.think}
@people.sort_by{rand}.each {|pax| pax.think}
newday = ((@time-@run_start_time)/(60*60*24)).floor
newmonth = @time.strftime("%m").to_i
if @day != newday
tick_day
end
if @month = newmonth
tick_month
end
@day = newday
@month=newmonth
end
def sanity_check(world, version)
clearLog
@world = world
@version = version
addLog "Simulation Loaded."
@airports.each{|x| x.sanity_check self, @version}
@planes.each{|x| x.sanity_check self, @version}
@people.each{|x| x.sanity_check self, @version}
end
def populate(pax)
@people << pax
addLog "#{pax.name} has entered the world."
end
end |