anpera.net https://anpera.dyndns.org/phpbb3/ |
|
Fehler in Special nach Umschreibung auf "Switch" https://anpera.dyndns.org/phpbb3/viewtopic.php?f=34&t=5014 |
Seite 1 von 1 |
Autor: | Deus X Machina [ Mi 07 Okt, 2009 22:02 ] |
Betreff des Beitrags: | Fehler in Special nach Umschreibung auf "Switch" |
Ich hab zum rumprobieren und rumspielen bei mir die "findgem.php" um einen differenzierten Fall erweitert, das e_rand gegen ein mt_rand ausgetauscht. Und dann dachte ich mir: Anstatt $session['user']['gems'] mehrfach per "if" und "elseif" abzufragen müsste eine einmalige Abfrage und folgendes überprüfen per "switch" eigentlich Datenbank freundlicher sein (wenn mich das täuscht klärt mich bitte auf, lese mich erst nach und nach in alles ein) Leider funktionierte es dann nicht mehr so wie es sollte. Das Special löste nämlich dann, falls man 0 Gems hat den Fall 1 (1 Gem) aus - alle anderen Möglichkeiten funktionierten. Ich hab mir einiges über die Funktion "switch" durchgelesen, und hab rausgefunden woran es liegt - nur richtig verstehen tu ich es noch nicht, wäre nett wenn es mir jemand erklären könnte. Zur Erläuterung hier der Teil den ich hinzugefügt habe (im Original Script dann natürlich als eigenen Case): $this->bbcode_second_pass_code('', '$gemsnow = $session['user']['gems']; output("`^Eine Lichtfee schwirrt aus dem Wald an dich heran und fliegt neugierig um dich herum."); switch ($gemsnow){ case ($gemsnow<=0): default: output ("`n`^Nach kurzer Zeit fliegt sie weg und wirkt irgendwie etwas enttäuscht. Kurze Zeit später siehst du ein Leuchten im Wald. Als du hingehst siehst du die Fee an zwei Edelsteinen hängen die beginnen zu leuchten. Als du näher kommst flattert sie auf und nimmt dabei einen der Edelsteine mit an dem sie mit ihren klebrigen Fingern hängt. Den anderen steckst du ein und du gehst freudig zurück auf deinen Weg`0"); $session['user']['gems']++; break; case ($gemsnow==1): output ("`n`^Plötzlich fliegt sie an deinen Edelsteinbeutel, schmiegt sich daran und mit ihren klebrigen 4 Fingerchen jeder Hand hält sie sich daran fest. Du überlegst noch was du tun sollst als du bemerkst dass der Edelstein darin durch den Beutel hindurch zu leuchten beginnt. Immer heller wird er, und als du nachsehen willst was damit passiert und den Beutel öffnest zerreisst es ihn durch die viele Energie und die herumfliegenden Scherben zerschneiden dein Gesicht.`n Die Fee ist vor Schreck aufgeflogen und du siehst sie nicht mehr. Als du aber deine Wunden begutachtest kommt sie zurückgeflattert und wirkt furchtbar traurig. Als du die Splitter endlich aus dem Gesicht hast streicht sie dir über die Wunden und sie heilen. Es fällt dir schwer diesem Geschöpf wirklich böse zu sein. Als du deinen Weg forsetzt, und die Fee dir zum Abschied winkt ehe sie wirklich verschwindet, fühlst du dich durch ihre Behandlung und deine Einstellung etwas schöner. (Charme +1)`0"); if ($session['user']['gems']>0){$session['user']['gems']--;} $session['user']['charm']++; break; case ($gemsnow>=2): output ("`n`^Plötzlich fliegt sie an deinen Edelsteinbeutel, schmiegt sich daran und mit ihren klebrigen 4 Fingerchen jeder Hand hält sie sich daran fest. Du überlegst noch was du tun sollst als du bemerkst dass die Edelsteine durch den Beutel hindurch zu leuchten beginnen. Kurz darauf fliegt die Fee fröhlich glucksend wieder davon.`n Du holst die Edelsteine hervor und untersuchst sie. Sie leuchten immer noch, und du meinst auf einmal dass sie aufeinander reagieren. Als du noch am ausprobieren bist glaubst du ein Ziehen in eine Richtung zu spüren und nach kurzer Zeit findest du dort wirklich einen weiteren Edelstein. Bei all dem hast du aber einen Waldkampf verloren.`0"); $session['user']['gems']++; $session['user']['turns']--; break; }')ersetzt man die Zeile mit dem "switch" durch folgendes $this->bbcode_second_pass_code('', 'switch (true){') klappt es - die Lösung hab ich hier gefunden, im dritten Kommentar (von ukuser, 01 Aug. 2009). Wie gesagt, klappen tuts jetzt (bin während dem Schreiben des Posts draufgekommen (hab nochmal nachgelesen)), aber wenn mir wer helfen könnte es zu verstehen wär ich sehr dankbar ![]() |
Autor: | anpera [ Do 08 Okt, 2009 04:04 ] |
Betreff des Beitrags: | Re: Fehler in Special nach Umschreibung auf "Switch" |
Zunächst mal: Wenn du auf $session['user']['gems'] abfragst, finden keine Datenbankzugriffe statt. $sesson ist eine Variable im Speicher wie jede andere auch. Datenbankfreundlicher wird das Script durch den Umbau also nicht. Auch das Ersetzen von e_rand durch mt_rand solltest du nochmal checken, da e_rand eine andere Wahrscheinlichkeitsverteilung als mt_rand hat. Zu deinem switch-Problem: Das ist ein kleines Logik-Problem switch($gemsnow) - übergibt den Inhalt von $gemsnow an die folgenden case-Abschnitte; die case-Abfragen vergleichen mit $gemsnow. case($gemsnow<=1) macht nun folgendes: - Auswerten von "gemsnow<=1". Hier kommt entweder "true" oder "false" raus, niemals ein anderer Wert. - Wenn $gamesnow 0 ist, pasiert nichts, da wegen $gemsnow<=1 "true" nur nach case(1) abgefragt wird. - Wenn $gamesnow 1 ist, wird der folgende Code im case ausgeführt, da "true" zu case(1) führt. - Wenn $gamesnow größer 1 ist, passiert nichts, da auf case(0) abgefragt wird, und $gamesnow ja >1 ist. case($gemsnow==1) löst bei 0 und 1 Edelsteinen aus, weil die Abfrage 0 (false) ergibt, wenn $gemsnow ungleich 1 ist, und dadurch auf 0 prüft. Und wenn $gemsnow 1 ist, ergibt sie true (also 1) und löst ebenfalls aus. Alle andren Werte lösen nicht aus, da sie auf 0 ("false") geprüft werden. case($gemsnow>=2) wird niemals ausgeführt, weil 1 ("true") niemals größergleich 2 ($gemsnow) ist. Mit switch(true) wird jede der case-Abfragen mit dem Wert "true" (und nicht mit $gemsnow) verglichen - und deshalb funktioniert die Abfrage. Hmm.. zum Verständnis nochmal: $this->bbcode_second_pass_code('', 'switch($session['user']['gems']){ case(0): // Abfrage auf 0 Edelsteine Dein Code break; case(1): // Abfrage auf 1 Edelstein Dein Code break; default: // Jede andere Anzahl Edelsteine Dein Code break; }')...dürfte unter der Voraussetzung, dass man keine negativen Edelsteine haben kann, in etwa das selbe bewirken. |
Autor: | Deus X Machina [ Do 08 Okt, 2009 10:37 ] |
Betreff des Beitrags: | Re: Fehler in Special nach Umschreibung auf "Switch" |
Okay, das mit $session['user']['gems'] ist gut zu wissen, da hab ich wohl irgendwie was falsch verstanden... muss mich wohl halt nochmal durch den code graben... Naja bin selber schuld wenn ich Schlüsse ziehe ohne mich völlig auszukennen. Trotzdem dürfte "switch" besser sein als "if - elseif - else" - ist zumindest mein Schluss nach einiger Zeit Forum lesen, genau weiß ich darüber leider nichts und die Benchmarks die hier irgendwo im Forum verlinkt waren schweigen sich darüber aus. Danke für den Hinweis mit mt_rans und e_rand, aber das ist mir bekannt, deswegen wurde es ja ersetzt. Balancetechnisch wird das eventuell noch überarbeitet, aber für den Fall wollte ich erstmal dass alle Ereignisse gleich oft auftreten. Zum eigentlichen Problem: Bin leider nicht ganz schlau geworden aus dem geschriebenen, aber daraus und dem vorher gelesenen wär ich auf folgenden Schluss gekommen: Die Überprüfung $gemsnow<=0 ergibt bei, einem Wert von 0 oder weniger, dass es wahr ist. Folge = True. True entspricht aber bei der case Überprüfung der 1 (Da stand was im Thread der PHP Seite über "loose comparisons", das hatte ich nicht völlig verstanden) Also wird Fall 1 ausgelöst, daja TRUE = 1. Das kann es dann aber auch nicht ganz stimmen (meine Überlegung) ... Ich hatte beim ersten Versuch die "case" Ereignisse umgekehrt, hab mich vorhin dran erinnert, hab das nochmal ausprobiert. Folge: Falls $gemsnow 0 ist wird nicht case($gemsnow==1) ausgeführt, sondern der allererste Code, in dem Fall case($gemsnow>=2). Naja zumindest wird mir jetzt langsam klar dass ich Äpfel mit Birnen verglichen habe, das ist niemals gut. Naja daja switch ($gemsnow) nicht mit case Abfragen wie case(<=0) funktioniert bleibt switch(TRUE) und das funktioniert nicht nur, sondern ich versteh es inzwischen auch, und ich versteh auch WARUM das andere nicht funktioniert. Danke vielmals dafür ![]() case($gemsnow>=2) wurde übrigens ohne Problem auch dann ausgeführt, wenn es hätte eintreten sollen, also bei 2 oder mehr vorhandenen Edelsteinen. Deswegen blick ich zwar immer noch nicht ganz durch auf welche Weise es falsch funktioniert hat, aber ich denke vorerst kann ich darauf verzichten, ich muss ja nicht alles am Anfang durchschauen. |
Autor: | anpera [ Do 08 Okt, 2009 11:58 ] |
Betreff des Beitrags: | Re: Fehler in Special nach Umschreibung auf "Switch" |
Bau dein switch-case-Konstrukt doch mal zurück in eine if-Abfrage, dann wird der Fehler deutlich: $this->bbcode_second_pass_code('', 'switch($gemsnow){ case($gemsnow<=0): break;}') wird zu irgendwas wie: $this->bbcode_second_pass_code('', 'if ($gemsnow==($gemsnow<=0)){ }') wodurch die gewünschte Logik verloren geht. Du möchtest $this->bbcode_second_pass_code('', 'if ($gemsnow<=0){ }') und das wäre als switch-case: $this->bbcode_second_pass_code('', 'switch(true){ case($gemsnow<=0): break;') oder (wenn man davon ausgeht, dass $gemsnow ja nicht kleiner als 0 sein kann): $this->bbcode_second_pass_code('', 'switch($gemsnow){ case(0): break;') Nächster Fall, Entsprechungen farblich markiert: if ($gemsnow==1){...} switch($gemsnow){case(1):...break; |
Seite 1 von 1 | Alle Zeiten sind UTC + 1 Stunde |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |