Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

11

27.08.2015, 06:33

Bitte Themen vor dem Beantworten richtig lesen.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

12

27.08.2015, 14:12

Um eine Zufallszahl in einem Range zu generieren verwende ich (C++, 2011 standard) folgende Funktionen (hier nur die für Int).
Ist vielleicht nicht genau dass was du brauchst, aber vielleicht hilft es trotzdem.


C-/C++-Quelltext

1
2
3
4
5
6
7
int generate_RandomInt(int x, int y)
{
    random_device rd;
    mt19937 e2(rd());
    uniform_int_distribution<int> dist(x, y); 
    return dist(e2);
}

13

27.08.2015, 14:14

time.h, inkonsistente Namensgebung und eine Funktion in einem Namespace. Hm.
Ich würde echt gern den vollen Code von Korowai sehen, weil ich mir echt nur sehr schwer was unter der Beschreibung vorstellen kann.

EDIT: Der Code über mir ist keine so gute Idee.... Jedes mal einen neuen Generator anzulegen, random_device nicht auf Exceptions prüfen, würde ich so wirklich lieber nicht benutzen.

MfG
Check

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

14

27.08.2015, 18:56

Um eine Zufallszahl in einem Range zu generieren verwende ich (C++, 2011 standard) folgende Funktionen (hier nur die für Int).

C-/C++-Quelltext

1
    mt19937 e2(rd());
Der Code ist sehr sehr langsam. Ich weiß, das klingt verblüffend, aber "random_device()" ist saumäßig langsam und schon wenige Calls davon pro Frame haben unsere Framerate massiv einbrechen lassen, unter 4 FPS. Ich rate stark dazu das device einmalig zu holen und dann immer darauf zuzugreifen. Auch das Erzeugen immer neuer Distributions ist nicht unbedingt schnell und meist auch überflüssig.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Korowai

unregistriert

15

27.08.2015, 21:48

Hallo,

danke für die Denkanstösse.

Da ich eine Version code::blocks nutze, die noch kein c++ 2011 hat, kann ich die neueren Funktionen noch nicht testen.

Ich stelle den code gerne noch ein, obwohl er inzwischen entschlackt ist und stark vereinfacht wurde. Das Ziel ist lediglich die Ermittlung eines per Runde sich ändernden Faktors, der mit dem Standortfaktor multipliziert wird und eine Art Preisentwicklung simuliert, die sich jede Runde ändert. SPäter möchte ich das ganze noch an die Arten und Anzahl der Käufe anpassen, die getätigt werden und die per Zufall erfolgen, also abhängig von der WArenverfügbarkeit. SOweit bin ich aber noch lange nicht.

Aber hier mal der code, im momentanen Stand. Ihr könnt gerne verbessern und rummäkeln, wenn Ihr Lust habt. Würde mich freuen

main.cpp:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <conio.h>
#include <iterator>
#include <list>
#include <vector>
#include <list>
#include <stdio.h>
#include <cstdlib>
#include <ctime>
#include <string>
#include "Spieler.hpp"
#include "Cbasis.hpp"
#include "CFoerderung.hpp"
#include "CPlanet.hpp"
#include "Flugwaechter.hpp"
#include "Jaeger.hpp"
#include "Schuerfer.hpp"
#include "Spieler.hpp"
#include "Preisentwicklung.hpp"
#include "Markt.hpp"

using namespace std;


string name;
int Anzahl;
int Runde=1;
int plecs0=500000;
int plecs1=50000;
int plecs2=50000;
int plecs3=50000;
int EP1=0;
int EP2=0;
int EP3=0;
int EP0=0;
float Inflation=0;
float Deflation=0;
float Kostenniveau=1;
float Kostenstand=1;
int Basisnummer0=13;
int alteRunde=1;

const int Mobile=4;

float Preisabfrage(float Kostenniveau);
float Deflationsabfrage(float Deflation);
float Inflationsabfrage(float Inflation);
...


int main ()
{
srand(time(0));

...

Menue(..);
...
}


Menue.cpp:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
void Menue(...)
{
    int Umrechnung;
    float Marktwertanzeige;
    float Marktwerte;
    float Kostenniveau;
    float Deflation;
    float Inflation;

    Preisabfrage(Kostenniveau);
    Deflationsabfrage(Deflation);
    Inflationsabfrage(Inflation);
    Kostenniveau=Preisabfrage(Kostenniveau);
    Deflation=Deflationsabfrage(Deflation);
    Inflation=Inflationsabfrage(Inflation);


    while (true)
    {
    string Basisname;


    if (alteRunde<=Runde)
    {
        if (Basisnummer0==13)
        {

        Marktwerte= (Kostenniveau+Inflation-Deflation)/90*100;
        };
        if (Basisnummer0==1)
        {

        Marktwerte= (Kostenniveau+Inflation-Deflation)/105.0*100;
        };
        if (Basisnummer0==9)
        {

            Marktwerte= (Kostenniveau+Inflation-Deflation)/90.0*100;
        }
        if (Basisnummer0==21)
        {

            Marktwerte= (Kostenniveau+Inflation-Deflation)/95.0*100;
        }
    };

    Umrechnung=Marktwerte*100;
    Marktwertanzeige=Umrechnung/100.0;

// Anzeige zum Test der Werte

    cout << "Deflation = " << Deflation << endl;
    cout << "Inflation = " << Inflation << endl;
    cout << "Kostenniveau = " << Kostenniveau << endl;
    cout << "Marktberechnung ohne Planet = " << Kostenniveau+Inflation-Deflation << endl;
    cout << "Markt1.Wertentwicklung = " << Markt1.Wertentwicklung << endl;

    ...


Die Preisentwicklung.cpp (hpp lasse ich mal weg)

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include "Preisentwicklung.hpp"

float Preisabfrage(float Kostenniveau)
{
    int Kostenentwicklung;

    Kostenentwicklung= rand()%99+1;


    if (Kostenentwicklung<=20)
    {
        Kostenniveau=0.85;
    }

    else if ((Kostenentwicklung>20)&&(Kostenentwicklung<=40))
        {
            Kostenniveau=0.95;

        }
        else if ((Kostenentwicklung>40)&&(Kostenentwicklung<=60))
        {
            Kostenniveau=1;

        }
        else if ((Kostenentwicklung>60)&&(Kostenentwicklung<=80))
        {
            Kostenniveau=1.05;

        }
        else if ((Kostenentwicklung>80)&&(Kostenentwicklung<=100))
        {
            Kostenniveau=1.15;

        }

return(Kostenniveau);
}

float Deflationsabfrage(float Deflation)
{
    int Kostenentwicklung;

    Kostenentwicklung= rand()%99+1;

    if (Kostenentwicklung<20)
    {
        Deflation=0.3;
    }
    else if (Kostenentwicklung>=21&&Kostenentwicklung<75)
    {
        Deflation=0.1;
    }
    else
    {
        Deflation=0.2;
    }
    return (Deflation);
}

float Inflationsabfrage(float Inflation)
{
    int Kostenentwicklung=0;

    Kostenentwicklung= rand()%99+1;

    if (Kostenentwicklung <20)
    {
        Inflation=0.3;
    }
    else if (Kostenentwicklung>=25&&Kostenentwicklung<75)
    {
        Inflation=0.1;
    }
    else
    {
        Inflation=0.2;
    }
    return (Inflation);

}


Es ist jetzt sehr aufs wesentliche reduziert. Ich hatte mich vorher in Umrechnungen verpopelt, die weder sinnbringend noch effizient waren.
Später sollen die oben genannten GImmicks hinzukommen.

Sorry, dass der code jetzt so billig wirkt, im Angesicht der vielen schlauen Antworten. Danke nochmal.

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

16

27.08.2015, 22:12

Code::Blocks muss gar kein C++11 weil das nur deine IDE ist. Der Compiler ist wahrscheinlich GCC oder Clang. Beide besitzen hervorragende Unterstützung für C++11 als auch C++14. Hast du daran gedacht, dem Compiler mitzuteilen, dass du gerne C++11 nutzen würdest? (Kommandozeilenargument: -std=c++11) Wenn es also nicht geht, würde ich dir empfehlen, dass du deinen Compiler updatest.

Rummäkeln dürfen wir? Gott sei dank, denn der ist wirklich nicht schön anzusehen. :P
Die wilden Ifs (bei denen du übrigens bei Einzeilern die {} weglassen kannst) würde ich mit Tabellen ersetzen.
Zum Beispiel den Code in "Preisabfrage" kannst du viel kompakter formulieren:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
float Preisabfrage(float Kostenniveau)
{
    static float MöglicheKosten[] = { 0.85, 0.95, 1.0, 1.05, 1.15 }; //Um die Wahrscheinlichkeit anzupassen, ist es am Einfachsten wenn du ein Wert mehrfach vorkommt.
    return MöglicheKosten[rand()%5]; //Es werden gleich nur 5 ausgewählt, statt 100. Außerdem sind
    //die Werte in einer kleinen Tabelle anstatt eine monströsen Verzweigung. Normalerweise würde ich noch die Verwendung von 
    //std::extent<decltype(MöglicheKosten)>::value empfehlen, um die 5 wegzubekommen, die man leicht mal vergessen könnte, bei einer Änderung
    //mit anzupassen. Aber da du offenbar noch eher am Anfang bist, ist die 5 direkt die einfachste Lösung.
}


Ich verstehe zum Beispiel auch nicht ganz warum du Marktwerte erst mit 100 multiplizierst und danach wieder durch 100 teilst. Da könntest du auch den Ursprungswert direkt verwenden. Ich würde dir empfehlen, dass du nur einen Datentypen verwendest. Du hast alle Konstanten als "double"s angegeben(kein f), rechnest aber mit "float"s. Für die Art Simulation, wäre es auch nicht verkehrt, generell Gleitkommazahlen doppelter Genauigkeit einzusetzen.

An der Stelle noch ein Vorschlag, für eine C++11 Methode, die wenigstens etwas besser ist:
(Achtung, nicht Threadsicher und immernoch nicht optimal, ich glaube aber, dass das für dich momentan nicht so wichtig ist.)

C-/C++-Quelltext

1
2
3
4
5
6
int generate_RandomInt(int Min, int Max)
{
    static mt19937 Generator(random_device());
    uniform_int_distribution<int> Distribution(Min, Max); 
    return Distribution(Generator);
}

Wenn du die C++11 direkt verwenden würdest, wäre es auch einfach direkt das zu erreichen, was du gerade selbst machst: Werte mit verschiedener Wahrscheinlichkeit auswählen.
Siehe: std::discrete_distribution
Warum "rand" eigentlich generell schlecht ist: rand() Considered Harmful

Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von »Spiele Programmierer« (27.08.2015, 22:24)


David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

17

28.08.2015, 06:42

Warum übergibst du Parameter an eine Funktion, aber benutzt deren Werte dann gar nicht, sondern benutzt die Parameter wie lokale Variablen? Ich meine z. B. den Parameter “Inflation“ der Funktion “Inflationsabfrage“.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

18

28.08.2015, 07:21

(Kommandozeilenargument: -std=c++11)
In Code::Blocks gibt es dafür unter Build-Options auch eine Checkbox, die man setzen kann. Man kann das natürlich auch über Parameter machen, finde ich aber irgendwie kontraproduktiv, bzw. nur dann sinnvoll, wenn die Option unter Code::Blocks tatsächlich nicht angeboten wird und der Compiler es trotzdem kann. Hier könnte genau das der Fall sein, ich wollte es trotzdem mal anmerken, damit nicht jeder Code::Blocks-User die Option per Parameter angibt.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Korowai

unregistriert

19

28.08.2015, 15:43

Hi David,

das ist noch meinem anfänglichen Missverständnis geschuldet, dass ich dachte, ich müsse einer Funktion die Variable mitgeben, deren Wert sie zurück liefern soll. Ist natürlich Quatsch, kann ich noch rausnehmen.

Hi BLueCobold,

ich werde mal nachsehen, ob ich das einstellen kann. Spätestens dann, wenn ich mich mit der random Funktion, die hier vorgestellt wurde, beschäftigen werde.

Hi SPieleprogrammierer,

ich muss mir DEinen code noch genauer ansehen. SIeht zunächst mal deutlich kürzer aus. Da steckt allerdings ein Effekt drin, den ich noch gar nicht kenne. Die Migrierung von rand in [ ... ] als Zusatz zum array. Das kenne ich noch gar nicht. Ich bin da noch nicht so sicher mit dem Verweben verschiedener Befehle, deshalb ist mein code noch so gestaffelt und gestückelt.

Der Zusatz des f bei den Werten, um als float auszuweisen, sehe ich in meinen Büchern verwendet. Es wurde nur nicht erklärt, dass das sein muss und das beim Weglassen der Variablentyp geändert wird. Danke für den HInweis.

c++11 EInstellung werde ich nach BlueCobolds Hnweis mal in code::blocks suchen und dazuschalten. Vielleicht dann auch direkt von rand zu discrete distribution umschwenken.

Bis denne,


Vielen Dank für die Unterstützung...

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

20

28.08.2015, 16:04

Prinzipiell kannst du es auch so schreiben, wenn es für dich verständlicher ist:

C-/C++-Quelltext

1
2
3
4
5
6
float Preisabfrage(float Kostenniveau)
{
    static float MöglicheKosten[] = { 0.85, 0.95, 1.0, 1.05, 1.15 };
    int GewählterIndex = rand() % 5;
    return MöglicheKosten[GewählterIndex];
}

Werbeanzeige