Loading

Revision differences

Old revision #pfsmdufv4New 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            st3 = st2;  31            st6 = st5; best_rating6 = best_rating5;
32            best_rating3 = best_rating2;  32            st5 = st4; best_rating5 = best_rating4;
33            st2 = st1;  33            st4 = st3; best_rating4 = best_rating3;
34            best_rating2 = best_rating1;  34            st3 = st2; best_rating3 = best_rating2;
35            st1 = st;  35            st2 = st1; best_rating2 = best_rating1;
36            best_rating1 = st->goods[type].rating;  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}