Compare commits

...
Author SHA1 Message Date
admin 96b9f63078 add a floor 2025-11-28 15:51:21 -08:00
admin f61c86964b before trying on main 2025-11-28 15:36:54 -08:00
3 changed files with 15 additions and 4 deletions
@@ -374,10 +374,10 @@ auto AbstractMCTSAI::MCTSExpansion(MCTSNode* node, const MCTSGameEngine& engine)
// Get outcome information from engine
const auto outcomeInfo = engine.getBinaryOutcomeInfo(*node->gameState, *action);
// Set up outcome metadata (2 outcomes for binary actions)
// Set up outcome metadata
chanceNode->outcomeProbabilities = outcomeInfo.getProbabilities();
chanceNode->outcomeRolls = outcomeInfo.getRepresentativeRolls();
chanceNode->totalActions = 2; // Binary: success and failure
chanceNode->totalActions = chanceNode->outcomeProbabilities.size();
// Chance node immediate score will be computed as expected value during backpropagation
// For now, initialize to parent's score as a reasonable default
@@ -71,10 +71,11 @@ auto GetFireDamage(
const double openEndedPercentileRoll1,
const double openEndedPercentileRoll2) -> CombatDamage {
double randomSwing = 1.0 + (2 * openEndedPercentileRoll1 - 100.0) * RANDOMNESS_FACTOR / 100.0;
const double basicDamage = BASE_FIRE_DAMAGE_PER_TROOP * randomSwing * troops;
const double basicDamage = std::max(0.0, BASE_FIRE_DAMAGE_PER_TROOP * randomSwing * troops);
randomSwing = 1.0 + (2 * openEndedPercentileRoll2 - 100.0) * RANDOMNESS_FACTOR / 100.0;
const double penetratingDamage = BASE_PENETRATING_FIRE_DAMAGE_PER_TROOP * randomSwing * troops;
const double penetratingDamage =
std::max(0.0, BASE_PENETRATING_FIRE_DAMAGE_PER_TROOP * randomSwing * troops);
return CombatDamage::Builder()
.SetFire(basicDamage)
@@ -4,6 +4,7 @@
#include "PlayerSetupCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/ShardokException.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/actions/EndPlayerSetupCommand.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/actions/PlaceHiddenUnitCommand.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/actions/PlaceUnitCommand.hpp"
@@ -20,6 +21,15 @@ auto PlayerSetupCommandFactory::AddAvailablePlaceAndHideUnitCommandsForOneUnit(
const bool isDefender,
const Unit *unit,
const GameStateW &gameState) const -> void {
// Attackers must have a valid starting_position_index (>= 0)
// Defenders use -1 since they share a single starting positions list
if (!isDefender && unit->starting_position_index() < 0) {
throw ShardokInternalErrorException(
"Attacker unit " + std::to_string(unit->unit_id()) +
" has invalid starting_position_index: " +
std::to_string(unit->starting_position_index()));
}
const auto &thisUnitStartingPositions =
(isDefender ? gameState->hex_map()->defender_starting_positions()
: gameState->hex_map()->attacker_starting_positions()->Get(