Jeu du morpion intelligent: humain versus php

Soyez le premier à donner votre avis sur cette source.

Vue 15 886 fois - Téléchargée 1 652 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

Messages postés
1237
Date d'inscription
samedi 8 novembre 2003
Statut
Membre
Dernière intervention
3 septembre 2006
14
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.
Messages postés
98
Date d'inscription
samedi 30 novembre 2002
Statut
Membre
Dernière intervention
10 septembre 2007
1
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.
Messages postés
9433
Date d'inscription
mardi 9 octobre 2001
Statut
Membre
Dernière intervention
13 avril 2007
8
Martin > ah ouais pas mal, perso j'ai du m'y prendre deux fois pour qu'il la mette en bas à droite ;-)
Messages postés
12303
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
35
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...
Messages postés
15
Date d'inscription
vendredi 1 juillet 2005
Statut
Membre
Dernière intervention
19 novembre 2005

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 !!!!!!!!!!!!

@+
Afficher les 22 commentaires

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.