Je nach Stufe Wert pro Stunde erhöhen

Hallo Leute, da einem hier immer gut geholfen wird, ersuche ich euch erneut ;D

Ich habe ein kleines “Spiel” innerhalb einer Community. Dort kann man mit gesammelten Punkten Objekte kaufen die dann wieder Ehre bringen.
Nun ist es im Moment so, das es einmal diesen festgelegten Ehre Betrag beim kauf gibt.
Nun möchte ich aber, dass z.B. Obj1 die Ehre stündlich um 5 erhöht.
Wie löse ich das ohne Cronjobs?
Ich habe eine eigende table für Objekte schonmal erstellt, wo reingeschrieben wird wie viel ehre es die Stunde gibt, preis, name etc…
Der wert der Ehre jedes einzelen Users steht in der table users wo dann wohl definiert werden muss, welches Objekt er besitzt.

Ich hoffe ihr könnt mir Tipps für die umsetzung geben.

Mfg

Du speicherst den Timestamp der letzten Aktualisierung, prüfst dann bei jedem Aufruf den Sekundenunterschied zur letzten Aktualisierung, und rechnest dann floor($unterschied/(3600/$ehre_pro_stunde)); zur Ehre dazu.

Ich hoffe ich habe keinen Denkfehler eingebaut, aber so in etwa sollte das gehen.

Mfg :wink2:

Das ist so nicht gut, weil die Genauigkeit nicht ausreicht und dieses fließende Erhöhen auch nicht zielführend ist

$last_update = ...; //hole aus DB
$time = time();

$hours = floor(($time - $last_update)/3600);

if($hours >= 1)
{
  $last_update += $hours*3600; //speichere danach in DB
  //Aktualisiere Werte
}

Es scheint mir präziser zu sein, einmalig den absoluten Zeitnullpunkt
der ‘Ehrzeitrechnung’ festzulegen und abzuspeichern und dann bei
Bedarf über die Differenz der aktuellen Zeit zum Zeitnullpunkt
die aktuelle ‘Ehre’ zu berechnen (bei Bedarf auch mit geeigneter
Rundung für einen diskreten Anstieg - ist ja immer die Frage, was
welche Zahltypen mit ‘Ehre’ zu tun haben mögen - von der
Wortwahl wären ‘Treuepunkte’ vielleicht weniger bombastisch als
’Ehre’ ;o)

hoffmann: Dann bekommt man aber Probleme, wenn man mehr als nur ein Objekt hat, oder der Wert dieses Objektes wechselt. Man müsste bei jeder Änderung den Nullpunkt neu festlegen und die Berechnung dann dort weiterführen. So scheint mir das zielführender.

@‘Ehre’: Ehre ist hier ein Insider-Witz (“Ich wette tausend Ehre…”)

Danke ich werd mich jetzt mal hinsetzen und es mit michs lösung vorerst testen :wink:

Also jeder Nutzer hätte einen eigenen ‘Ehren-Nullpunkt’, ansonsten
ist da eine Redefinition ja kontraproduktiv, wenn der Wert stündlich
steigen soll. Die zur Redefinition benötigte Zeit reduziert ja die
Genauigkeit, daher ist es besser, den Nullpunkt nicht zu ändern.
Der Fehler der Nullpunktkorrektur kumuliert also mit jeder
Aktualisierung.
Wenn es neben der kontinuierlich steigenden ‘Ehre’ noch weitere
Werte gibt, würde man das eher in einen zeitabhängige Anteil und
einen aktionsabhängigen Teil zerlegen. Letzterer wird dann als
variabler Versatz berücksichtigt.
(Kann jemand auch ‘entehrt’ werden, indem ihm ‘Ehre’ wieder
abgezogen wird? ;o)

Was ähnliches kenne ich übrigens von Gehaltsabrechnungen, da gibt
es im öffentlichen Dienst auch Dienstalterstufen, im Jargon dann
eben der Greisenzuschlag, der alle zwei Jahre angehoben wird ;o)

Deswegen hab ich das auf genau festgelegte Intervalle (je eine Stunde) begrenzt. Damit fällt der Genauigkeitsverlust weg. :wink:

Öhm, nein, der Fehler wird dann jede Stunde beziehungsweise
wenn erst nach mehreren Stunden aktualisiert wird mit der
jeweiligen Aktualisierung immer weiter an. Das wird nicht gerade
viel sein, auch ist der Fehler nicht statistisch zufällig, der geht
systematisch zu einer Seite, das heißt jede Erhöhung erfolgt so
nach einer Stunde und einem kleinen, nicht genau bekannten
Zeitintervall. Über die Jahre bekommt so etwas weniger 'Ehre’
zusammen als angekündigt - würde mir zumindest bei meiner
Gehaltsabrechnung nicht gefallen, wenn sich mein Geburtstag
jedes Jahr um einen Tag verschieben würde, zu dem der
Greisenzuschlag erhöht wird ;o)

@hoffmann: Der Code von michi7x7 arbeitet exakt. Es wird als Updatezeitstempel nicht die aktuelle Zeit genommen, sondern es werden nur genau die bereits vollständig abgelaufenen Stunden dazugezählt, daher gibt es keinen Fehler im Zeitintervall.
Beispiel: Stündlich 5 Punkte
Zeit 0h: Updated = 0 , Ehre = 0
Zeit 1.5h -> Updated = 1, Ehre += (1-0) * 5 = 5
Zeit 1.8h -> Updated = 1, Ehre += (1-1) *5 = 5
Zeit 2.0h -> Updated = 2, Ehre += (2-1) * 5 = 10
Zeit 8.8h -> Updated = 8, Ehre += (8-2) *5 = 40

[quote=“progandy”]@hoffmann: Der Code von michi7x7 arbeitet exakt. Es wird als Updatezeitstempel nicht die aktuelle Zeit genommen, sondern es werden nur genau die bereits vollständig abgelaufenen Stunden dazugezählt, daher gibt es keinen Fehler im Zeitintervall.
Beispiel: Stündlich 5 Punkte
Zeit 0h: Updated = 0 , Ehre = 0
Zeit 1.5h -> Updated = 1, Ehre += (1-0) * 5 = 5
Zeit 1.8h -> Updated = 1, Ehre += (1-1) *5 = 5
Zeit 2.0h -> Updated = 2, Ehre += (2-1) * 5 = 10
Zeit 8.8h -> Updated = 8, Ehre += (8-2) *5 = 40
…[/quote]Viele Wege führen nach Rom :wink:

finds immer wieder erstaunlich, dass keiner die tollen 5.3 DateTime Geschichten verwendet
gut, bei massiver Nutzung spürt man’s an der Performance, dafür hat man keinen y2038 bug xD
find sie auch ziemlich handlich

zum problem:
mir ist nicht klar wie die Problemstellung aussieht
Kann man Ehre wieder verlieren?

Wenn nicht, dann einfach Nullpunkt auf Kaufdatum setzen und die Funktion ist dann sicherlich einfach (und hier auch schon diskutiert).
Ein Beispiel wäre das Zeitinterval durch 3600 zu teilen und abzurunden mal dem Ehre-Faktor.
Ich würde mir vom DateTime-Objekt die Stunden rausgeben, brauchst nix teilen und nix abrunden.
Kann man Ehre wieder verlieren musst du wohl den Nullpunkt nach einem Lauf aktualisieren.

Zu der Cronjobs-Frage: Dein Skript braucht die Daten ja nur wenn jemand die Daten braucht (klingt naiv, ist naiv aber ein wichtiger Gedanke). Setz ein Update an eine Stelle in deinem Spiel, sodass es auf jeden Fall ausgeführt wird bevor die aktuellen Daten benötigt werden. Z.B. direkt vor Abfrage der Ehre.
Du könntest das Update auch auf jeder oder vielen Seiten triggern aber nur ein Update pro Zeitinterval xy zulassen - in diesem Fall zu jeder vollen Stunde (?) (und anscheinend bei Kauf eines Objekts)

Ich hoffe ich bin am Ende nicht doch im falschen Fred gelandet und … was wollt ich eigentlich sagen?

PS: Auch bei “dynamischer” Ehre könntest du den Nullpunkt auf dem Kaufdatum lassen und ein Feld für “verbrauchte Ehre” hinzufügen und diese dann entsprechend von der kumulierten Ehre abziehen.
Wege gibts wohl ausreichend viele.

Holla ! :smiley:
Dachte nicht, dass noch eine solche Disskussion folgen wird :smiley:
Also ich habs im Moment so gelöst :wink:

$timeget=mysql_query("select ehre, lastupdate from user WHERE user = '".$_SESSION['user']."'");
$row1 = mysql_fetch_array($timeget);

$time = time();
$lastupdate = $row1['lastupdate'];
$ehre = $row1['ehre'];
$time=$time/3600;
$time = $time-$lastupdate;
$time=floor($time);
if($time >= 1)
{
$newtime = time();
$newtime = $newtime/3600;
mysql_query("UPDATE user Set lastupdate = '$newtime' WHERE user = '".$_SESSION['user']."'");
$newehre = $ehre + 5;
mysql_query("UPDATE user Set ehre = '$newehre' WHERE user = '".$_SESSION['user']."'");
echo "IF";
}else{
echo "else";}
?>

Die Echos sind/waren nur zum testen da ^^

Nun aber ein Problem.
Ich muss natürlich wissen, wie viele Stunden zwischen lastupdate und jetzt liegen und dann ja irgendwie in einer schleife den ehre wert erhöhen. Nur wie :slight_smile: ?

In meinem Code ist $hours genau die ganzzahlige Anzahl der Stunden, die gupdatet werden müssen.

Der neue Punktestand (?) ist demnach

$points += $hours * $points_per_hour;

die beiden mysql_query-Befehle lassen sich übrigens zusammenfassen.

@michi
!haue ich war heut zu lang im mathe unterricht -.- :smiley:

@progandy
stimmt schon, hatte das eben nur zum testen mit copy & paste gemacht :wink: :smiley:
Aber trotzdem danke für den Hinweis