// The alliance / shared-vision mask -- the spine's fourth phase. // // Early in every strategic turn, before anything else in the turn can read it, the driver // walks the server's player vector and rebuilds one word on each player's turn record from // scratch. The word is a bitmask of "whose vision this player shares this turn": the player's // own bit, plus every member of the player's alliance when it is in one. // // Two things about it are worth stating in the header because both are places a // reimplementation goes quietly wrong. // // 1. The bit is the player's POSITION IN THE PLAYER VECTOR, not the player's own index // field. Every other per-player index in the tail -- the turn-results array, the battle // tally, the archive key -- uses the index field, and this one does not. The shift count // in the original is the loop induction variable; the index field is never loaded in this // phase. // 2. The mask is rebuilt, not accumulated. The word is cleared first, so nothing survives // from the previous turn. // // The word is not itself a save leaf. It reaches the wire only because the last phase of the // post-combat tail copies the whole turn record into the per-turn statistics archive, which // IS on the wire -- so this phase is checkable against bytes the original wrote. #pragma once #include #include #include #include "mars/stream/shapes.h" namespace sots::app { // The value the original uses for "this player is in no alliance". constexpr std::int32_t kNoAlliance = -1; // One player's mask. `vectorIndex` is the player's position in the server's player vector. // // Above 31 players the original's shift wraps -- x86 masks a variable shift count to five // bits -- so bit (index % 32) would be set. No save in the corpus has more than eight // players and that path is untested; it is reproduced rather than "fixed" because the point // of this file is to be the original, not to be correct. std::int32_t AllianceMask(const mars::stream::shapes::Player& p, std::size_t vectorIndex); // The whole phase: every player's mask, in vector order. std::vector RebuildAllianceMasks( const std::vector& players); } // namespace sots::app