Old revision #pfsmdufv4 | New revision #pempnuqzd | ||
---|---|---|---|
2 | { | 2 | { |
3 | /* Return if nothing to do. Also the rounding below fails for 0. */ | 3 | /* Return if nothing to do. Also the rounding below fails for 0. */ |
4 | if (amount == 0) return 0; | 4 | if (amount == 0) return 0; |
5 | |||
6 | Station *st1 = NULL; // Station with best rating | 5 | Station *st1 = NULL; // Station with best rating |
7 | Station *st2 = NULL; // Second best station | 6 | Station *st2 = NULL; // Second best station |
8 | Station *st3 = NULL; // Third best station | 7 | Station *st3 = NULL; // Third best station |
8 | Station *st4 = NULL; // Fourth best station | ||
9 | Station *st5 = NULL; // Fifth best station | ||
10 | Station *st6 = NULL; // Sixth best station | ||
9 | uint best_rating1 = 0; // rating of st1 | 11 | uint best_rating1 = 0; // rating of st1 |
10 | uint best_rating2 = 0; // rating of st2 | 12 | uint best_rating2 = 0; // rating of st2 |
11 | uint best_rating3 = 0; // rating of st3 | 13 | uint best_rating3 = 0; // rating of st3 |
14 | uint best_rating4 = 0; // rating of st4 | ||
15 | uint best_rating5 = 0; // rating of st5 | ||
16 | uint best_rating6 = 0; // rating of st6 | ||
12 | 17 | ||
13 | for (Station * const *st_iter = all_stations->Begin(); st_iter != all_stations->End(); ++st_iter) { | 18 | for (Station * const *st_iter = all_stations->Begin(); st_iter != all_stations->End(); ++st_iter) { |
14 | Station *st = *st_iter; | 19 | Station *st = *st_iter; | … | … |
26 | if (st->facilities == FACIL_BUS_STOP) continue; // non-passengers are never served by just a bus stop | 31 | if (st->facilities == FACIL_BUS_STOP) continue; // non-passengers are never served by just a bus stop |
27 | } | 32 | } |
28 | 33 | ||
29 | /* This station can be used, add it to st1/st2/st3 | 29 | /* This station can be used, add it to st1/st2/st3/st4/st5/st6 */ |
30 | if (st1 == NULL || st->goods[type].rating >= best_rating1) { | 35 | if (st1 == NULL || st->goods[type].rating >= best_rating1) { |
31 | st | 31 | st6 = st5; best_rating6 = best_rating5; |
32 | | 32 | st5 = st4; best_rating5 = best_rating4; |
33 | st | 33 | st4 = st3; best_rating4 = best_rating3; |
34 | | 34 | st3 = st2; best_rating3 = best_rating2; |
35 | st | 35 | st2 = st1; best_rating2 = best_rating1; |
36 | | 36 | st1 = st; best_rating1 = st->goods[type].rating; |
37 | } else if (st2 == NULL || st->goods[type].rating >= best_rating2) { | 42 | } else if (st2 == NULL || st->goods[type].rating >= best_rating2) { |
38 | st3 = st2; | 43 | st6 = st5; best_rating6 = best_rating5; |
39 | best_rating3 = best_rating2; | 44 | st5 = st4; best_rating5 = best_rating4; |
40 | st2 = st; | 45 | st4 = st3; best_rating4 = best_rating3; |
41 | best_rating2 = st->goods[type].rating; | 46 | st3 = st2; best_rating3 = best_rating2; |
47 | st2 = st; best_rating2 = st->goods[type].rating; | ||
42 | } else if (st3 == NULL || st->goods[type].rating >= best_rating3) { | 48 | } else if (st3 == NULL || st->goods[type].rating >= best_rating3) { |
43 | st3 = st; | 49 | st6 = st5; best_rating6 = best_rating5; |
44 | best_rating3 = st->goods[type].rating; | 50 | st5 = st4; best_rating5 = best_rating4; |
51 | st4 = st3; best_rating4 = best_rating3; | ||
52 | st3 = st; best_rating3 = st->goods[type].rating; | ||
53 | } else if (st4 == NULL || st->goods[type].rating >= best_rating4) { | ||
54 | st6 = st5; best_rating6 = best_rating5; | ||
55 | st5 = st4; best_rating5 = best_rating4; | ||
56 | st4 = st; best_rating4 = st->goods[type].rating; | ||
57 | } else if (st5 == NULL || st->goods[type].rating >= best_rating5) { | ||
58 | st6 = st5; best_rating6 = best_rating5; | ||
59 | st5 = st; best_rating5 = st->goods[type].rating; | ||
60 | } else if (st6 == NULL || st->goods[type].rating >= best_rating6) { | ||
61 | st6 = st; best_rating6 = st->goods[type].rating; | ||
45 | } | 62 | } |
46 | } | 63 | } |
47 | 64 | … | … |
68 | * this calculation. In reality that will mean the bonus will be pretty low. | 85 | * this calculation. In reality that will mean the bonus will be pretty low. |
69 | * Nevertheless, the best station should always get the most cargo regardless | 86 | * Nevertheless, the best station should always get the most cargo regardless |
70 | * of rounding issues. */ | 87 | * of rounding issues. */ |
71 | uint worst_cargo = amount * best_rating2 / (best_rating1 + best_rating2); | 88 | uint cargo_st2 = amount * best_rating2 / (best_rating1 + best_rating2); |
72 | assert(worst_cargo <= (amount - worst_cargo)); | 89 | assert(cargo_st2 <= (amount - cargo_st2)); |
73 | 90 | ||
74 | /* And then send the cargo to the stations! */ | 91 | uint cargo_st1 = amount - cargo_st2; |
75 | uint moved = UpdateStationWaiting(st1, type, amount - worst_cargo, source_type, source_id); | 92 | assert(amount = cargo_st1 + cargo_st2); |
93 | |||
94 | /* And then send the cargo to the stations! */ | ||
95 | uint moved = UpdateStationWaiting(st1, type, cargo_st1, source_type, source_id); | ||
76 | /* These two UpdateStationWaiting's can't be in the statement as then the order | 96 | /* These two UpdateStationWaiting's can't be in the statement as then the order |
77 | * of execution would be undefined and that could cause desyncs with callbacks. */ | 97 | * of execution would be undefined and that could cause desyncs with callbacks. */ |
78 | return moved + UpdateStationWaiting(st2, type, worst_cargo, source_type, source_id); | 98 | return moved + UpdateStationWaiting(st2, type, cargo_st2, source_type, source_id); |
79 | } | 99 | } |
80 | 100 | ||
81 | /* three stations around, the best three (highest rating) are in st1, st2 and st3 */ | 101 | if (st4 == NULL) { |
102 | /* three stations around, the best three (highest rating) are in st1, st2 and st3 */ | ||
103 | assert(st1 != NULL); | ||
104 | assert(st2 != NULL); | ||
105 | assert(st3 != NULL); | ||
106 | assert(best_rating1 != 0 || best_rating2 != 0 || best_rating3 != 0); | ||
107 | |||
108 | /* Then determine the amount the worst stations get. We do it this way as the | ||
109 | * best should get a bonus, which in this case is the rounding difference from | ||
110 | * this calculation. In reality that will mean the bonus will be pretty low. | ||
111 | * Nevertheless, the best station should always get the most cargo regardless | ||
112 | * of rounding issues. */ | ||
113 | uint cargo_st3 = amount * best_rating3 / (best_rating1 + best_rating2 + best_rating3); | ||
114 | assert(cargo_st3 <= (amount - cargo_st3)); | ||
115 | |||
116 | uint remaining = amount - cargo_st3; | ||
117 | uint cargo_st2 = remaining * best_rating2 / (best_rating1 + best_rating2); | ||
118 | assert(cargo_st2 <= (remaining - cargo_st2)); | ||
119 | |||
120 | uint cargo_st1 = remaining - cargo_st2; | ||
121 | assert(amount == cargo_st1 + cargo_st2 + cargo_st3); | ||
122 | |||
123 | /* And then send the cargo to the stations! */ | ||
124 | uint moved = UpdateStationWaiting(st1, type, cargo_st1, source_type, source_id); | ||
125 | moved += UpdateStationWaiting(st2, type, cargo_st2, source_type, source_id); | ||
126 | return moved + UpdateStationWaiting(st3, type, cargo_st3, source_type, source_id); | ||
127 | } | ||
128 | |||
129 | if (st5 == NULL) { | ||
130 | /* Four stations around, the best four (highest rating) are in st1, st2, st3 and st4 */ | ||
131 | assert(st1 != NULL); | ||
132 | assert(st2 != NULL); | ||
133 | assert(st3 != NULL); | ||
134 | assert(st4 != NULL); | ||
135 | assert(best_rating1 != 0 || best_rating2 != 0 || best_rating3 != 0 || best_rating4 != 0); | ||
136 | |||
137 | /* Then determine the amount the worst stations get. We do it this way as the | ||
138 | * best should get a bonus, which in this case is the rounding difference from | ||
139 | * this calculation. In reality that will mean the bonus will be pretty low. | ||
140 | * Nevertheless, the best station should always get the most cargo regardless | ||
141 | * of rounding issues. */ | ||
142 | uint cargo_st4 = amount * best_rating4 / (best_rating1 + best_rating2 + best_rating3 + best_rating4); | ||
143 | assert(cargo_st4 <= (amount - cargo_st4)); | ||
144 | |||
145 | uint remaining = amount - cargo_st4; | ||
146 | uint cargo_st3 = remaining * best_rating3 / (best_rating1 + best_rating2 + best_rating3); | ||
147 | assert(cargo_st3 <= (remaining - cargo_st3)); | ||
148 | |||
149 | remaining -= cargo_st3; | ||
150 | uint cargo_st2 = remaining * best_rating2 / (best_rating1 + best_rating2); | ||
151 | assert(cargo_st2 <= (remaining - cargo_st2)); | ||
152 | |||
153 | uint cargo_st1 = remaining - cargo_st2; | ||
154 | assert(amount == cargo_st1 + cargo_st2 + cargo_st3 + cargo_st4); | ||
155 | |||
156 | /* And then send the cargo to the stations! */ | ||
157 | uint moved = UpdateStationWaiting(st1, type, cargo_st1, source_type, source_id); | ||
158 | moved += UpdateStationWaiting(st2, type, cargo_st2, source_type, source_id); | ||
159 | moved += UpdateStationWaiting(st3, type, cargo_st3, source_type, source_id); | ||
160 | return moved + UpdateStationWaiting(st4, type, cargo_st4, source_type, source_id); | ||
161 | } | ||
162 | |||
163 | if (st6 == NULL) { | ||
164 | /* Five stations around, the best five (highest rating) are in st1, st2, st3, st4 and st5 */ | ||
165 | assert(st1 != NULL); | ||
166 | assert(st2 != NULL); | ||
167 | assert(st3 != NULL); | ||
168 | assert(st4 != NULL); | ||
169 | assert(st5 != NULL); | ||
170 | assert(best_rating1 != 0 || best_rating2 != 0 || best_rating3 != 0 || best_rating4 != 0 || best_rating5 != 0); | ||
171 | |||
172 | /* Then determine the amount the worst stations get. We do it this way as the | ||
173 | * best should get a bonus, which in this case is the rounding difference from | ||
174 | * this calculation. In reality that will mean the bonus will be pretty low. | ||
175 | * Nevertheless, the best station should always get the most cargo regardless | ||
176 | * of rounding issues. */ | ||
177 | uint cargo_st5 = amount * best_rating5 / (best_rating1 + best_rating2 + best_rating3 + best_rating4 + best_rating5); | ||
178 | assert(cargo_st5 <= (amount - cargo_st5)); | ||
179 | |||
180 | uint remaining = amount - cargo_st5; | ||
181 | uint cargo_st4 = remaining * best_rating4 / (best_rating1 + best_rating2 + best_rating3 + best_rating4); | ||
182 | assert(cargo_st4 <= (remaining - cargo_st4)); | ||
183 | |||
184 | remaining -= cargo_st4; | ||
185 | uint cargo_st3 = remaining * best_rating3 / (best_rating1 + best_rating2 + best_rating3); | ||
186 | assert(cargo_st3 <= (remaining - cargo_st3)); | ||
187 | |||
188 | remaining -= cargo_st3; | ||
189 | uint cargo_st2 = remaining * best_rating2 / (best_rating1 + best_rating2); | ||
190 | assert(cargo_st2 <= (remaining - cargo_st2)); | ||
191 | |||
192 | uint cargo_st1 = remaining - cargo_st2; | ||
193 | assert(amount == cargo_st1 + cargo_st2 + cargo_st3 + cargo_st4 + cargo_st5); | ||
194 | |||
195 | /* And then send the cargo to the stations! */ | ||
196 | uint moved = UpdateStationWaiting(st1, type, cargo_st1, source_type, source_id); | ||
197 | moved += UpdateStationWaiting(st2, type, cargo_st2, source_type, source_id); | ||
198 | moved += UpdateStationWaiting(st3, type, cargo_st3, source_type, source_id); | ||
199 | moved += UpdateStationWaiting(st4, type, cargo_st4, source_type, source_id); | ||
200 | return moved + UpdateStationWaiting(st5, type, cargo_st5, source_type, source_id); | ||
201 | } | ||
202 | |||
203 | /* Six stations around, the best six (highest rating) are in st1, st2, st3, st4, st5 and st6 */ | ||
82 | assert(st1 != NULL); | 204 | assert(st1 != NULL); |
83 | assert(st2 != NULL); | 205 | assert(st2 != NULL); |
84 | assert(st3 != NULL); | 206 | assert(st3 != NULL); |
85 | assert(best_rating1 != 0 || best_rating2 != 0 || best_rating3 !=0); | 207 | assert(st4 != NULL); |
86 | 208 | assert(st5 != NULL); | |
87 | /* Then determine the amount the worst station gets. We do it this way as the | 209 | assert(st6 != NULL); |
210 | assert(best_rating1 != 0 || best_rating2 != 0 || best_rating3 != 0 || best_rating4 != 0 || best_rating5 != 0 || best_rating6 != 0); | ||
211 | |||
212 | /* Then determine the amount the worst stations get. We do it this way as the | ||
88 | * best should get a bonus, which in this case is the rounding difference from | 213 | * best should get a bonus, which in this case is the rounding difference from |
89 | * this calculation. In reality that will mean the bonus will be pretty low. | 214 | * this calculation. In reality that will mean the bonus will be pretty low. |
90 | * Nevertheless, the best station should always get the most cargo regardless | 215 | * Nevertheless, the best station should always get the most cargo regardless |
91 | * of rounding issues. */ | 216 | * of rounding issues. */ |
92 | uint worst_cargo_st3 = amount * best_rating3 / (best_rating1 + best_rating2 + best_rating3); | 217 | uint cargo_st6 = amount * best_rating6 / (best_rating1 + best_rating2 + best_rating3 + best_rating4 + best_rating5 + best_rating6); |
93 | assert(worst_cargo_st3 <= (amount - worst_cargo_st3)); | 218 | assert(cargo_st6 <= (amount - cargo_st6)); |
94 | 219 | ||
95 | uint remaining_amount = amount - worst_cargo_st3; | 220 | uint remaining = amount - cargo_st6; |
96 | uint worst_cargo_st2 = remaining_amount * best_rating2 / (best_rating1 + best_rating2); | 221 | uint cargo_st5 = remaining * best_rating5 / (best_rating1 + best_rating2 + best_rating3 + best_rating4 + best_rating5); |
97 | assert(worst_cargo_st2 <= (remaining_amount - worst_cargo_st2)); | 222 | assert(cargo_st5 <= (remaining - cargo_st5)); |
223 | |||
224 | remaining -= cargo_st5; | ||
225 | uint cargo_st4 = remaining * best_rating4 / (best_rating1 + best_rating2 + best_rating3 + best_rating4); | ||
226 | assert(cargo_st4 <= (remaining - cargo_st4)); | ||
227 | |||
228 | remaining -= cargo_st4; | ||
229 | uint cargo_st3 = remaining * best_rating3 / (best_rating1 + best_rating2 + best_rating3); | ||
230 | assert(cargo_st3 <= (remaining - cargo_st3)); | ||
231 | |||
232 | remaining -= cargo_st3; | ||
233 | uint cargo_st2 = remaining * best_rating2 / (best_rating1 + best_rating2); | ||
234 | assert(cargo_st2 <= (remaining - cargo_st2)); | ||
235 | |||
236 | uint cargo_st1 = remaining - cargo_st2; | ||
237 | assert(amount == cargo_st1 + cargo_st2 + cargo_st3 + cargo_st4 + cargo_st5 + cargo_st6); | ||
98 | 238 | ||
99 | /* And then send the cargo to the stations! */ | 239 | /* And then send the cargo to the stations! */ |
100 | uint moved = UpdateStationWaiting(st1, type, remaining_amount - worst_cargo_st2, source_type, source_id); | 240 | uint moved = UpdateStationWaiting(st1, type, cargo_st1, source_type, source_id); |
101 | /* HALP - I GOT 3 UpdateStationWaitings now! */ | 241 | moved += UpdateStationWaiting(st2, type, cargo_st2, source_type, source_id); |
102 | moved += UpdateStationWaiting(st2, type, worst_cargo_st2, source_type, source_id); | 242 | moved += UpdateStationWaiting(st3, type, cargo_st3, source_type, source_id); |
103 | return moved + UpdateStationWaiting(st3, type, worst_cargo_st3, source_type, source_id); | 243 | moved += UpdateStationWaiting(st4, type, cargo_st4, source_type, source_id); |
244 | moved += UpdateStationWaiting(st5, type, cargo_st5, source_type, source_id); | ||
245 | return moved + UpdateStationWaiting(st6, type, cargo_st6, source_type, source_id); | ||
104 | } | 246 | } |