31 explicit Game(std::string_view filename);
72 void ParseRule(std::size_t x, std::size_t y,
RuleDirection direction);
80 bool CanMove(std::size_t x, std::size_t y,
Direction dir,
81 const std::vector<ObjectID>& movingIDs = {});
90 std::vector<ObjectID> GetPlayerIDsAt(
const Position& position)
const;
96 void ProcessPlayerStack(
const Position& position,
97 const std::vector<ObjectID>& playerIDs,
101 void ProcessMoveProperty();
116 std::size_t attempts = 0;
129 void AddMoveRuleAttempts(
const Rule& rule, std::vector<MoveState>& moving,
130 std::size_t& rounds);
137 void AppendMatchingMoveObjects(
const Rule& rule,
138 const std::vector<ObjectType>& subjects,
140 std::vector<ObjectID>& matching)
const;
147 void RegisterEmptyMoveAttemptAt(
const Rule& rule,
const Position& position,
148 std::vector<MoveState>& moving,
149 std::size_t& rounds);
157 static void RegisterMoveAttempt(std::vector<MoveState>& moving,
ObjectID id,
159 Direction direction, std::size_t& rounds);
164 void ProcessMoveRound(std::vector<MoveState>& moving, std::size_t round);
169 void ProcessEmptyMoveState(std::vector<MoveState>& moving,
175 static void MergeEmptyMoveStates(std::vector<MoveState>& moving,
180 void ProcessObjectMoveState(MoveState& state);
183 void ProcessDirectionProperties();
189 void ApplyDirectionProperties(ObjectInstance& instance,
191 const std::vector<Rule>& rules)
const;
195 ObjectInstance EmptyAt(
const Position& position)
const;
198 void ProcessTransformations();
201 struct Transformation
210 std::vector<RuleCondition> conditions;
214 struct TransformationResult
217 bool matched =
false;
220 bool transforms =
false;
223 bool expandsAll =
false;
226 bool protectedByIdentity =
false;
229 std::vector<ObjectType> targets;
232 std::vector<ObjectType> allTargets;
236 struct LocatedInstance
239 ObjectInstance instance;
246 struct EmptyTransformation
255 TransformationResult result;
260 std::vector<Transformation> FindTransformations()
const;
266 void AppendSubjectTransformations(
268 std::vector<Transformation>& transformations)
const;
274 TransformationResult ResolveTransformation(
275 const LocatedInstance& source,
276 const std::vector<Transformation>& transformations)
const;
280 void AppendAllTargets(TransformationResult& result)
const;
292 void CollectTransformationSnapshot(std::vector<LocatedInstance>& instances,
293 std::vector<Position>& emptyTiles)
const;
298 void AppendTransformationInstancesAt(
300 std::vector<LocatedInstance>& instances)
const;
305 void ApplyTransformation(
const LocatedInstance& source,
306 const TransformationResult& result);
314 const std::vector<ObjectType>& targets);
318 void ApplyEmptyTransformation(
const EmptyTransformation& pending);
321 void UpdateAllNouns();
328 bool HasPropertyAtPosition(
const ObjectInstance& instance,
337 bool HasPropertyAt(std::size_t x, std::size_t y,
ObjectType property)
const;
345 bool MatchesConditionsAt(
346 const ObjectInstance& instance,
const Position& position,
347 const std::vector<RuleCondition>& conditions)
const;
355 bool MatchesConditionAt(
const ObjectInstance& instance,
357 const RuleCondition& condition)
const;
360 struct OpenShutInteraction
363 std::vector<ObjectID> matchedIDs;
365 std::vector<ObjectID> destroyedIDs;
373 OpenShutInteraction GetOpenShutInteraction(
374 const Position& source,
const std::vector<ObjectID>& movingIDs,
380 std::vector<ObjectID> DestroyOpenShutObjects(
381 const std::vector<ObjectID>& ids);
388 void ProcessMove(std::size_t x, std::size_t y,
Direction dir,
389 const std::vector<ObjectID>& ids);
396 void ProcessPush(std::size_t x, std::size_t y,
Direction dir,
397 const std::vector<ObjectID>& ids);
400 void ProcessOpenShut();
409 void ProcessHotMelt();
412 void ProcessDefeat();
415 void CheckPlayState();
418 RuleManager m_ruleManager;
421 ObjectType m_playerIcon = ObjectType::ICON_EMPTY;
423 std::vector<ObjectType> m_playerIcons;
424 std::vector<ObjectType> m_allNouns;
425 std::vector<ObjectID> m_movementGeneratedIDs;
426 std::mt19937 m_randomEngine{ std::random_device{}() };