PHP: 2-dim Arrays "ausschnittsweise" vergleichen

PHP, Ajax, CSS, HTML, Javascript
Eben für die wirklich Harten, die alles selber machen.
Antworten
Gichtus
Beiträge: 107
Registriert: Mi 21.Jan, 2004 23:13
Wohnort: Arnstadt

PHP: 2-dim Arrays "ausschnittsweise" vergleichen

Beitrag von Gichtus »

Am Besten fange ich mal am Anfang an ;) :

Es geht um das Ponder-Spiel. Dort gibt es 2 Arrays, die auf Gleichheit überprüft werden müssen.
Also ganz einfach ($array1 === $array2), oder?

Wenn der Spieler ein Feld anklickt, muss innerhalb des Skripts auf den Rand des Arrays überprüft werden, damit keine nichtexistenten Felder "erzeugt" werden. Das macht pro Klick bis zu 4 Tests (oben, unten, rechts, links). Die würde ich gerne weglassen.
Und zwar so: ich erzeuge Arrays, die am Rand eine zusätzliche Spalte/Reihe haben, welche aber nicht mit angezeigt werden. Dadurch ist es egal, ob der Spieler auf ein Randfeld klickt, weil Nachbarfelder existent sind.

Aufgrund des Spielprinzips ist allerdings nicht nur unvorhersehbar, wie die Ränder aussehen müssen, es ist auch völlig egal ;)
D.h.: ich muss mit 2 geschachtelten Schleifen jedes benötigte Feld auf "===" prüfen :(

Ich suche also eine Funktion, bzw. Konstrukt, die/das die Arrays innerhalb vorgegebener Rahmen vergleicht.
(und schneller ist, als die geschachtelten Schleifen)
Bild
Benutzeravatar
oxpus
Administrator
Beiträge: 28737
Registriert: Mo 27.Jan, 2003 22:13
Wohnort: Bad Wildungen
Kontaktdaten:

Beitrag von oxpus »

Wenn es hier "nur" um die Anzeige geht, warum dann die Schleifen dafür nicht mit einem um +1 erhöhten Startwert und um -1 verringertem Endwert laufen lassen?
Dann wäre das Array machbar, der User sieht den "Rand" nicht und Du kannst problemlos vergleichen.

Oder liege ich jetzt völlig daneben?
Nun, ohne den aktuellen Code ist sowas schwer zu beurteilen.
Karsten Ude
-={ Das Mädchen für alles }=-
Kein Support per Messenger, Email oder PN! Unaufgeforderte Nachrichten werden ignoriert!
No support per Messenger, Email or PM. Each unasked message will be ignored!
Gichtus
Beiträge: 107
Registriert: Mi 21.Jan, 2004 23:13
Wohnort: Arnstadt

Beitrag von Gichtus »

Das Anzeigen ist nicht das Problem. Das muss sowieso in Schleifen.
(Wenn es funktioniert, was ich mir denke, dann muss es nichtmal das... ;) )

Es geht um den Vergleich am Ende des Spiels, ob das Ziel erreicht wurde. (Gleichheit der sichtbaren Arrays)
Ich hatte gehofft, dass es eine Art "Maskierung" geben würde...
Aber vllt. schaffe ich das durch geschicktes "shiften" und/oder löschen.
z.B.: Oberste und unterste Reihe löschen, dann in den verbleibenden Reihen das erste und das letzte Feld löschen --> es bleiben nur die "wichtigen" Felder über.

Code (in PHP) gibts noch keinen, ich mache mir erstmal Sorgen um die Algorithmen ;)

Warum ich mir solche Gedanken mache:
-Warum nicht *g*
-evtl. gibts nen "Insane"-Level mit zb. 100x100 Feldern -> Laufzeit/CPU-Last
-Der AthlonXP verbraucht zuviel Saft, vllt. "zieht" der Server auf das gute alte Webpad mit MMX200 um...

Aber keine Angst, ich werde nicht mit jeder Kleinigkeit nerven *versprochen*
Bild
Benutzeravatar
oxpus
Administrator
Beiträge: 28737
Registriert: Mo 27.Jan, 2003 22:13
Wohnort: Bad Wildungen
Kontaktdaten:

Beitrag von oxpus »

:l2:
Ich hab jetzt auch alles verstanden, ehrlich...
Karsten Ude
-={ Das Mädchen für alles }=-
Kein Support per Messenger, Email oder PN! Unaufgeforderte Nachrichten werden ignoriert!
No support per Messenger, Email or PM. Each unasked message will be ignored!
Gichtus
Beiträge: 107
Registriert: Mi 21.Jan, 2004 23:13
Wohnort: Arnstadt

Beitrag von Gichtus »

http://phponder.scmar.de ;)

^pre-alpha-Status *g*

PHP ist SEHR seltsam:
lt. meinem Buch und div. PHP-Tuts werden Variablen automatisch deklariert. So auch Arrays.
Also: Man weisst einem Element einen Wert zu, und schon existiert es. Bei 2-dim-Arrays scheint das nicht ganz zu stimmen.

Um wieder zum o.g. Problem zu kommen:

Ich möchte ein Array, welches z.b. die Aussmasse 3x3 hat. Das "Definiere" ich per Schleifen:

Code: Alles auswählen

for ( $i=0; $i<3; $i++ )
    {
    for ( $j=0; $j<3; $j++ )
      {
      $ist[$i][$j]=0;
      }
    }
Wenn ein Feld im Spiel aktiviert wird, müssen die Nachbarfelder geprüft und ggf 1 erhöht werden.
Ich will allerdings nicht jedesmal prüfen, ob sich das aktivierte Feld am Rand oder in der Ecke befindet, also wird pauschal in allen 4 Richtungen erhöht.

Im Endeffekt müsste sich also folgendes Array ergeben:

Code: Alles auswählen

01110
12221
12221
12221
01110
wobei:
-0: nie angesprochen (also auch nicht im Array)
-1: "Ausversehen" angesprochen (also nicht Spielentscheidend)
-2: gehört zum Spielfeld

Aber so sieht das Feld mit print_r() aus:

Code: Alles auswählen

[0] => Array
        (
            [0] => 2
            [1] => 2
            [2] => 2
        )

    [1] => Array
        (
            [0] => 2
            [1] => 2
            [2] => 2
        )

    [2] => Array
        (
            [0] => 2
            [1] => 2
            [2] => 2
        )
Nicht, das ich was dagegen hätte (das macht den Vergleich ist==soll leichter), aber ist das sowas wie ein "Feature" ?
Bild
Benutzeravatar
oxpus
Administrator
Beiträge: 28737
Registriert: Mo 27.Jan, 2003 22:13
Wohnort: Bad Wildungen
Kontaktdaten:

Beitrag von oxpus »

Arrays sollten alleine aus Sicherheitsgründen schon deklariert werden, bevor mal sie erstellt. Also ein kurzes $variable = array(); reicht ja.
Und nein, das ist kein Feature, eher ein Fehler.
Nach Deinem Beispiel der verschachtelten Schleife dürfte überall nur "0" enthalten sein. Oder ist das wirklich nur ein Beispiel?
Karsten Ude
-={ Das Mädchen für alles }=-
Kein Support per Messenger, Email oder PN! Unaufgeforderte Nachrichten werden ignoriert!
No support per Messenger, Email or PM. Each unasked message will be ignored!
Gichtus
Beiträge: 107
Registriert: Mi 21.Jan, 2004 23:13
Wohnort: Arnstadt

Beitrag von Gichtus »

$soll=array();
$ist=array();

natürlich mit drin, alte gewohnheit ;)
Die Verschachtelte Schleife wird danach ausgeführt (ich mag Variablen nicht, bei denen ich keinen Startwert kenne...besonders bei ++ )

Der letzte Codeausschnitt ist das Ergebnis, nachdem das Spiel beendet wurde (nur die Inhalte auf "2" geändert)

/e: der "Server" laggt bissel...sry
/e2: hab meinen Denkfehler gefunden *glaub*, wenn gewünscht, kann ich Erklärung nachreichen ;)
Zuletzt geändert von Gichtus am Fr 25.Feb, 2005 01:11, insgesamt 3-mal geändert.
Bild
Benutzeravatar
oxpus
Administrator
Beiträge: 28737
Registriert: Mo 27.Jan, 2003 22:13
Wohnort: Bad Wildungen
Kontaktdaten:

Beitrag von oxpus »

Ja, bitte erkläre was Du gefunden hast.
Karsten Ude
-={ Das Mädchen für alles }=-
Kein Support per Messenger, Email oder PN! Unaufgeforderte Nachrichten werden ignoriert!
No support per Messenger, Email or PM. Each unasked message will be ignored!
Gichtus
Beiträge: 107
Registriert: Mi 21.Jan, 2004 23:13
Wohnort: Arnstadt

Beitrag von Gichtus »

k...so langsam geht auch die Beule vom "Kopf->Tisch" wieder weg ;)

Was mich "verworren" hat, ist diese automatische Feldgenerierung bei Arrays. Dieses Konzept ist mir irgendwie neu. Ich bin gewohnt, Variablen zu Beginn zu definieren. (Name, Typ, evtl. Inhalt ...) Was nicht definiert ist, gibts nicht - inklusive nicht definierter Arrayfelder.

Nun zu PHP: Ich hatte es fälschlicherweise so Verstanden: Arrayfelder werden beim Zugriff generiert (sowas wie "touch()"). Um zu Prüfen, OB ein Feld existiert gibt es schliesslich isset().

Code: Alles auswählen

 if ( $ist[($i-1)][$j]>0 ) 
    {
    $ist[($i-1)][$j]++;
 usw.
Das ist eine fragliche Stelle. Wenn man auf ein uninitialisiertes Feld zugreift, gibt PHP wahrscheinlich FALSE zurück.
Dank der loosly Types ist das dummerweise ==0 ....

G
Bild
Benutzeravatar
oxpus
Administrator
Beiträge: 28737
Registriert: Mo 27.Jan, 2003 22:13
Wohnort: Bad Wildungen
Kontaktdaten:

Beitrag von oxpus »

Dank der loosly Types ist das dummerweise ==0 ....
Sofern man damit gleich rechnet, ansonsten eben empty() oder == ''
Karsten Ude
-={ Das Mädchen für alles }=-
Kein Support per Messenger, Email oder PN! Unaufgeforderte Nachrichten werden ignoriert!
No support per Messenger, Email or PM. Each unasked message will be ignored!
Gichtus
Beiträge: 107
Registriert: Mi 21.Jan, 2004 23:13
Wohnort: Arnstadt

Beitrag von Gichtus »

ich häng das Teil einfach mal an.
Bild
Benutzeravatar
oxpus
Administrator
Beiträge: 28737
Registriert: Mo 27.Jan, 2003 22:13
Wohnort: Bad Wildungen
Kontaktdaten:

Beitrag von oxpus »

:l2
-Highscore (ich hab vor nichts mehr Bammel, als vor Usereingaben) :(
Der ist gut. Ist doch wirklich eins der einfacheren Dinge...
Ich scheitere da eher an der Komplexität der Spielfeldberechnung...
Karsten Ude
-={ Das Mädchen für alles }=-
Kein Support per Messenger, Email oder PN! Unaufgeforderte Nachrichten werden ignoriert!
No support per Messenger, Email or PM. Each unasked message will be ignored!
Gichtus
Beiträge: 107
Registriert: Mi 21.Jan, 2004 23:13
Wohnort: Arnstadt

Beitrag von Gichtus »

Spielfeldberechnung:

In der alten Version (bash) hab ich mir das sehr einfach gemacht: Das "Script" hat solange zufällig auf das Feld gehämmert, bis alle Felder belegt waren. D.h.: bei einem Spielfeld von 10x10 wurden für das letzte Feld im Schnitt 100 Versuche gebraucht.
In dieser Version gibt es einen Zähler, der die leeren Felder als Wert hat.
Es wird ein Zufallswert generiert, dessen Bereich von 1 bis "leere Felder". Dann werden in den beiden inneren Schleifen die leeren Felder gezählt. Solange, bis der Zufallswert ereicht ist. Dort "drückt" der Computer dann den Knopf. -> für jedes Feld wird _ein_ "Versuch" benötigt.
btw.: in der neuen Version ist das rechts/oben/unten/links in eine Schleife gewandert, das spart Quelltext und Übersichtlichkeit ;)

Highscore/Benutzereingaben:

Die Datei, in der diese Sachen gespeichert werden sollen, muss von Apache les/schreibbar sein. Das Dumme, man kann sie auch durch direkten Aufruf auslesen. Wenn ich das nicht will (Highscore ist relativ egal, aber bei Counter o.ä. schon kritischer), schlägt ein Buch vor, die Datei .php zu nennen, damit sie durch den Parser gejagt wird. Das gibt zwar Fehler, aber Inhalt der Datei wird nicht angezeigt. Wenn aber jemand das weiss, könnte er durch geschicktes Spielen Quelltext in dieser Datei unterbringen, der dann doch ausgeführt wird.
Es gibt zwar addslashes() und strip_tags(), aber es gibt sicher Möglichkeiten, sowas auszuhebeln


MfG, der paranoiker G
Bild
Benutzeravatar
oxpus
Administrator
Beiträge: 28737
Registriert: Mo 27.Jan, 2003 22:13
Wohnort: Bad Wildungen
Kontaktdaten:

Beitrag von oxpus »

Man kann sowas auch mit "Gewalt" unberechenbar machen. So wie zerlegen eines Strings in einzelne Chars mit Semilokon getrennt.
Nur ein Beispiel von vielen.
Und dennoch steige ich durch die Spielfeldberechnung nicht durch. Die komplexe Logik dahinter ist leider nicht so ganz meine Welt. Daher sind meine Mods auch eher einfach und damit u.U. langsam gestrickt.
Karsten Ude
-={ Das Mädchen für alles }=-
Kein Support per Messenger, Email oder PN! Unaufgeforderte Nachrichten werden ignoriert!
No support per Messenger, Email or PM. Each unasked message will be ignored!
Antworten