Einfaches Tic-Tac-Toe PHP / Pure HTML

12124
Eldros

Ich habe ein einfaches Tic-Tac-Toe mit PHP gemacht und nur HTML-Code generiert.

Ein paar Anmerkungen:

  • Ich habe mir noch nicht die Mühe gemacht, den Gegnern (den Os) eine KI zu geben, und das ist beabsichtigt.
  • Es gibt keinen CSS-Stil, ich möchte ihn mit einer CSS-Datei anhängen.
  • tictactoe.php ist natürlich der Name des Skripts selbst, daher beziehen sich alle Links auf die Seite selbst.

Jetzt weiß ich nicht, ob ich alles richtig gemacht habe, hier sind meine Sorgen:

  • Wenn ich die Funktionen des Spiels in der Zukunft erweitern möchte (Hinzufügen von Javascript, gegnerischen AIs, neue Spielfunktionen), befürchte ich, dass die Struktur des Codes nicht dafür angepasst ist. Soll ich meinen Code ändern, damit er objektorientiert ist? BEARBEITEN Ich habe vor, dem Spiel neue Funktionen hinzuzufügen, wie z. B. Kräfte, die den Status des Bretts ändern würden, wie zum Zurückspulen in einen vorherigen Zustand und; Einige CSS und Javascript in einer nicht aufdringlichen Weise und fügen Sie eine Möglichkeit hinzu, um zu überprüfen, ob Optionen deaktiviert sind (z. B. Javascript / Flash), oder überprüfen Sie die Version des Browsers auf HTML5 / css3-Funktionen.
  • Momentan ist es einfach, den gewünschten Board-Status zu "betrügen" und direkt einzuführen. Ich möchte das verhindern und möglichst ohne Javascript, da ich möchte, dass das Spiel auch ohne es spielbar ist.
<table>
<?php
//Determine if a player as aligned three of its symbols and return the id of the player (1
//for X Player, -1 for O Player(Computer)). Otherwise return 0;
function isWinState($board){
    $winning_sequences = '012345678036147258048642';
    for($i=0;$i<=21;$i+=3){
        $player = $board[$winning_sequences[$i]];
        if($player == $board[$winning_sequences[$i+1]]){
            if($player == $board[$winning_sequences[$i+2]]){
                if($player!=0){
                    return $player;
                }
            } 
        }   
    }
    return 0;
}

//Player O plays its turn at random
function OsTurn($board){
    if(in_array(0,$board)){
        $i = mt_rand(0,8);
        while($board[$i]!=0){
            $i = mt_rand(0,8);
        }
        $board[$i]=-1;
    }
    return $board;
}

$winstate = 0;
$values = array();

if(empty($_GET['values'])){
    //initializing the board
    $values = array_fill(0,9,0);
    //determine who begins at random
    if(mt_rand(0,1)){
        $values = OsTurn($values);
    }
}else{
    //get the board
    $values = explode(',',$_GET['values']);
    //Check if a player X won, if not, player 0 plays its turn.
    $winstate = isWinState($values);
    if($winstate==0){
        $values = OsTurn($values);
    }
    //Check if a player 0 won
    $winstate = isWinState($values);    
}
//Display the board as a table
for($i=0;$i<9;$i++){
    //begin of a row
    if(fmod($i,3)==0){echo '<tr>';}
    echo '<td>';
    //representation of the player token, depending on the ID
    if($values[$i]==1){
        echo 'X';
    }else if($values[$i]==-1){
        echo 'O';
    }else{
        //If noone put a token on this, and if noone won, make a link to allow player X to
        //put its token here. Otherwise, empty space.
        if($winstate==0){
            $values_link = $values;
            $values_link[$i]=1;
            echo '<a href="tictactoe.php?values='.implode(',',$values_link).'">&nbsp;</a>';
        }else{
            echo '&nbsp;';
        }
    }
    echo '</td>';
    //end of a row
    if(fmod($i,3)==2){echo '</tr>';}
}
?>
</table>
<?php
//If someone won, display the message
if($winstate!=0){
    echo '<p><b>Player '.(($winstate==1)?'X':'O').' won!</b></p>';
}
?>
Antworten
12
Bringt Erinnerungen zurück - TTT war eines der ersten Spiele, die ich in C. gebaut habe. Michael K vor 10 Jahren 4

1 Antwort auf die Frage

8
Michael K

Es gibt keinen Grund, dies "objektorientierter" zu machen, wenn Sie es nicht brauchen. So können Sie beispielsweise weitere AI-Konstrukte hinzufügen:

switch ($aiLevel) {
   case 1: $values = $OsTurn($values);
   case 2: $values = $betterAi($values);
   case 3: $values = $unbeatableAi($values);
}

Weitere Funktionen können auf ähnliche Weise hinzugefügt werden. Ich bin mir nicht genau sicher, was Sie vorhaben, daher kann ich nur einige allgemeine Anmerkungen machen. Unterteilen Sie alles in Funktionen und stellen Sie sicher, dass der Ablauf des Programms leicht zu erkennen ist. Die Art und Weise, wie Sie Ihren Code strukturiert haben, ist gut. Es ist nicht schwierig, weitere Funktionen hinzuzufügen, wenn Sie einen ähnlichen Stil verwenden.

CSS wirkt sich nicht auf Ihr Skript aus. es ändert sich einfach, wie die Seite aussieht. Sie müssen nur sicherstellen, dass Sie bei der Ausgabe von HTML die richtigen Elemente verwenden. Javascript ist möglicherweise komplizierter, aber es gibt viele Möglichkeiten, dies zu tun, einschließlich Formularelementen (möglicherweise ausgeblendet) und Seitenübergaben. Es gibt andere Möglichkeiten, die mir nicht bewusst sind, da ich nicht in erster Linie ein Webprogrammierer bin.

Ich glaube, wenn Sie über Betrug sprechen, sagen Sie, dass Sie einen überzeugenden Boardwertsatz an das Skript senden können, indem Sie die URL selbst eingeben. Um dies zu verhindern, benötigen Sie eine Möglichkeit, den Zustand zu erhalten. Ein Cookie wäre ein einfacher Start. Speichern Sie den aktuellen Status der Karte nach jedem Seitenaufruf darin, und überprüfen Sie, ob die einzige Änderung die Platzierung eines anderen Elements ist. Eine robustere, aber etwas umständlichere Lösung wäre die Verwendung von Sitzungsvariablen zum Speichern des Zustands. Dies würde das Problem der "cookys are bad" und die Möglichkeit vermeiden, dass jemand das cooky fälscht!

In meinem Kommentar finden Sie genaue Angaben dazu, was ich vorhabe. Muss ich auch ein Cookie verwenden? Ich habe eine abergläubische "Angst" vor Cookies (die Besprechung, ob Cookies böse sind, gehört Programmierern.se, also werde ich nachsehen), aber könnte ich mit Session-Variablen nicht ein ähnliches Ergebnis erzielen? Eldros vor 10 Jahren 0
Ja du könntest. Das wäre wahrscheinlich auch eine bessere Lösung. Michael K vor 10 Jahren 0
Eine andere Frage, ich hatte immer den Eindruck, dass man nur effektiven Unit-Test mit OO-Code durchführen kann. Aber wenn ich mich irre, was wäre der Unit-Test, den Sie mit einem solchen Code machen würden? Ich habe daran gedacht, ein Gewinnbrett zu testen, vor allem eines, bei dem vor der Gewinnlinie eine leere Linie geprüft wurde, aber es ist sicherlich noch mehr dabei. Sollte diese Frage dem OP hinzufügen? Oder sollte ich diese eigene Frage stellen? Eldros vor 10 Jahren 0
Nein, Sie benötigen keine OO für den Komponententest. In vielerlei Hinsicht ist direkter Verfahrenscode einfacher - es gibt oft weniger Abhängigkeiten, so dass Sie nicht so viel Spaß machen müssen. Wie Sie es testen können, können alle Ihre nicht druckbaren Funktionen getestet werden. Sie haben ein Beispiel zum Testen von `isWinState ()` gegeben; Dasselbe könnte auf `OsTurn ()` angewendet werden. Das funktioniert natürlich nur bei einer deterministischen KI. Michael K vor 10 Jahren 0