1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-27 22:49:25 +02:00

Fix formatting, remove unused code

This commit is contained in:
Ivan Savenko
2025-05-19 17:43:29 +03:00
parent 157b4fea74
commit 38f7c04471
4 changed files with 55 additions and 44 deletions

View File

@@ -24,23 +24,18 @@
VCMI_LIB_NAMESPACE_BEGIN VCMI_LIB_NAMESPACE_BEGIN
BiasedRandomizer::BiasedRandomizer(int seed) bool RandomizationBias::roll(vstd::RNG & generator, int successChance, int totalWeight, int biasValue)
: seed(seed)
{
}
bool BiasedRandomizer::roll(int successChance, int totalWeight, int biasValue)
{ {
assert(successChance > 0); assert(successChance > 0);
assert(totalWeight >= successChance); assert(totalWeight >= successChance);
int failChance = totalWeight - successChance; int failChance = totalWeight - successChance;
int newRoll = seed.nextInt(1,totalWeight); int newRoll = generator.nextInt(1, totalWeight);
// accumulated bias is stored as premultiplied to avoid precision loss on division // accumulated bias is stored as premultiplied to avoid precision loss on division
// so multiply everything else in equation to compensate // so multiply everything else in equation to compensate
// precision loss is small, and generally insignificant, but better to play it safe // precision loss is small, and generally insignificant, but better to play it safe
bool success = newRoll * totalWeight - accumulatedBias <= successChance * totalWeight; bool success = newRoll * totalWeight - accumulatedBias <= successChance * totalWeight;
if (success) if(success)
accumulatedBias -= failChance * biasValue; accumulatedBias -= failChance * biasValue;
else else
accumulatedBias += successChance * biasValue; accumulatedBias += successChance * biasValue;
@@ -48,6 +43,16 @@ bool BiasedRandomizer::roll(int successChance, int totalWeight, int biasValue)
return success; return success;
} }
RandomGeneratorWithBias::RandomGeneratorWithBias(int seed)
: generator(seed)
{
}
bool RandomGeneratorWithBias::roll(int successChance, int totalWeight, int biasValue)
{
return bias.roll(generator, successChance, totalWeight, biasValue);
}
GameRandomizer::GameRandomizer(const IGameInfoCallback & gameInfo) GameRandomizer::GameRandomizer(const IGameInfoCallback & gameInfo)
: gameInfo(gameInfo) : gameInfo(gameInfo)
{ {
@@ -56,14 +61,14 @@ GameRandomizer::GameRandomizer(const IGameInfoCallback & gameInfo)
GameRandomizer::~GameRandomizer() = default; GameRandomizer::~GameRandomizer() = default;
bool GameRandomizer::rollMoraleLuck(std::map<ObjectInstanceID, BiasedRandomizer> & seeds, ObjectInstanceID actor, int moraleLuckValue, EGameSettings diceSize, EGameSettings diceWeights) bool GameRandomizer::rollMoraleLuck(std::map<ObjectInstanceID, RandomGeneratorWithBias> & seeds, ObjectInstanceID actor, int moraleLuckValue, EGameSettings diceSize, EGameSettings diceWeights)
{ {
assert(moraleLuckValue > 0); assert(moraleLuckValue > 0);
auto goodLuckChanceVector = gameInfo.getSettings().getVector(diceWeights); auto goodLuckChanceVector = gameInfo.getSettings().getVector(diceWeights);
int luckDiceSize = gameInfo.getSettings().getInteger(diceSize); int luckDiceSize = gameInfo.getSettings().getInteger(diceSize);
size_t chanceIndex = std::min<size_t>(goodLuckChanceVector.size(), moraleLuckValue) - 1; // array index, so 0-indexed size_t chanceIndex = std::min<size_t>(goodLuckChanceVector.size(), moraleLuckValue) - 1; // array index, so 0-indexed
if (!seeds.count(actor)) if(!seeds.count(actor))
seeds.emplace(actor, getDefault().nextInt()); seeds.emplace(actor, getDefault().nextInt());
if(goodLuckChanceVector.size() == 0) if(goodLuckChanceVector.size() == 0)
@@ -94,23 +99,18 @@ bool GameRandomizer::rollBadLuck(ObjectInstanceID actor, int luckValue)
bool GameRandomizer::rollCombatAbility(ObjectInstanceID actor, int percentageChance) bool GameRandomizer::rollCombatAbility(ObjectInstanceID actor, int percentageChance)
{ {
if (!combatAbilitySeed.count(actor)) if(!combatAbilitySeed.count(actor))
combatAbilitySeed.emplace(actor, getDefault().nextInt()); combatAbilitySeed.emplace(actor, getDefault().nextInt());
if (percentageChance <= 0) if(percentageChance <= 0)
return false; return false;
if (percentageChance >= 100) if(percentageChance >= 100)
return true; return true;
return combatAbilitySeed.at(actor).roll(percentageChance, 100, biasValueAbility); return combatAbilitySeed.at(actor).roll(percentageChance, 100, biasValueAbility);
} }
//HeroTypeID GameRandomizer::rollHero(PlayerColor player, FactionID faction)
//{
//
//}
CreatureID GameRandomizer::rollCreature() CreatureID GameRandomizer::rollCreature()
{ {
std::vector<CreatureID> allowed; std::vector<CreatureID> allowed;
@@ -215,14 +215,15 @@ ArtifactID GameRandomizer::rollArtifact(std::set<ArtifactID> potentialPicks)
std::vector<ArtifactID> GameRandomizer::rollMarketArtifactSet() std::vector<ArtifactID> GameRandomizer::rollMarketArtifactSet()
{ {
std::vector<ArtifactID> out; return {
for(int j = 0; j < 3; j++) rollArtifact(EArtifactClass::ART_TREASURE),
out.push_back(rollArtifact(EArtifactClass::ART_TREASURE)); rollArtifact(EArtifactClass::ART_TREASURE),
for(int j = 0; j < 3; j++) rollArtifact(EArtifactClass::ART_TREASURE),
out.push_back(rollArtifact(EArtifactClass::ART_MINOR)); rollArtifact(EArtifactClass::ART_MINOR),
out.push_back(rollArtifact(EArtifactClass::ART_MAJOR)); rollArtifact(EArtifactClass::ART_MINOR),
rollArtifact(EArtifactClass::ART_MINOR),
return out; rollArtifact(EArtifactClass::ART_MAJOR)
};
} }
vstd::RNG & GameRandomizer::getDefault() vstd::RNG & GameRandomizer::getDefault()
@@ -237,7 +238,7 @@ void GameRandomizer::setSeed(int newSeed)
PrimarySkill GameRandomizer::rollPrimarySkillForLevelup(const CGHeroInstance * hero) PrimarySkill GameRandomizer::rollPrimarySkillForLevelup(const CGHeroInstance * hero)
{ {
if (!heroSkillSeed.count(hero->getHeroTypeID())) if(!heroSkillSeed.count(hero->getHeroTypeID()))
heroSkillSeed.emplace(hero->getHeroTypeID(), getDefault().nextInt()); heroSkillSeed.emplace(hero->getHeroTypeID(), getDefault().nextInt());
const bool isLowLevelHero = hero->level < GameConstants::HERO_HIGH_LEVEL; const bool isLowLevelHero = hero->level < GameConstants::HERO_HIGH_LEVEL;
@@ -255,7 +256,7 @@ PrimarySkill GameRandomizer::rollPrimarySkillForLevelup(const CGHeroInstance * h
SecondarySkill GameRandomizer::rollSecondarySkillForLevelup(const CGHeroInstance * hero, const std::set<SecondarySkill> & options) SecondarySkill GameRandomizer::rollSecondarySkillForLevelup(const CGHeroInstance * hero, const std::set<SecondarySkill> & options)
{ {
if (!heroSkillSeed.count(hero->getHeroTypeID())) if(!heroSkillSeed.count(hero->getHeroTypeID()))
heroSkillSeed.emplace(hero->getHeroTypeID(), getDefault().nextInt()); heroSkillSeed.emplace(hero->getHeroTypeID(), getDefault().nextInt());
auto & heroRng = heroSkillSeed.at(hero->getHeroTypeID()); auto & heroRng = heroSkillSeed.at(hero->getHeroTypeID());
@@ -314,7 +315,6 @@ SecondarySkill GameRandomizer::rollSecondarySkillForLevelup(const CGHeroInstance
int selectedIndex = RandomGeneratorUtil::nextItemWeighted(weights, heroRng.seed); int selectedIndex = RandomGeneratorUtil::nextItemWeighted(weights, heroRng.seed);
SecondarySkill selectedSkill = skills.at(selectedIndex); SecondarySkill selectedSkill = skills.at(selectedIndex);
//deterministic secondary skills //deterministic secondary skills
++heroRng.magicSchoolCounter; ++heroRng.magicSchoolCounter;
++heroRng.wisdomCounter; ++heroRng.wisdomCounter;

View File

@@ -18,18 +18,29 @@ enum class EGameSettings;
class CGHeroInstance; class CGHeroInstance;
class RandomizationBias
{
int32_t accumulatedBias = 0;
public:
/// Performs coin flip with specified success chance
/// Returns true with probability successChance percents, and false with probability totalWeight-successChance percents
bool roll(vstd::RNG & generator, int successChance, int totalWeight, int biasValue);
};
/// Biased randomizer that has following properties: /// Biased randomizer that has following properties:
/// - at bias value of 0 it acts as statistical random generator, just like vstd::RNG /// - at bias value of 0 it acts as statistical random generator, just like vstd::RNG
/// - at bias value of 100 it guarantees that it will take at most 100/chance rolls till succesfull roll /// - at bias value of 100 it guarantees that it will take at most 100/chance rolls till succesfull roll
/// - at bias value between 1..99 similar guarantee is also provided, but with larger number of rolls /// - at bias value between 1..99 similar guarantee is also provided, but with larger number of rolls
/// No matter what bias is, statistical probability on large number of rolls remains the same /// No matter what bias is, statistical probability on large number of rolls remains the same
/// Its goal is to simulate human expectations of random distributions and reduce frustration from "bad" rolls /// Its goal is to simulate human expectations of random distributions and reduce frustration from "bad" rolls
class BiasedRandomizer class RandomGeneratorWithBias
{ {
CRandomGenerator seed; CRandomGenerator generator;
int32_t accumulatedBias = 0; RandomizationBias bias;
public: public:
explicit BiasedRandomizer(int seed); explicit RandomGeneratorWithBias(int seed);
/// Performs coin flip with specified success chance /// Performs coin flip with specified success chance
/// Returns true with probability successChance percents, and false with probability 100-successChance percents /// Returns true with probability successChance percents, and false with probability 100-successChance percents
bool roll(int successChance, int totalWeight, int biasValue); bool roll(int successChance, int totalWeight, int biasValue);
@@ -42,8 +53,8 @@ class DLL_LINKAGE GameRandomizer final : public IGameRandomizer
struct HeroSkillRandomizer struct HeroSkillRandomizer
{ {
HeroSkillRandomizer(int seed) explicit HeroSkillRandomizer(int seed)
:seed(seed) : seed(seed)
{} {}
CRandomGenerator seed; CRandomGenerator seed;
@@ -62,13 +73,14 @@ class DLL_LINKAGE GameRandomizer final : public IGameRandomizer
std::map<HeroTypeID, HeroSkillRandomizer> heroSkillSeed; std::map<HeroTypeID, HeroSkillRandomizer> heroSkillSeed;
std::map<PlayerColor, CRandomGenerator> playerTavern; std::map<PlayerColor, CRandomGenerator> playerTavern;
std::map<ObjectInstanceID, BiasedRandomizer> goodMoraleSeed; std::map<ObjectInstanceID, RandomGeneratorWithBias> goodMoraleSeed;
std::map<ObjectInstanceID, BiasedRandomizer> badMoraleSeed; std::map<ObjectInstanceID, RandomGeneratorWithBias> badMoraleSeed;
std::map<ObjectInstanceID, BiasedRandomizer> goodLuckSeed; std::map<ObjectInstanceID, RandomGeneratorWithBias> goodLuckSeed;
std::map<ObjectInstanceID, BiasedRandomizer> badLuckSeed; std::map<ObjectInstanceID, RandomGeneratorWithBias> badLuckSeed;
std::map<ObjectInstanceID, BiasedRandomizer> combatAbilitySeed; std::map<ObjectInstanceID, RandomGeneratorWithBias> combatAbilitySeed;
bool rollMoraleLuck(std::map<ObjectInstanceID, RandomGeneratorWithBias> & seeds, ObjectInstanceID actor, int moraleLuckValue, EGameSettings diceSize, EGameSettings diceWeights);
bool rollMoraleLuck(std::map<ObjectInstanceID, BiasedRandomizer> & seeds, ObjectInstanceID actor, int moraleLuckValue, EGameSettings diceSize, EGameSettings diceWeights);
public: public:
explicit GameRandomizer(const IGameInfoCallback & gameInfo); explicit GameRandomizer(const IGameInfoCallback & gameInfo);
~GameRandomizer(); ~GameRandomizer();
@@ -83,8 +95,6 @@ public:
bool rollCombatAbility(ObjectInstanceID actor, int percentageChance); bool rollCombatAbility(ObjectInstanceID actor, int percentageChance);
// HeroTypeID rollHero(PlayerColor player, FactionID faction) override;
CreatureID rollCreature() override; CreatureID rollCreature() override;
CreatureID rollCreature(int tier) override; CreatureID rollCreature(int tier) override;

View File

@@ -117,6 +117,7 @@ public:
virtual bool isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero) = 0; virtual bool isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero) = 0;
/// Returns global random generator. TODO: remove, replace with IGameRanndomizer as separate parameter to such methods
virtual vstd::RNG & getRandomGenerator() = 0; virtual vstd::RNG & getRandomGenerator() = 0;
}; };

View File

@@ -19,7 +19,7 @@ enum class EArtifactClass;
namespace vstd namespace vstd
{ {
class RNG; class RNG;
} }
/// Provides source of random rolls for game entities /// Provides source of random rolls for game entities