Compare commits

...
Author SHA1 Message Date
admin b404024128 Look up fleeing units by id 2026-06-25 07:55:03 -07:00
4 changed files with 55 additions and 2 deletions
@@ -14,6 +14,7 @@
#include "src/main/cpp/net/eagle0/shardok/library/util/ActionResultFlatbufferHelpers.hpp"
namespace shardok {
auto BecomeOutlawCommand::InternalExecute(
const GameStateW& currentState,
const std::shared_ptr<RandomGenerator>& generator) const -> vector<ActionResult> {
@@ -28,7 +29,9 @@ auto BecomeOutlawCommand::InternalExecute(
result.mutable_player()->set_value(GetPlayerId());
result.mutable_actor()->set_value(fleeingUnitId);
net::eagle0::shardok::storage::ResolvedUnit* resolvedUnit = result.add_resolved_units();
AddUnitToResolved(*resolvedUnit, *currentState->units()->Get(fleeingUnitId));
AddUnitToResolved(
*resolvedUnit,
*FindUnitByIdOrThrow(*currentState->units(), fleeingUnitId, "BecomeOutlawCommand"));
if (PercentileRollSucceeds(successOdds, roll)) {
result.set_type(net::eagle0::shardok::common::ActionType::BECAME_OUTLAW);
@@ -29,7 +29,8 @@ auto FleeCommand::InternalExecute(
result.mutable_player()->set_value(GetPlayerId());
result.mutable_actor()->set_value(fleeingUnitId);
const auto* fleeingUnit = currentState->units()->Get(fleeingUnitId);
const auto* fleeingUnit =
FindUnitByIdOrThrow(*currentState->units(), fleeingUnitId, "FleeCommand");
net::eagle0::shardok::storage::ResolvedUnit* resolvedUnit = result.add_resolved_units();
AddUnitToResolved(*resolvedUnit, *fleeingUnit);
@@ -6,8 +6,10 @@
#define EAGLE0_SHARDOK_LIBRARY_UTIL_ACTION_RESULT_FLATBUFFER_HELPERS_HPP
#include <cstring>
#include <sstream>
#include <stdexcept>
#include <string>
#include <string_view>
#include <type_traits>
#include "src/main/flatbuffer/net/eagle0/shardok/storage/unit.hpp"
@@ -37,6 +39,21 @@ static_assert(std::is_trivially_copyable_v<Unit>);
return unit;
}
[[nodiscard]] static inline auto FindUnitByIdOrThrow(
const flatbuffers::Vector<const Unit*>& units,
const int unitId,
const std::string_view context) -> const Unit* {
for (size_t i = 0; i < units.size(); ++i) {
const auto* unit = units.Get(static_cast<unsigned int>(i));
if (unit->unit_id() == unitId) { return unit; }
}
std::ostringstream message;
message << context << " could not find unit_id=" << unitId << " in units vector of size "
<< units.size();
throw std::out_of_range(message.str());
}
static inline void AddChangedUnit(ActionResult& result, const Unit& unit) {
result.add_changed_units_fb(&unit, sizeof(Unit));
}
@@ -35,6 +35,22 @@ class FleeCommandTest : public ::testing::Test {
}
public:
[[nodiscard]] static auto GameStateWithSingleUnitId(const UnitId unitId) -> GameStateW {
flatbuffers::FlatBufferBuilder fbb;
fbb.ForceDefaults(true);
auto unit = AddGenericUnit(0, unitId, Coords(3, 3));
std::vector<Unit> units{unit};
auto unitsOffset = fbb.CreateVectorOfSortedStructs(&units);
GameStateBuilder gsb(fbb);
gsb.add_units(unitsOffset);
fbb.Finish(gsb.Finish());
return GameStateW(fbb);
}
const ActionCost cost = ActionCost::UsesAllActionCost(5);
const PercentileRollOdds odds = MakeOdds(80);
@@ -84,4 +100,20 @@ TEST_F(FleeCommandTest, rollOverOdds_vip_unitFlees) {
EXPECT_EQ(net::eagle0::shardok::storage::ResolvedUnit_UnitStatus_FLED_UNIT, ru.status());
}
TEST_F(FleeCommandTest, unitIdDoesNotNeedToMatchVectorIndex) {
const UnitId unitId = 6;
const auto compactGameState = GameStateWithSingleUnitId(unitId);
const auto results = FleeCommand(cost, 0, unitId, odds).ExecuteWithRoll(compactGameState, 70);
const ActionResult fleeResult = ResultWithType(results, net::eagle0::shardok::common::FLED);
EXPECT_EQ(1, fleeResult.resolved_units_size());
const net::eagle0::shardok::storage::ResolvedUnit& ru = fleeResult.resolved_units(0);
EXPECT_EQ(unitId, DecodeResolvedUnitForTest(ru).unit_id());
EXPECT_EQ(net::eagle0::shardok::storage::ResolvedUnit_UnitStatus_FLED_UNIT, ru.status());
}
} // namespace shardok