Ich habe ein Problem mit einem bestimmten Codeabschnitt, der einem Gegner basierend auf seinem voreingestellten Schwierigkeitsgrad eine zufällige Menge von Elementen geben soll. Ich verwende eine modifizierte Template-Version der zufälligen Funktion von Bjorne. Als ich seine ursprüngliche Version verwendet hatte ich immer noch das Problem:Verwenden von Zufallszahlen innerhalb von Switch-Statement-Fällen
Random number generator code from Stroustrup:
template<class T>
T rand_num(const T & low, const T & high)
{
static std::default_random_engine re{};
using Dist = std::uniform_int_distribution<T>;
static Dist uid{};
return uid(re, Dist::param_type{ low,high });
}
Wenn ich den Abschnitt zu testen, indem sie ein EnemyAI
Objekt, das die OffensiveEntity
und Einstellung der Schwierigkeit zu kapselt, sagen wir, 1, ist es immer setzt die Zufallszahl auf 1 und wählt immer in diesem Fall den Gesundheitstrank. Wenn ich die zweite if
-Anweisung auf eine Bedingung von if (tempRandom == 1)
setzen würde, würde sie den Stick wählen.
void EnemyAI::Equip()
{
m_offensiveEntity->ClearItems();
std::vector<std::shared_ptr<Item>> tempItems;
int tempRandom = 0;
switch (m_difficultyLevel)
{
case 0:
case 1:
{
tempRandom = rand_num<int>(1, 4);
if ((tempRandom == 1) || (tempRandom == 2) || (tempRandom == 3) || (tempRandom == 4))
tempItems.push_back(CreateTempItem("Health Potion : HP", 3, 3,
-10, Result::Effect::nothing));
if (tempRandom == 3)
tempItems.push_back(CreateTempItem("Wooden Stick : DMG", 5, 2, 10, Result::Effect::nothing, 3, 13, Result::Effect::nothing));
break;
}
case 2: ... etc
Was ist die Ursache für dieses Problem? Hier ist die Ausgabe:
Health Potion : HP name
3 durability
-10 total damage
3 energy cost
0 effect
Wenn in dieser Typisierung:
int main()
{
std::shared_ptr<EnemyAI> offensiveEntityInterface =
std::make_shared<EnemyAI>(EnemyAI("Dank Memerson", 50, 1));
offensiveEntityInterface->Equip();
for (auto & i : offensiveEntityInterface->GetEquiped())
{
std::cout << i->GetName() << " name \n";
std::cout << i->GetHP() << " durability \n";
std::shared_ptr<const Result> tempResult = i->Use();
std::cout << tempResult->m_totalDamage << " total damage \n";
std::cout << tempResult->m_energyCost << " energy cost \n";
std::cout << tempResult->m_effect << " effect \n";
}
std::cin.get();
return 0;
}
Heres der Quellcode in einem Pastebin https://pastebin.com/F4Q74Gc6
Also Ihr zweites Beispiel ist nicht notwendig, wenn Sie die standardmäßige Zufallsmaschine als statisch wie im ersten Beispiel deklarieren? Wenn die Funktion mit dem std :: default_random_engine-Engine-Objekt mit std :: random_device in der zweiten Funktion aufgerufen wird, wird das exakt gleiche Ergebnis erzeugt, wenn das statische std :: default_random_engine-Engine-Objekt in der Funktion initialisiert und aufgerufen wird. – Chopdops
@Chopfdops Die Ausgabe zwischen den beiden Versionen unterscheidet sich nicht wesentlich in dem, was sie "tun", d. H. Beide arbeiten, um Zufallszahlen in einem bestimmten Bereich zu erzeugen. Der Unterschied besteht darin, dass die erste Version neue Instanziierungen von 'std :: default_random_engine' für jeden eindeutigen Typ erzeugt, mit denen die Funktion aufgerufen wird, während die zweite Version nur eine Instanziierung erstellt, unabhängig davon, wie viele Typen Sie verwenden (außer Sie erstellen manuell) mehr Motoren selbst). – Xirema
@Chopdops Der Grund, warum das wichtig ist, ist, dass "engine" -Objekte ziemlich teuer zu konstruieren sind, besonders wenn 'std :: default_random_engine' auf' std :: mt19937' mappt, was bei vielen C++ - Implementierungen Standard ist. Wenn Sie wissen, dass Sie nur 'rand_num' aufrufen und keine andere Version dieser Funktion aufrufen, dann ist der Unterschied egal und Sie können die erste Version verwenden. Wenn nicht, erleiden Sie jedes Mal, wenn ein Typ zum ersten Mal verwendet wird, Leistungseinbußen. –
Xirema