Eleven methods maintained m_tileOccupancy by hand — place, deconstruct, removeBuilding, placeImmediate, tickDeconstruction, findRotateInPlaceTarget and tryDirectCoupleDeposit all indexed a raw std::map<std::pair<int,int>, BuildingId> directly, so the invariant "occupancy stays in sync with placement" was re-implemented at every call site. They now ask and tell a small owned index instead: occupy / release / isOccupied / findOwner. BuildingGrid is a member of BuildingSystem, not a peer system: it has no per-tick behaviour and nothing outside BuildingSystem touches it. The internal keying stays std::pair<int,int> rather than moving to QPoint. The checksum folds the entries in map iteration order, so the comparator is part of the determinism contract; changing it is a separate decision, not a side effect of this move. Verified with a golden-checksum capture before and after — all four sample ticks identical. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YHcUerKAZKWNvSKJxYKbnG
53 lines
1.2 KiB
C++
53 lines
1.2 KiB
C++
#include "BuildingGrid.h"
|
|
|
|
#include "StateChecksum.h"
|
|
|
|
void BuildingGrid::occupy(QPoint cell, BuildingId id)
|
|
{
|
|
m_owners[{cell.x(), cell.y()}] = id;
|
|
}
|
|
|
|
void BuildingGrid::occupy(const std::vector<QPoint>& cells, BuildingId id)
|
|
{
|
|
for (const QPoint& cell : cells)
|
|
{
|
|
occupy(cell, id);
|
|
}
|
|
}
|
|
|
|
void BuildingGrid::release(const std::vector<QPoint>& cells)
|
|
{
|
|
for (const QPoint& cell : cells)
|
|
{
|
|
m_owners.erase({cell.x(), cell.y()});
|
|
}
|
|
}
|
|
|
|
bool BuildingGrid::isOccupied(QPoint tile) const
|
|
{
|
|
return m_owners.count({tile.x(), tile.y()}) > 0;
|
|
}
|
|
|
|
std::optional<BuildingId> BuildingGrid::findOwner(QPoint tile) const
|
|
{
|
|
const std::map<std::pair<int, int>, BuildingId>::const_iterator it =
|
|
m_owners.find({tile.x(), tile.y()});
|
|
if (it == m_owners.end())
|
|
{
|
|
return std::nullopt;
|
|
}
|
|
return it->second;
|
|
}
|
|
|
|
void BuildingGrid::appendChecksum(Hasher& hasher) const
|
|
{
|
|
// std::map iterates in sorted key order.
|
|
hasher.append(m_owners.size());
|
|
for (const std::pair<const std::pair<int, int>, BuildingId>& entry : m_owners)
|
|
{
|
|
hasher.append(entry.first.first);
|
|
hasher.append(entry.first.second);
|
|
hasher.append(entry.second);
|
|
}
|
|
}
|