Double Removal Bug

I just started working on a new rust algo for Season 3 and it is crashing because of a bugged game state.

A panic is raised due to a double remove as it is parsing the frame (this is stock starter kit code). Sure enough, the frame in question has my opponent doing a double removal at [13, 11] -

“p1Units”: [[[14, 12, 60, “62”], [24, 12, 60, “64”], [19, 12, 60, “66”], [27, 13, 60, “70”], [25, 11, 60, “72”], [26, 12, 60, “74”], [23, 11, 60, “76”], [6, 11, 42, “78”], [20, 11, 60, “80”], [0, 13, 60, “82”], [15, 11, 60, “98”], [18, 11, 60, “100”], [13, 11, 14, “112”], [21, 11, 60, “116”], [22, 11, 60, “118”], [17, 11, 60, “120”], [16, 11, 60, “135”], [8, 11, 34, “141”], [7, 11, 38, “143”], [26, 13, 60, “157”], [1, 13, 60, “171”], [3, 12, 54, “185”], [4, 13, 60, “305”], [11, 11, 60, “350”], [10, 11, 60, “352”], [12, 11, 60, “354”]], [[23, 9, 30, “169”], [22, 9, 30, “183”], [5, 9, 30, “216”], [5, 8, 30, “265”], [6, 8, 30, “317”]], [[3, 11, 75, “88”], [24, 11, 75, “90”], [14, 11, 69, “92”], [19, 11, 75, “96”], [5, 11, 63, “155”], [25, 12, 75, “189”], [2, 12, 75, “208”], [1, 12, 75, “210”], [2, 11, 75, “247”], [9, 11, 37, “253”], [3, 10, 75, “273”], [4, 9, 75, “285”], [21, 9, 75, “303”]], [], [], [], [[9, 11, 0, “346”], [13, 11, 0, “347”], [13, 11, 0, “348”]]],

Here’s the replay: https://terminal.c1games.com/watch/4164700

Shouldn’t the engine have forbidden my opponent from generating this game state?

I agree that the engine should be preventing that sort of game state. Adding this to the backlog with a fairly low priority, it should be fixed in coming weeks.

Ok, thanks @RegularRyan.

In the meantime here’s a defensive coding fix for any other rust devs out there:

OLD CODE:

// fill in the remove units
for unit_data in units.remove() {
    let slot: &mut Option<Unit<RemoveUnitType>> = remove.get_mut(unit_data.coords())
        .ok_or(MapParseError::UnitInIllegalPosition(unit_data.coords()))?;
    if slot.is_some() {
        return Err(MapParseError::MultipleRemovesSamePosition(unit_data.coords()));
    }
    *slot = Some(Unit {
        unit_type: RemoveUnitType,
        stability: unit_data.stability(),
        id: Some(unit_data.unit_id().clone()),
        owner: player
    });
}

NEW CODE:

// fill in the remove units
for unit_data in units.remove() {
    let slot: &mut Option<Unit<RemoveUnitType>> = remove.get_mut(unit_data.coords())
        .ok_or(MapParseError::UnitInIllegalPosition(unit_data.coords()))?;
    if !slot.is_some() {
        *slot = Some(Unit {
            unit_type: RemoveUnitType,
            stability: unit_data.stability(),
            id: Some(unit_data.unit_id().clone()),
            owner: player
        });
    }
}
1 Like