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 Structure
s 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 Structure
s, a Blueprint
now also keeps track of the total occupied space and which of the Structure
s 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 Furnace
s and nicer Structure
coloring, the game now looks like this: