ZeusWPI / MOZAIC

MOZAIC is the Massive Online Zeus Artificial Intelligence Competition platform
GNU Lesser General Public License v3.0
13 stars 6 forks source link

Gamerules panicking in step_expeditions #125

Closed wschella closed 6 years ago

wschella commented 7 years ago

I couldn't immediately find the problem, so i'm pasting relevant details here so I can go on with my work. The only thing that makes sense is us not cleaning up old expeditions or something (it's the only subtraction going on) This happens after the bots made their first move, map is standard hex:

Player 1:

{"moves": [{"origin":"protos","destination":"duteros","ship_count":4}, {"origin":"protos","destination":"extos","ship_count":4}, {"origin":"protos","destination":"tritos","ship_count":3}, {"origin":"protos","destination":"pemptos","ship_count":3}, {"origin":"protos","destination":"protos","ship_count":2}]}

Player 2:

{"moves": [{"origin":"tetartos","destination":"tritos","ship_count":4}, {"origin":"tetartos","destination":"pemptos","ship_count":4}, {"origin":"tetartos","destination":"extos","ship_count":3}, {"origin":"tetartos","destination":"duteros","ship_count":3}, {"origin":"tetartos","destination":"tetartos","ship_count":2}]}

Stacktrace:

thread 'main' panicked at 'attempt to subtract with overflow', src/games/planetwars/planet_wars.rs:227
stack backtrace:
   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
             at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::_print
             at /checkout/src/libstd/sys_common/backtrace.rs:71
   2: std::panicking::default_hook::{{closure}}
             at /checkout/src/libstd/sys_common/backtrace.rs:60
             at /checkout/src/libstd/panicking.rs:355
   3: std::panicking::default_hook
             at /checkout/src/libstd/panicking.rs:371
   4: std::panicking::rust_panic_with_hook
             at /checkout/src/libstd/panicking.rs:549
   5: std::panicking::begin_panic
             at /checkout/src/libstd/panicking.rs:511
   6: std::panicking::begin_panic_fmt
             at /checkout/src/libstd/panicking.rs:495
   7: rust_begin_unwind
             at /checkout/src/libstd/panicking.rs:471
   8: core::panicking::panic_fmt
             at /checkout/src/libcore/panicking.rs:69
   9: core::panicking::panic
             at /checkout/src/libcore/panicking.rs:49
  10: mozaic_bot_driver::games::planetwars::planet_wars::PlanetWars::step_expeditions
             at /mnt/d/Workspace/Zeus/MOZAIC/src/botdriver/src/games/planetwars/planet_wars.rs:227
  11: <mozaic_bot_driver::games::planetwars::planet_wars::PlanetWars as mozaic_bot_driver::game::Game>::step
             at /mnt/d/Workspace/Zeus/MOZAIC/src/botdriver/src/games/planetwars/planet_wars.rs:111
  12: mozaic_bot_driver::match_runner::MatchRunner::run
             at /mnt/d/Workspace/Zeus/MOZAIC/src/botdriver/src/match_runner.rs:28
  13: mozaic_bot_driver::main
             at /mnt/d/Workspace/Zeus/MOZAIC/src/botdriver/src/main.rs:64
  14: __rust_maybe_catch_panic
             at /checkout/src/libpanic_unwind/lib.rs:98
  15: std::rt::lang_start
             at /checkout/src/libstd/panicking.rs:433
             at /checkout/src/libstd/panic.rs:361
             at /checkout/src/libstd/rt.rs:57
  16: main
  17: __libc_start_main
  18: _start

Relevant code:

 fn step_expeditions(&mut self) {
        let mut i = 0;
        let exps = &mut self.expeditions;
        while i < exps.len() {
            // compare with 1 to avoid issues with planet distance 0
            if exps[i].turns_remaining <= 1 {
                // remove expedition from expeditions, and add to fleet
                let exp = exps.swap_remove(i);
                let planet = self.planets.get_mut(&exp.target).unwrap();
                planet.orbit(exp.fleet);
            } else {
                exps[i].turns_remaining -= 1;
                if let Some(owner) = exps[i].fleet.owner {
                    // owner has an expedition in progress; this is a sign of life.
                    self.players.get_mut(&owner).unwrap().alive = true;
                }

                // proceed to next expedition
                i += 1;
            }
        }
    }
iasoon commented 7 years ago

I tried my best reproducing this on 32086cf by playing the initial moves as described, but the expeditions get dispatched as expected. Are you certain the information you provided is correct?

wschella commented 7 years ago

It's not wrong, but maybe incomplete. Just realized the moves that effectively crashed the gamerules might not have been logged in the bot nor in the gamerules

iasoon commented 7 years ago

Yes, that will probably be the case. I am quite puzzled by how this issue can happen though, since according to that if statement, which is called on every element as far as I can see, should make sure that turns_remaining > 1.

wschella commented 7 years ago

Unrelated to the bug, but don't we want to preserve the order of the expeditions as commanded by the players? People might expect us to do that so that they don't have to filter their own expeditions when they send too much troops, but their priorities are correct.

The .swap_remove kinda removes this ordering.

iasoon commented 7 years ago

@wschella We do keep the order of expeditions as commanded by the player in dispatching, which is unrelated to this code. The only way the ordering you refer to here gets to the players is through the list of expeditions we provide to them, but that shouldn't matter since the expeditions all have an id.

wschella commented 7 years ago

Right!

iasoon commented 6 years ago

Since many games have been played since, and this was never observed again, I'd suggest this was due to a glitch in the matrix.