mmofacts.com

Rohstoffe (mal wieder)

gepostet vor 16 Jahre, 7 Monate von Sanni
Ich weiss net habe gerade voll den black out aber mir fällt gerade absolut nichtmehr ein wie man einer Rohstoffe jede stunde um 5 % erhöht aber nicht in form von ticks sondern das man nach einer halbe stunde auch 2,5% hinzu bekommen hat. Ich hate es mal ausgerechnet nur ist es schon sehr lange her.
time() - last_getet_money = restzeit
habe_rohstoffe / 100 * 5 = get_rohstoffe
weiter komme ich nicht... mir wills einfach net einfallen...
gepostet vor 16 Jahre, 7 Monate von Klaus
50% der Arbeit hast du ja schon geschafft.
habe_rohstoffe = habe_rohstoffe + get_rohstoffe
last_geted_manni = time()
gepostet vor 16 Jahre, 7 Monate von None
got. past tense von "to get" ist "got", nicht "geted".
(sollte dies hier gemeint sein)
gepostet vor 16 Jahre, 7 Monate von Todi42
Wenn der Rohstoff innerhalb einer Stunde linear um 5% steigt, dann steigt er innerhalb einer Stunde um den Faktor 1,05. Gegeben sein die Anfangsmenge x0 und die Anfangszeit t0, dann hat man zum Zeitpunkt t1 die Menge x1. (Die Zeitdifferenz muss in Sekunden gegeben sein.)
x1 = x0 * + x0 * (0,05 * (t1 - t0)/60*60)
Dreisatz ist schon ne tolle Sache ;-)
gepostet vor 16 Jahre, 7 Monate von Sanni
@Klaus
ja so könnte man es machen wen man mit Ticks arbeitet.
3600 Sekunden sind ja +5% der Rohstoffe
doch wen ich jetzt 1850 Sekunden nach dem letsten aufruf habe so kann ich ja net wieder einfach 5% hinzupacken sondern 2,5%. Genau so wie 1 sekunde, 3599 oder 999.999.9999.9999.999 nach dem letsten aufruf müssen gewertet werden als würde man stündlich 5% der aktuellen Rohstoffe hinzubekommen.
Nur mir fällt gerade die rechnung dazu nicht ein.
gepostet vor 16 Jahre, 7 Monate von Otteros
vll hilft das:
restzeit = time() - last_getet_money
get_rohstoffe = habe_rohstoffe / 100 * 5
get_rohstoffe = get_rohstoffe / 3600 * restzeit (wenn das dein Zeitunterschied ist, der berechnet werden soll)
stimmt zwar glaub ich net ganz, aber besser als ewig zu grübbeln.
MfG Otto
gepostet vor 16 Jahre, 7 Monate von Sanni
ahh genau das wars, danke Todi42 und Otteros.
gepostet vor 16 Jahre, 7 Monate von Nuky
Wenn man nicht denken will, fragt man einfach, ge?
die formel von todi in leicht:
x1 = x0 plus das was dazugekommen ist
das was dazugekommen ist = 5% von x0 * vergangene zeit
vergangene zeit = jetzt - damals / anzahl der sekunden pro stunde
gepostet vor 16 Jahre, 7 Monate von Otteros
Man muss nur aufpassen, das man 60*60 in Klammern setzt oder 3600 schreibt, weil sonnst wird das ganze durch 60 geteilt und wieder mit 60 mal genommen: Effekt = 0.
MfG Otto
gepostet vor 16 Jahre, 7 Monate von Kallisti
Das ist aber nicht korrekt, weil es bei eurer Formel keine "Zinseszinsen" gibt und jemand der jede Minute beispielsweise klickt (oder was auch immer die Verteilung ausloest) effektiv mehr Rohstoffe bekommt, als jemand der das nicht tut. Und bei minuetlicher Verteilung ist die Problematik von Rundungsfehlern natuerlich gewaltig.
Um das mal deutlicher zu machen - bei oben angegebenem Code bekommt ein Spieler der mit einem Bot oder Script einen Tag lang jede Sekunde (!) die Seite reloaden laesst seine Rohstoffe staerker gegenueber jemandem erhoeht, der sich nur einmal am Tag einloggt.
Muss man sich halt einen Zeitraum definieren, der als virtuelle "Verteilung" fungiert. Genau aus dem Grund zahlt einem die Bank ja auch nur einmal im Jahr Zinsen aus und nicht jede Stunde.
Wenn man dann wiederum nichts unter den Tisch fallen lassen moechte (auszurechnen wie viele Stunden in der Zeitdifferenz stecken reicht nicht, weil floor(3.5)+floor(3.5) eben 6 und nicht 7 ist.), muss das Ganze Datumsfunktionen mitnutzen.
In Pseudocode gesprochen:

hours_diff = GetTotalHours(current_time) - GetTotalHours(last_update)
x *= 1.05 ^ hours_diff
GetTotalHours waere allerdings recht haesslich zu realisieren. Vielleicht einfacher:

time_diff = current_time - last_update
// more minutes/seconds in current time than in last update
if(current_time % 3600 > last_update % 3600) {
// only fully passed hours are counted
hours_diff = int(time_diff / 3600)
} else {
// there was a transition, so we have to count "broken" hours
hours_diff = int(time_diff / 3600) + 1
}
x *= 1.05 ^ hours_diff
Man koennte natuerlich auch erst die Berechnung machen und dann nur ein if, falls true +1 drauf, aber obiges finde ich uebersichtlicher fuer das Verstaendnis.
So erreichst du natuerlich nur eine stuendliche Verteilung und eben nicht, dass es jede halbe Stunde z.B. 2.5% dazu gibt, aber das ist technisch ja auch gar nicht moeglich.
Willst du wirklich feinere Granularitaet, musst du den Faktor und die Zeitdifferenz anpassen, also beispielsweise fuer Minuten dies hier machen:

time_diff = current_time - last_update
// more seconds in current time than in last update
if(current_time % 60 > last_update % 60) {
// only fully passed minutes are counted
minutes_diff = int(time_diff / 60)
} else {
// there was a transition, so we have to count "broken" minutes
minutes_diff = int(time_diff / 60) + 1
}
x *= (1+0.05/60) ^ minutes
Wichtig natuerlich: Je geringere Zeitintervalle, umso mehr Zinseszinsen erhaelt der Spieler, allein deshalb wuerde ich groessere Intervalle als Minuten nehmen oder mich gegen eine prozentuale Loesung entscheiden.
Das Problem hier ist natuerlich, dass je feiner die Granularitaet wird, du Probleme mit Rundungsfehlern bekommst. Aber das ist bei der anderen, obigen "Loesung" ganz ohne Zinseszinsen, ja genau dasselbe Problem.
Deshalb musst du auf jeden Fall Gleitkommawerte in der DB abspeichern (wobei man natuerlich aufgrund der limiterten Praezision auch hier Fehler hat, aber ich denke die kann man unter den Tisch fallen lassen) und an den Stellen an denen du diese benutzt nur den Integer part modifizieren.
Man sieht, selbst so ein Thema ist mit gewissen Annahmen (prozentuale Erhoehung) nicht so einfach, wie viele meinen.
gepostet vor 16 Jahre, 7 Monate von duschendestroyer
andere frage
warum will man einen rohstoff potenziell wachsen lassen?
wenn sich dein rohstoff jede stunde um 5% erhöht dann heisst das ja dass man umso mehr rohstoffe bekommt je mehr man im lager hat
das passiert höchstens dann wenn du geld oder bakterien lagerst
gepostet vor 16 Jahre, 7 Monate von Kallisti
Richtig, aber nichtsdestotrotz haben ihn vier Leute in einer fehlerhaften Implementation bestaerkt.
Ich wollte mit meinen Beispielen auch nur aufzeigen, dass es (lassen wir die logische Begruendung mal aussen vor) auch technisch gar keinen Sinn macht es so zu berechnen.
gepostet vor 16 Jahre, 7 Monate von Sanni
@Kallisti boar juhu endlich mal eine Lösung vielen vielen dank für deine mühe, aber was ist den das für ein Rechenoperator: ^
ausserdem, wen ich die kommzahlen speichere nur nicht ausgebe sollten doch rundungsfehler minimal endstehen also nur solche über die man echt hinweg sehen kann?
@duschendestroyer in meinem Fall brauche ich es für die Bevölkerung. Sie steigert sich ja nicht immer konstant um 10 Personen sondern muss jeh nach menge wachsen. Das diese in Kriegen wieder sterben müssen um am ende nicht die 32 bit Grenze zu ereichen ist schon klar.
gepostet vor 16 Jahre, 7 Monate von Progralixx
Original von Sanni
was ist den das für ein Rechenoperator: ^

x ^ y heißt "x hoch y"
Original von Sanni

ausserdem, wen ich die kommzahlen speichere nur nicht ausgebe sollten doch rundungsfehler minimal endstehen also nur solche über die man echt hinweg sehen kann?
Ist das eine Frage oder eine Feststellung? Ich hab jetzt keine Lust darüber nachzudenken was das heißen soll. Benutz mal die deutsche Rechtschreibung und Grammatik.
gepostet vor 16 Jahre, 7 Monate von Sanni
ähm, da ist ein Fragezeichen somit wird es wohl eine Frage sein.
Die Rechtschreibung kann so gut sein wie sie will, es liegt rein an der interpretation des Lesers vorallem wie er es verstehen will.
gepostet vor 16 Jahre, 7 Monate von progs
Da es (gerade bei der Bevölkerung) keine 0,5 Menschen gibt, solltest Du bei der Ausgabe immer abrunden, dann hast Du keine Probleme und es entstehen keine Rundungsdifferenzen. Außerdem wunder sich dann niemand, wieso er irgendwas nicht bauen kann, wenn er 100 Leute angezeigt bekommt, 100 Leute braucht, aber in der DB nur 99,945323 stehen.
gepostet vor 16 Jahre, 7 Monate von Kallisti
Nur um Missverstaendnissen vorzubeugen: Du solltest bei der Anzeige abrunden, nicht bei Speicherung. Also in der DB _sollen_ xx,yyyy stehen. Und ja, die Fehler die durch die mangelhafte Praezision von Float oder Double Zahlen entsteht sollten in dem Fall wirklich zu vernachlaessigen sein.
gepostet vor 16 Jahre, 7 Monate von Todi42
Original von Kallisti
Richtig, aber nichtsdestotrotz haben ihn vier Leute in einer fehlerhaften Implementation bestaerkt.

Wo siehst Du einen Fehler in meinem Ansatz (mal von den fehlenden Klammern) abgesehen? Der OP wollte ein lineares Wachstum (was meiner Meinung nach auch Sinn macht).
gepostet vor 16 Jahre, 7 Monate von Kallisti
Original von Todi42
Original von Kallisti
Richtig, aber nichtsdestotrotz haben ihn vier Leute in einer fehlerhaften Implementation bestaerkt.

Wo siehst Du einen Fehler in meinem Ansatz (mal von den fehlenden Klammern) abgesehen? Der OP wollte ein lineares Wachstum (was meiner Meinung nach auch Sinn macht).
Bei deinem Ansatz bekommt jemand, der haeufiger klickt mehr Wachstum, weil deine Rechnung die Zinseszinsen nicht mit abdeckt. Aber durch die Berechnung sorgt derjenige dafuer, dass er quasi regelmaessig seine Zinsen ausgeschuettet bekommt und bei der naechsten Verteilung auch Zinseszinsen erhaelt, was bei jemandem der nur einmal zugreift nicht der Fall ist.
Abgesehen davon ist ein prozentuales Wachstum absolut gesehen nicht linear.
Beispiel:
Spieler 1 hat 100.000 Einwohner
Spieler 2 hat 100.000 Einwohner
Das Wachstum sei mal 10% statt 5% pro Stunde, um das Ganze deutlicher zu machen.
Spieler 1 klickt nach einer Stunde: 110.000 Einwohner
Spieler 2 hat immer noch 100.000 Einwohner.
Noch eine Stunde spaeter klicken beide Spieler.
Spieler 1 bekommt wieder 10% dazu, aber eben von 110k und nicht von 100k.
Resultat?
Spieler 1 hat 121.000 Einwohner
Spieler 2 hat 120.000 Einwohner
Fazit: Durch eine Aktion mehr, 1000 Einwohner Vorsprung.
Macht man das nun nicht in Stunden-, sondern in Sekundenintervallen, maximiert man die Menge an Zinsen noch weiter.
-> Ergo Konzeptfehler.
gepostet vor 16 Jahre, 7 Monate von Todi42
Original von Kallisti
-> Ergo Konzeptfehler.

Ok, jetzt sehe ich, warum die eine Exponentielle Funktion genommen hast. Muss man ja aber nicht machen. n% legt das aber natürlich nahe ;-) Meisten ist solch ein Resourcenwachstum ja abhängig von irgend welchen Gebäuden und nicht von den Resourcen selber.

Auf diese Diskussion antworten