Jeu du morpion intelligent: humain versus php

Soyez le premier à donner votre avis sur cette source.

Vue 17 879 fois - Téléchargée 1 793 fois

Description

Jouez en ligne au jeu du morpion contre l'ordinateur.
Personnalisez le niveau.
Présence d'un mode invincible (corrigé 1 fois).
Gestion des points.

Mais surtout, amusez-vous bien !

Source / Exemple :


<?php

//======================================= http://altert.family.free.fr/ ========

  $BackGroundColor = "#F8F8F8";
  $ActiveCellColor = "yellow";

//------------------------------------------------------------------------------

  function GetGet($Value,$DefaultValue) {
  //INFO: l'utilisation de HTMLSPECIALCHARS évite les trous de sécurité du type
  //      http://localhost/morpion.php?game=100020010&level=2&serverpts=<script>alert("Salut");</script>&playerpts=0
    if (isset($_GET[$Value])) {
      if ($_GET[$Value]=='')
        return $DefaultValue;
      else
        return htmlspecialchars($_GET[$Value]);
    } else
      return $DefaultValue;
  }

  function HasChar($Text,$Char) {
    $HasC = false;
    for ($i=0 ; $i<strlen($Text) ; $i++)
      if ($Text[$i]==$Char) {
        $HasC = true;
        break;
      }
    return $HasC;
  }

//------------------------------------------------------------------------------

  $DisallowLinks = false;
  $WinningPosition = -1;
  $ServerPoints = GetGet('serverpts',0);
  $PlayerPoints = GetGet('playerpts',0);
  $Grid = GetGet('game','000000000');
  $Level = GetGet('level','1');              //par défaut, le moteur est "Intermédiaire"

//------------------------------------------------------------------------------

  function Full3($P1,$P2,$P3) {
  //Indique si 3 cases spécifiées sont occupées par le même signe
    global $Grid;
    return ($Grid[$P1]!='0' && $Grid[$P1]==$Grid[$P2] && $Grid[$P2]==$Grid[$P3]);
  }

  function CheckWin() {
  //0-1-2
  //3-4-5
  //6-7-8
    global $Grid;
    return ( Full3(0,3,6) || Full3(1,4,7) || Full3(2,5,8) ||     //Verticales
             Full3(0,1,2) || Full3(3,4,5) || Full3(6,7,8) ||     //Horizontales
             Full3(0,4,8) || Full3(2,4,6)      );                //Diagonales
  }

  function EchoTab($Index) {
    global $Grid, $DisallowLinks, $Level, $ServerPoints, $PlayerPoints;
    if (!HasChar($Grid,'0')) {
      echo '<a class=link href="morpion.php?level='.$Level.'&serverpts='.$ServerPoints.'&playerpts='.$PlayerPoints.'">';
      if ($Grid[$Index]=='1')
        echo '<img src="croix.gif" alt="Cliquez pour recommencer">';
      else
        echo '<img src="cercle.gif" alt="Cliquez pour recommencer">';
      echo '</a>';
    } else {
      switch ($Grid[$Index]) {
        case '0':
            $CurGrid = $Grid;
            $CurGrid[$Index] = '1';
            if ($DisallowLinks)
              echo '<img src="blank.gif" border="0">';
            else
              echo '<a href="morpion.php?game='.$CurGrid.'&level='.$Level.'&serverpts='.$ServerPoints.'&playerpts='.$PlayerPoints.'"><img src="blank.gif" border="0"></a>';
          break;
        case '1':
            echo '<img src="croix.gif">';
          break;
        case '2':
            echo '<img src="cercle.gif">';
          break;
      }
    }
  }

  function GetCellColor($Cell,$EchoSth) {
  //0-1-2
  //3-4-5
  //6-7-8
    global $BackGroundColor, $ActiveCellColor, $WinningPosition;

  //Recherche de la condition de coloration
    switch ($Cell) {
      case 0: $CellBG = Full3(0,1,2) || Full3(0,3,6) || Full3(0,4,8);                  break;
      case 1: $CellBG = Full3(0,1,2) || Full3(1,4,7);                                  break;
      case 2: $CellBG = Full3(0,1,2) || Full3(2,5,8) || Full3(2,4,6);                  break;
      case 3: $CellBG = Full3(3,4,5) || Full3(0,3,6);                                  break;
      case 4: $CellBG = Full3(3,4,5) || Full3(1,4,7) || Full3(0,4,8) || Full3(2,4,6);  break;
      case 5: $CellBG = Full3(3,4,5) || Full3(2,5,8);                                  break;
      case 6: $CellBG = Full3(6,7,8) || Full3(0,3,6) || Full3(2,4,6);                  break;
      case 7: $CellBG = Full3(6,7,8) || Full3(1,4,7);                                  break;
      case 8: $CellBG = Full3(6,7,8) || Full3(2,5,8) || Full3(0,4,8);                  break;
    }

  //Application de la couleur
    if ($CellBG) {
      $WinningPosition = $Cell;
      if ($EchoSth)
        echo $ActiveCellColor;
    } else
      if ($EchoSth)
        echo $BackGroundColor;
  }

//------------------------------------------------------------------------------

/*
  INFORMATIONS GENERALES
     Joueur '0' = personne
     Joueur '1' = internaute
     Joueur '2' = serveur

  • /
function Computing() { global $Grid, $Level; $Buffer = $Grid; $Choix = -1; $Symetrical = (($Level>=2) && ($Grid=='100010002' || $Grid=='200010001' || $Grid=='001010200' || $Grid=='002010100')); //Recherche d'une position immédiatement gagnante for ($i=0 ; $i<9 ; $i++) { $Grid = $Buffer; if ($Grid[$i]=='0') { $Grid[$i] = '2'; if (CheckWin()) { $Choix = $i; break; } } } //Recherche d'une position qui contre l'adversaire if ($Choix==-1) for ($i=0 ; $i<9 ; $i++) { $Grid = $Buffer; if ($Grid[$i]=='0') { $Grid[$i] = '1'; if (CheckWin()) { $Choix = $i; break; } } } //Recherche d'une position qui dispense 2 positions gagnantes if ($Choix==-1 && $Level>=1) for ($i=0 ; $i<9 ; $i++) { $Grid = $Buffer; if ($Grid[$i]=='0') { $Grid[$i] = '2'; $Buffer2 = $Grid; $WinCount = 0; for ($j=0 ; $j<9 ; $j++) { $Grid = $Buffer2; if ($Grid[$j]=='0') { $Grid[$j] = '2'; if (CheckWin()) $WinCount++; } } if ($WinCount>=2) { $Choix = $i; break; } } } $Grid = $Buffer; //Recherche d'une position adverse qui force 2 positions gagnantes if ($Choix==-1 && $Grid!='100020001' && $Grid!='001020100' && !$Symetrical && $Level>=1) for ($i=0 ; $i<9 ; $i++) { $Grid = $Buffer; if ($Grid[$i]=='0') { $Grid[$i] = '1'; $Buffer2 = $Grid; $WinCount = 0; for ($j=0 ; $j<9 ; $j++) { $Grid = $Buffer2; if ($Grid[$j]=='0') { $Grid[$j] = '1'; if (CheckWin()) $WinCount++; } } if ($WinCount>=2) { $Choix = $i; break; } } } $Grid = $Buffer; //Petit remède d'invincibilité complémentaire if ($Level>=1) $NoCorner = ($Grid=='100020001' || $Grid=='001020100'); else $NoCorner = false; //Choix de la case centrale si disponible if ($Choix==-1 && $Grid[4]=='0') if ($Level>=1 || ($Level==0 && rand(0,5)!=4)) $Choix = 4; //En mode de jeu le plus grand, il est interdit pour l'ordinateur de jouer sur les points cardinaux au second tour (sinon il perd à coup sûr) //D'après une situation particulière de symétrie, on exploite cette même interdiction mais pour des raisons différentes if (($Choix==-1 && $Level>=2 && $Grid=='000010000') || $Symetrical) { $_choice = -1; while ($_choice==-1) switch(rand(1,4)) { case 1: if ($Grid[6]=='0') $_choice=6; break; case 2: if ($Grid[8]=='0') $_choice=8; break; case 3: if ($Grid[0]=='0') $_choice=0; break; case 4: if ($Grid[2]=='0') $_choice=2; break; } $Choix = $_choice; } //Choix d'une case au pif... if ($Choix==-1) { $Case = rand(0,8); while ($Grid[$Case]!='0') { $Case++; if ($Case>8) $Case = 0; } //...on ne doit pas jouer pas au pif dans les coins quand c'est stratégiquement suicidaire if ($NoCorner) { if ($Case==0 || $Case==2 || $Case==6 || $Case==8) $Case++; if ($Case>8) $Case = 1; } $Choix = $Case; } //Restauration des données $Grid = $Buffer; return $Choix; } if (($Grid!='000000000' || isset($_GET['serverbegins'])) && !CheckWin() && HasChar($Grid,'0')) { $Index = Computing(); if ($Index!= -1) $Grid[$Index]='2'; else { echo '<b>Une erreur fatale est survenue.'; echo '<br/><br/>Cliquez <a href="morpion.php">ici</a> pour faire une nouvelle partie.'; return 0; } } //Traitement des points: pour pouvoir transmettre efficacement les scores, il est nécessaire //d'appeler 9 fois dans le vide la fonction GetCellColor. Cela permet d'initialiser correctement //la variable $WinningPosition et donc de rendre les scores transmissibles via la fonction //EchoTbl qui est chargée d'afficher les nouveaux scores. for ($i=0 ; $i<9 ; $i++) GetCellColor($i,false); if ($WinningPosition>=0 && $WinningPosition<9) switch ($Grid[$WinningPosition]) { case '1': $PlayerPoints++; break; case '2': $ServerPoints++; break; } ?> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <title>Le jeu du morpion</title> <style> A.link { color: #8080FF; text-decoration: none } A.link:hover { color: blue; text-decoration: underline overline } TD.gameboard { border: 2px solid maroon } IMG { border: 0 } </style> </head> <body bgcolor="<?php echo $BackGroundColor; ?>"> <table width="35%" cellspacing="0" border="0" align="center"> <tr> <td colspan="2" height="50px" align="center" style="border: 1px solid #996600"> <?php if ($DisallowLinks=CheckWin()) echo '<b><font face="Verdana" color="#996600">La partie est terminée !</font></b>'; else if (!HasChar($Grid,'0')) { echo '<b><font face="Verdana" color="#996600">Match nul !</font></b>'; $DisallowLinks=true; } else echo '&nbsp;'; ?> </td> </tr> <tr> <td valign="center" width="35%" style="border-right: 1px solid navy"> <font size="4" color="green"><b>Actions :</b></font> <br/>&nbsp; <?php if ($Grid=='000000000') echo '<br/><a class=link href="morpion.php?game='.$Grid.'&serverbegins&level='.$Level.'&serverpts='.$ServerPoints.'&playerpts='.$PlayerPoints.'">Laisser la main</a>'; else echo '<br/>&nbsp;'; ?> <?php if ($ServerPoints!=0 || $PlayerPoints!=0) echo '<br/><a class=link href="morpion.php?game=000000000&level='.$Level.'">RAZ</a>'; else echo '<br/>&nbsp;'; ?> <br/><a class=link href="morpion.php?level=<?php echo $Level.'&serverpts='.$ServerPoints.'&playerpts='.$PlayerPoints; ?>">Recommencer</a> </td> <td rowspan="2"> <br/>&nbsp; <table width="156" border="3" cellspacing="3" align="center" style="border: none"> <tr> <td bgcolor="<?php GetCellColor(0,true); ?>" class=gameboard style="border-top:none; border-left:none"><?php EchoTab(0); ?></td> <td bgcolor="<?php GetCellColor(1,true); ?>" class=gameboard style="border-top:none"><?php EchoTab(1); ?></td> <td bgcolor="<?php GetCellColor(2,true); ?>" class=gameboard style="border-top:none; border-right:none"><?php EchoTab(2); ?></td> </tr> <tr> <td bgcolor="<?php GetCellColor(3,true); ?>" class=gameboard style="border-left:none"><?php EchoTab(3); ?></td> <td bgcolor="<?php GetCellColor(4,true); ?>" class=gameboard><?php EchoTab(4); ?></td> <td bgcolor="<?php GetCellColor(5,true); ?>" class=gameboard style="border-right:none"><?php EchoTab(5); ?></td> </tr> <tr> <td bgcolor="<?php GetCellColor(6,true); ?>" class=gameboard style="border-bottom:none; border-left:none"><?php EchoTab(6); ?></td> <td bgcolor="<?php GetCellColor(7,true); ?>" class=gameboard style="border-bottom:none"><?php EchoTab(7); ?></td> <td bgcolor="<?php GetCellColor(8,true); ?>" class=gameboard style="border-bottom:none; border-right:none"><?php EchoTab(8); ?></td> </tr> </table> <br/>&nbsp; </td> </tr> <tr> <td valign="center" width="35%" style="border-right: 1px solid navy; border-top: 1px solid navy"> <font size="4" color="green"><b>Options:</b></font> <br/>&nbsp; <?php function EchoLevelList($Lvl,$Caption) { global $Grid, $Level, $ServerPoints, $PlayerPoints; echo '<br/>'; if ($Level==$Lvl) echo '<img src="tic.gif" align="absmiddle">&nbsp;'; if ($Grid=='000000000') echo '<a class=link href="morpion.php?game='.$Grid.'&level='.$Lvl.'&serverpts='.$ServerPoints.'&playerpts='.$PlayerPoints.'">'.$Caption.'</a>'; else echo $Caption; } EchoLevelList(0,'Faible'); EchoLevelList(1,'Intermédiaire'); EchoLevelList(2,'Invincible'); ?> </td> </tr> <tr> <td colspan="2" align="center"> <font size="2" color="navy">Serveur : <?php echo $ServerPoints; ?>&nbsp;&nbsp;&nbsp;<b>..::..</b>&nbsp;&nbsp;&nbsp;Joueur : <?php echo $PlayerPoints; ?></font> </td> </tr> <tr> <td colspan="2" align="center" style="border: 2px solid #996600"> <font size="2" color="maroon">Jeu du morpion <b>©</b> septembre 2005</font> </td> </tr> </table> </body> </html>

Conclusion :


Vous pouvez toujours aller visiter http://altert.family.free.fr/

Codes Sources

A voir également

Ajouter un commentaire Commentaires
cs_grandvizir Messages postés 1106 Date d'inscription samedi 8 novembre 2003 Statut Membre Dernière intervention 3 septembre 2006 22
17 déc. 2005 à 14:42
martin_j a eu raison de se manisfester et il faut prendre les diverses réactions dans le bon sens. Eu qui crût prendre !

L'algorithme est simplement tombé sur un cas particulier qui est la symétrie du plateau de jeu dans le cadre de la réflexion N°4 de la fonction Computing(). L'algo n'avait rien de mauvais, il lui manquait juste une petite partie de sa réflexion. J'ai donc effectué les modifications de manière à ce que l'astuce de martin_j ne soit plus possible.

J'en ai profité pour :
- colorer les cases lorsqu'une ligne/colonne/diagonale est réalisée
- gérer un système de points
- incorporer un facilateur de clics

Pour ce qui est du morpion d'ordre 4, mieux vaut préférer un arbre de jeu plutôt que mon algo de réflexion (lui, qui permet de gérer facilement des niveaux de jeu). Vous voyez déjà aisément la taille relativement importante requise pour la gestion de l'ordre 3...

coucou747> Encore heureux que le serveur ne joue jamais les mêmes coups ! Ceci est preuve de constructivité de la part de l'auteur du jeu :)) De plus l'algo ne joue "au pif" que si sa réflexion ne lui a apporté aucune solution pouvant jouer en sa faveur.
cs_BadNews Messages postés 98 Date d'inscription samedi 30 novembre 2002 Statut Membre Dernière intervention 10 septembre 2007 1
28 nov. 2005 à 05:02
lol Martin_j, j'ai dis que si le code est bien programmé, il est IMPOSSIBLE de le battre. Faut croire que le code n'est pas parfait, c'est tout. lmao.
cs_Anthomicro Messages postés 9433 Date d'inscription mardi 9 octobre 2001 Statut Membre Dernière intervention 13 avril 2007 8
19 nov. 2005 à 13:10
Martin > ah ouais pas mal, perso j'ai du m'y prendre deux fois pour qu'il la mette en bas à droite ;-)
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
19 nov. 2005 à 12:53
ouais, c'est vrai... mais t'aurais du donner ton astuce dès le départ...

Bon, à part ça, on peut dire que ton IA joue parfois au hazard... la mienne sur javascriptfr était totalement déterminée, je n'avais pas mis trois niveaux, mais j'avais fait deux modes : lui en premier, ou moi en premier...
cs_Martin_j Messages postés 15 Date d'inscription vendredi 1 juillet 2005 Statut Membre Dernière intervention 19 novembre 2005
19 nov. 2005 à 12:43
Salut,

1) Je clique au milieu
2) L'invincible met son rond sur la en bas à doite
3) Je clique en haut à gauche
4) Lui en haut, milieu
5) Moi en bas, à gauche
6) Lui en haut à droite
7) Moi au mileu à gauche

GAGNE !!!!!!!!!!!!

@+

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.