Logik-Problem: Ineinander verschachtelte Funktionen (PHP)

d3mueller

Mitglied
Hi,

also zum allgemeinen. Ich Programmierer mein erstes Browsergame. Einfach zum Spaß :). Dabei habe ich schon unglaublich viel gelernt, was ich in Büchern und alles nie gelernt hätte. Zum Einsatz kommt natürlich hauptsächlich PHP zum Berechnen. Und halt das "Webseitenstandardzeugs" wie HTML,CSS,Javascript....

auf jeden Fall stehe ich gerade wieder vor einem Problem. Darüber grüble ich schon seit Tagen, weiß aber nicht, wie ich es lösen kann.

Ich kann auch keinen Code posten, da das Problem eher ein Logik-Problem ist, und ich glaube, dass ein Code-Snippet nicht hilfreich wäre. Weil mir auch kein Teil im Code einfällt, bei dem exakt das Problem liegt. (teilweise existiert de Code für das Problem ja noch nicht, bzw. ist veraltet)


Also etwas zum Prinzip des Browsergames.

Es gibt Tore, mit denen man zu anderen Welten gehen kann. (Entweder sind dort andere Spieler oder ne KI). Damit es realistischer ist, simuliere ich genau das Verbinden der Tore. Also wenn ein Tor A zu Tor B führt, dann kann Tor C nicht zur Gleichen Zeit Tor A oder B anwählen. Und das eben alles genau berechnet etc.

Jetzt kann man Leute durch das Tor schicken, um die andere Welt zu erkunden/bekämpfen/...
Dazu habe ich eben ein Modul entwickelt, was die Missionen rundenbasiert berechnet, aber es dem Spieler nicht als rundenbasiert anzeigt, sondern etwas realistischer. Also die merken nicht, wann eine Runde vorbei ist oder so. Das ist nur intern zum berechnen.

Diese einzelnen Runden haben einen "trigger", wann die nächste Runde ausgeführt wird. Das ist wichtig, weil wenn jemand um 10:00 Uhr morgens eine Mission dauert und die Seite erst um 18:00 Uhr neulädt, soll die Mission ja trotzdem um 10:00 Uhr ausgeführt worden sein. Weil das wird nicht über Cronjobs berechnet, sondern immer nur dann, wenn der Spieler die Seite neulädt. Dann wird rückwirkend alles notwendige berechnet. Und eben nur das, was gerade benötigt wird.

Daraus ergibt sich ein Problem, wenn mehrere Spieler interagieren. Wenn Spieler A um 10:00 Uhr eine Mission startet und Tor A aktiviert, und dann Spieler B um 10:01 Uhr versucht, das Tor A zu erreichen, muss das Skript ja dann die Mission von Spieler A berechnen, damit das Tor A korrekterweise gerade nicht angewählt werden kann (weil es con Spieler A benutzt wird).



Soweit so gut. Das ist ja noch machbar, in dem man jedes Mal, wenn man ein Tor anwählt, einfach alle Missionen des Tor-Besitzers durchrechnen lässt.


Jetzt habe ich allerdings folgendes Problem:

Ich habe eine Funktion, die alle aktiven Missionen von einem Spieler oder alle aktiven Missionen zu/von einem bestimmten Tor berechnet.

Diese geht also in der Datenbank alle gerade aktiven Missionen durch und führt die Runden aus, bis der "trigger" schließlich in der Zukunft liegt.

Für jede Mission gibt es eine eigene Funktion (z.B. Funktion erforschen() ), die eben die Runden berechnet. Und in jeder Mission gibt es eine Runde, in der das Tor des Spieler aktiviert werden muss, damit die Leute auf eine andere Welt gehen können.

Bevor das Tor aber aktiviert werden kann, müssen ja alle Missionen berechnet werden, die von dem Tor wegführen, und alle die dort hinführen. Das geht ja nicht anders.

Aber wenn diese Missionen berechnet werden, dann werden dort ja auch Tore aktiviert, wodurch wieder alle Missionen erst berechnet werden müssen. Und hier komme ich nicht mehr weiter.

wie kann man das richtig berechnen, dass er die Missionen logisch durchrechnet und nicht in eine Endlosschleife gerät?


Hat jemand eine Idee?

Ich hoffe, ihr versteht mein Problem. Ist ziemlich schwer zu formulieren, und ich bin mir selbst noch nicht sicher, ob das der Kern des Problems ist. Wüsste aber nicht, wie man das anders formulieren könnte.

Viele Grüße,
Dennis
 

alxy

Erfahrenes Mitglied
Ich versteh das Problem nicht :D
Generell solltest du vielleicht eher mit cronjobs arbeiten um den Rechenaufwand pro Aktion zu kürzen.

So und nun tatsächlich zu dem was ich verstanden habe. Du legst fest Tor A führt in einer gewissen Zeit (10:00 bis 11:00) zu Tor B, danach wird die Belegung geändert? Erste Frage: Führt B dann auch zu A?
Warum musst du alle Missionen durchrechnen die dann zu Tor A führen? oder weggehen?
 

d3mueller

Mitglied
:D ja, tut mir Leid, dass es etwas komisch geschrieben ist. Ich weiß selber nicht, wie man das Problem richtig formuliert. Ist einfach ziemlich schwer :D

Zu den Conjobs: Ich hab halt keinen eigenen Server oder so. Ich hab nen Cronjob, der jede Stunde läuft (von cronjob.de), um die Ressourcen zu erhöhen

Ich hab halt keine Möglichkeit, dynamisch irgendwelche Cronjobs zu erstellen (also dass sich automatisch ein Cronjob bei der "trigger"-Zeit aktiviert und die Runde berechnet). das kann ich nicht. (oder gibt es da einen Weg, ohne eigenen Server?). Mit Cronjobs wäre das glaube ich erheblich leichter, aber ich weiß nicht, wie ich das umsetzen kann. (Es würde glaube ich aber mein Logik-Problem lösen, weil das nachträgliche Berechnen und so einfach wegfallen würde).


---

Genau, für eine Stunde (in dem Beispiel jetzt). Nein, man kommt nicht von B zu A.

Warum ich die durchrechnen muss: Ja, da wird das ganze etwas komplexer^^

Also man hat drei Spieler. Spieler A,B und C.

Jeder hat ein Tor (A,B und C)

Spieler A startet um 10:00 Uhr eine Mission. Wenn man jetzt in die Spielwelt "eintaucht", dann wird das Tor demnach um 10:00 Uhr geöffnet (Zieltor sei hier Tor B von Spieler B) und ist bis exakt 11:00 Uhr offen. In dieser Spielwelt ist es dann quasi automatisch so, dass Spieler C weder eine Verbindung zu Tor A, noch zu Tor B aufbauen kann, weil beide Tore ja aktiviert sind zwischen 10:00 Uhr und 11:00 Uhr.

Aber dieses Aktivieren der Tore, erfolgt ja erst beim berechnen der Mission. Das heißt, wenn Spieler A die Seite dann erst um 10:30 Uhr neu aufruft, dann wird auch erst um 10:30 Uhr nachträglich auf aktiv gesetzt. Und dann wird in die Datenbank eingetragen, dass das Tor schon seit 10:00 Uhr aktiv war.

Aber was, wenn Spieler C um 10:20 Uhr versucht, mit Tor A zu verbinden? Zu der Zeit, hat Spieler A ja noch nicht die Seite neugeladen, und somit steht das Tor noch nicht auf aktiv, obwohl es eigentlich in dieser spielwelt schon aktiv sein müsste.

Deswegen muss Spieler C, wenn er Tor A anwählt, die Missionen von Spieler A berechnen (und von allen anderen Spielern, die auch versuchen, mit Tor A zu verbinden), damit das Tor auch auf aktiv gesetzt wird, wie es sein sollte.


Ist es so leichter zu verstehen? :D
 

Spyke

Premium-User
Andere idee.
Ev. die missionen sofort berechnen, sichtbar muss das ergebnis ja nur ab nem bestimmtem zeitpunkt sein.
Die verwendeten ressourcen wären ja ab start der mission nicht mehr verfügbar, wodurch dort eine "doppelverwendung nicht eintretten dürfte.
Und für die sperrung des tores könnt man ja einfach nen zeitstempel setzen.
 

d3mueller

Mitglied
Das mit dem Sofort-berechnen ist eine gute Idee! :)

Wie meinst du das mit den Zeitstempel? So, dass man z.B. ne Tabelle hat und dort steht, von wan bis wann das Tor offen iss (und auch Zukunftswerte dort einträgt)? Und man bei jedem Aktivierungsversuch, da nach schaut? Oder meinst du das anders?

Edit: Aber eine Sache ist mir grad noch eingefallen.

Wenn alles sofort berechnet wird, dann könnte es aber auch unrealistisch sein. Wenn zum Beispiel während der Mission ein zweiter Spieler auf den Planeten geht, dann kann man das nicht miteinbeziehen, wie man die Mission ja schon längst komplett berechnet hat.


EDIT 2:

Gerade ist mir eine mögliche Lösung in den Sinn gekommen. Ich weiß nur nicht, ob ich da drin irgendwo einen Fehler habe. Es ist irgendwie zu einfach^^

Folgendes: die Funktion, die die Missionen berechnet holt sich ja alle aktiven Missionen und berechnet die. Jetzt könnten die ja einfach nach "trigger" sortiert werden. Also der trigger, der am weitesten in der Vergangenheit liegt, kommt zuerst und dann aufsteigend.

Wenn jetzt nämlich in einer Mission das Tor aktiviert werden muss, kann man sich beim aktivieren des Tores sparen, nochmal die Missionen durchzurechnen(was ja dann diese Endlosschleife hervorbringt). Weil alle entscheidenden Runden der Missionen (die, die vorher passiert sind) wurden ja schon berechnet. Oder? Weil die Runden, die in der Zukunft liegen, sind ja egal.

Also muss man nur die Sortierung richtig einstellen und dann beim aktivieren des Tores einfach nicht die Funktion zum checken der Missionen starten. Oder?
 
Zuletzt bearbeitet: