MailRuChamps / miniaicups

Правила, исходники и прочее для aicups.ru
GNU General Public License v3.0
157 stars 139 forks source link

Очерёдность сплита требуется пересмотреть #92

Closed DragoonXen closed 6 years ago

DragoonXen commented 6 years ago

split приводит к большему числу кусков, чем позволено в настройках

http://aicups.ru/session/86875/

тик 2031 +

в игре параметр MAX_FRAGS_CNT=4

tongohiti commented 6 years ago

Рискну предположить, что ноги растут вот откуда.

Код, который исполняется в локал-раннере (работает правильно!):

    void apply_strategies() {
        for (Strategy *strategy : strategy_array) {
            int sId = strategy->getId();
            PlayerArray fragments = get_players_by_id(sId);
            CircleArray visibles = get_visibles(fragments);

            Direct direct = strategy->tickEvent(fragments, visibles);
//            logger->write_direct(tick, sId, direct);

            int yet_cnt = fragments.length();
            for (Player *frag : fragments) {
                frag->apply_direct(direct, Constants::instance().GAME_WIDTH, Constants::instance().GAME_HEIGHT);
                logger->write_direct_for(tick, frag);

                if (direct.split && frag->can_split(yet_cnt)) {
                    frag->logical = Player::SPLIT;
                    yet_cnt++;
                }
                if (direct.eject && frag->can_eject()) {
                    frag->logical = Player::EJECT;
                }
            }
        }
    }

Код, который исполняется на сервере (баг!):

    void apply_direct_for(int sId, Direct direct) {
//        logger->write_direct(tick, sId, direct);
        PlayerArray fragments = get_players_by_id(sId);
        int yet_cnt = fragments.length();

        for (Player *frag : fragments) {
            frag->apply_direct(direct, Constants::instance().GAME_WIDTH, Constants::instance().GAME_HEIGHT);
            logger->write_direct_for(tick, frag);

            if (direct.split && frag->can_split(yet_cnt)) {
                frag->logical = Player::SPLIT;
            }
            if (direct.eject && frag->can_eject()) {
                frag->logical = Player::EJECT;
            }
        }
    }

Разница в том, что во втором случае забыли yet_cnt++ после присвоения frag->logical = Player::SPLIT;. Это всё в mechanic.h

PS Копипаста - зло!

alex3d commented 6 years ago

Кстати в процессе выпиливания стейтов этот баг был пофикшен

DragoonXen commented 6 years ago

В таком случае осталось только рассмотреть очерёдность сплита. Насколько помню из общения в чате - в первую очередь сплитим самые массивные куски