Structures of individual Sizes

<
>
December 26, 2020

Up until now every Structure had a size of 1x1, but that’s rather limiting from a gameplay perspective.
That’s why I added individual sizes for the different Structure types.

pub fn size(&self) -> [u8; 2] {
    match self {
        Self::Belt(_) | Self::Arm(_) | Self::LongArm(_) | Self::Source(_) | Self::Target(_) => {
            [1, 1]
        }
        Self::Furnace(_) => [2, 2],
        Self::Module(x) => x.size(),
    }
}

Since Structures now have individual sizes, it’s also necessary to keep track of the occupied space when trying to add or remove a Structure from a Blueprint.
Instead of just keeping track of the Structures, a Blueprint now also keeps track of the total occupied space and which of the Structures it belongs to.
For interactions during the simulation it’s also important which of the positons is the ‘anchor’ of a Structure:

pub struct Blueprint {
    structures: HashMap<StructureID, Structure>,
    positions: HashMap<Pos, (IsAnchorPoint, StructureID)>,
    ...
}

When trying to place a new Structure it can now be checked that none of its space is already occupied:

impl Blueprint {
...
    pub fn add(&mut self, pos: Pos, structure: Structure) -> bool {
        let [w, h] = structure.size();
        for offset_x in 0..w {
            for offset_y in 0..h {
                let pos = Pos {
                    row: pos.row as u8 + offset_y,
                    col: pos.col as u8 + offset_x,
                };
                if ... || self.positions.contains_key(&pos)
                {
                    return false;
                }
            }
        }
...

With the larger Furnaces and nicer Structure coloring, the game now looks like this: