ypopezios has proposed merging lp:~widelands-dev/widelands/ship_scheduling_2
into lp:widelands.
Commit message:
Get windows builds and ask for testing.
Requested reviews:
Widelands Developers (widelands-dev)
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/ship_scheduling_2/+merge/352335
See description of the branch:
https://code.launchpad.net/~widelands-dev/widelands/ship_scheduling_2
--
Your team Widelands Developers is requested to review the proposed merge of
lp:~widelands-dev/widelands/ship_scheduling_2 into lp:widelands.
=== modified file 'src/economy/fleet.cc'
--- src/economy/fleet.cc 2018-04-07 16:59:00 +
+++ src/economy/fleet.cc 2018-08-04 06:22:49 +
@@ -637,9 +637,9 @@
act_pending_ = false;
if (!active()) {
- // If we are here, most likely act() was called by a port with waiting wares or an expedition
- // ready
- // although there are still no ships. We can't handle it now, so we reschedule the act()
+ // If we are here, most likely act() was called by a port with waiting wares or
+ // with an expedition ready, although there are still no ships.
+ // We can't handle it now, so we reschedule the act()
schedule_act(game, 5000); // retry in the next time
act_pending_ = true;
return;
@@ -647,212 +647,95 @@
molog("Fleet::act\n");
- // we need to calculate what ship is to be send to which port
- // for this we will have temporary data structure with format
- // <,score>
- // where ship and port are not objects but positions in ports_ and ships_
- // this is to allow native hashing
- std::map, uint16_t> scores;
-
- // so we will identify all pairs: idle ship : ports, and score all such
- // pairs. We consider
- // - count of wares onboard, first ware (oldest) is counted as 8 (prioritization)
- // (counting wares for particular port only)
- // - count wares waiting at the port/3
- // - distance between ship and a port (0-10 points, the closer the more points)
- // - is another ship heading there right now?
-
- // at the end we must know if requrests of all ports asking for ship were addressed
- // if any unsatisfied, we must schedule new run of this function
- // when we send a ship there, the port is removed from list
+ // We need to calculate what ship is to be sent to which port,
+ // so we will score all pairs: idle ship : port.
+ // For the score of each pair, we consider:
+ // - count of wares onboard that ship for that port
+ // - count of wares waiting at that port
+ // - distance between that ship and that port
+
+ // At the end we must know if the request of any port for a ship
+ // is still unsatisfied, to schedule new run of this function.
+ // This list holds all waiting ports and we remove every port where we send a ship.
std::list waiting_ports;
-
- // this is just helper - first member of scores map
- std::pair mapping; // ship number, port number
-
- // first we go over ships - idle ones (=without destination)
- // then over wares on these ships and create first ship-port
- // pairs with score
- for (uint16_t s = 0; s < ships_.size(); s += 1) {
- if (ships_[s]->get_destination(game)) {
- continue;
- }
- if (ships_[s]->get_ship_state() != Ship::ShipStates::kTransport) {
+ for (uint16_t pi = 0; pi < ports_.size(); ++pi) {
+ if (ports_[pi]->get_need_ship()) {
+ waiting_ports.push_back(pi);
+ }
+ }
+
+ for (Ship* s : ships_) {
+ if (s->get_destination(game)) {
+ continue; // has already destination
+ }
+ if (s->get_ship_state() != Ship::ShipStates::kTransport) {
continue; // in expedition obviously
}
-
- for (uint16_t i = 0; i < ships_[s]->get_nritems(); i += 1) {
- PortDock* dst = ships_[s]->items_[i].get_destination(game);
- if (!dst) {
-// if wares without destination on ship without destination
-// such ship can be send to any port, and should be sent
-// to some port, so we add 1 point to score for each port
-for (uint16_t p = 0; p < ports_.size(); p += 1) {
- mapping.first = s;
- mapping.second = p;
- scores[mapping] += 1;
-}
-continue;
- }
-
- bool destination_found = false; // Just a functional check
- for (uint16_t p = 0; p < ports_.size(); p += 1) {
-if (ports_[p] == ships_[s]->items_[i].get_destination(game)) {
- mapping.first = s;
- mapping.second = p;
- scores[mapping] += (i == 0) ? 8 : 1;
- destination_found = true;
-}
- }
- if (!destination_found) {
-// Perhaps the throw here is too strong
-// we can still remove it before stable release if it proves too much
-// during my testing this situation never happened
-throw wexception("A ware with destination that does not match any of player's"
- " ports, ship %u, ware's destination: %u",
- ships_[s]->serial(),
- ships_[s]->items_[i].get_destination(game)->serial());
- }
- }
- }
-
- // now opposite aproach - we go over ports to find out those that have wares
- // waiting for ship