L3 Info : PHP et Applications Web
 
◃  Ch. 3 Un coup de poker  ▹
 

Classes JeuCartes et Main

  • La Classe JeuCartes permet de modéliser un jeu de 52 cartes
    /**
     * Classe JeuCartes
     *
     * Représentation d'un jeu de 52 cartes
     * @author Dominique Fournier
     * @date 2017-2022
     * @version 1.3 compatible PHP7.4
     */
    
    require_once("Carte.php");
    
    class JeuCartes {
    
      /**
       * $paquet : un tableau de Cartes
       * @access private
       * @var array (Carte[])
       */
      private array $paquet;
    
      /**
       * $taille : le nombre de cartes contenu dans le paquet
       * @access private
       * @var int
       */
      private int $taille;
    
      /**
       * self::NB_COULEURS : le nombre de couleurs (catégories de Cartes)
       * @access public
       * @const int
       */
      const NB_COULEURS = 4; //array("spades","hearts","clubs","diams");
    
      /**
       * @access public
       * @param int $t le nombre de cartes du paquet (multiple de 4)
       */
      public function __construct($t = 52) {
        $this->taille = $t;
        $this->paquet = array();
        for($i=0;$i<self::NB_COULEURS;$i++) {
          for($j=0;$j<$t/self::NB_COULEURS;$j++) {
    	    $c = new Carte($i,$j);
    	    $this->addCarte($c);
          }
        }
      }
    
      /**
       * ajoute une carte au paquet uniquement lors de l'initialisation (private?)
       * @access public
       * @param Carte $c la Carte à ajouter
       */
      public function addCarte(Carte $c): void {
        $this->paquet[sizeof($this->getPaquet())] = $c;
      }
    
      /**
       * @access public
       * @param int $pos la position de la carte dans le paquet
       * @return Carte $this->paquet[$pos];
       */
      public function getCarte($pos): Carte {
        if ($pos >=0 && $pos < sizeof($this->paquet))
          return $this->paquet[$pos];
        else
            exit("Indice de carte non valide :". $pos);
      }
    
      /**
       * @access public
       * @return array $this->paquet;
       */
      public function getPaquet(): array {
        return $this->paquet;
      }
    
      /**
       * @access public
       * @param int $pos
       * @param Carte $c
       */
      public function setCarte($pos, Carte $c): void {
        if ($pos >=0 && $pos < $this->getTaille()) {
          $this->paquet[$pos] = $c;
        }
        else {
          exit("Indice de carte non valide :". $pos);
        }
      }
    
      /**
       * @access public
       * @return int $this->taille;
       */
      public function getTaille(): int {
        return $this->taille;
      }
    
      /**
       * @access public
       * @param int $t
       */
      public function setTaille(int $t): void {
        $this->taille = $t;
      }
    
      /**
       * @return void
       * @access public
       */
      public function melangePaquet(): void {
        for ($i=0;$i<max(3,$this->getTaille()/10);$i++) {
          $this->coupePaquet();
          $this->riffleShuffe();
        }
      }
    
      /**
       * simulation de mélange type 'riffle-shuffle'
       * @access private
       * @return void
       */
      private function riffleShuffe(): void {
        $tabTmp1 = array();
        $tabTmp2 = array();
        for ($i=0;$i<$this->getTaille()/2;$i++) {
          $tabTmp1[$i] = $this->getCarte($i);
          $tabTmp2[$i] = $this->getCarte($i+$this->getTaille()/2);
        }
        for ($i=0;$i<$this->getTaille()/2;$i++) {
          $this->setCarte($i*2,$tabTmp1[$i]);
          $this->setCarte(($i*2)+1,$tabTmp2[$i]);
        }
      }
    
      /**
       * @access public
       * @return void
       */
      public function coupePaquet(): void {
        $coupe = rand(1,$this->getTaille()-2);
        $tabTmp = array();
        for ($i=$coupe,$j=0;$i<$this->getTaille();$i++,$j++) {
          $tabTmp[$j] = $this->getCarte($i);
        }
        for ($i=$coupe-1,$j=1;$i>=0;$i--,$j++) {
          $this->setCarte($this->getTaille()-$j,$this->getCarte($i));
        }
        for ($i=0;$i<sizeof($tabTmp);$i++) {
          $this->setCarte($i,$tabTmp[$i]);
        }
      }
    
      /**
       * @access public
       * @return string une chaîne résumant le paquet
       */
      public function __toString(): string {
        $resultat = "[";
        for($j=0;$j<$this->getTaille();$j++) {
          $c = $this->getCarte($j);
          $resultat .= $c->__toString();
        }
        return $resultat .= "]";
      }
    
      /**
       * @access public
       * @return Carte
       */
      public function distribueCarte(): Carte {
        $c = array_pop($this->paquet);
        $this->setTaille($this->getTaille()-1);
        return $c;
      }
    
      /**
       * @access public
       * @param Carte
       */
      public function remiseCarte(Carte $c) {
        array_unshift($this->paquet,$c);
        $this->setTaille($this->getTaille()+1);
      }
    }
  • La classe Main représente une main de 5 cartes au jeu de Poker
    /**
     * Classe Main
     *
     * @author Dominique Fournier
     * @date 2017-2022
     * @version 1.3 compatible PHP7.4
     */
    
    require_once("Carte.php");
    
    class Main {
    
      /**
       * $cardList : un tableau de 5 Cartes
       * @access private
       * @var array (Carte[])
       */
      private array $cardList;
    
      /**
       * @access public
       * initialise $this->cardList avec un tableau vide
       */
      public function __construct() {
        $this->cardList = array();
      }
    
      /**
       * méthode ajoutant une carte à la main
       * @access public
       * @param Carte $c une instance de Carte
       * @return void
       */
      public function addCarte(Carte $c) {
        $this->cardList[sizeof($this->cardList)] = $c;
      }
    
      /**
       * @access public
       * @param int $i la position de la carte dans $this->cardList
       * @return Carte $this->cardList[$index];
       */
      public function getCarte(int $index): Carte {
        if ($index >=0 && $index < sizeof($this->cardList)) {
          return $this->cardList[$index];
        }
        exit("Indice de carte non valide :". $index);
      }
    
      /**
       * @access public
       * @return int sizeof($this->cardList);
       */
      public function getTailleMain(): int {
        return sizeof($this->cardList);
      }
    
      /**
       * @access public
       * @return string une chaine résumant la main
       */
      public function __toString(): string {
        $resultat = "[";
        for($j=0;$j<$this->getTailleMain();$j++) {
          $c = $this->getCarte($j);
          $resultat .= $c->__toString();
        }
        return $resultat .= "]";
      }
    
      /**
       * @access public
       * @param int $index
       * @param Carte $c
       * @return void
       */
      public function setCarte($index, Carte $c):void {
        if ($index<sizeof($this->cardList)) {
          $this->cardList[$index] = $c;
        }
      }
    
      /**
       * méthode triant la main selon la hauteur des cartes
       * @access public
       * @return void
       */
      public function triMain(): void {
        sort($this->cardList);
      }
    
      /**
       * méthode calculant la signature d'une main
       * la signature correspond à la séquence constitutée des différences
       * de hauteurs des cartes consécutives
       * @access public
       * @return string la chaîne représentant la signature
       */
      public function signature(): string {
        $signature = "";
        for ($i=1; $i<sizeof($this->cardList); $i++) {
          $diff = $this->getCarte($i)->getHauteur()-$this->getCarte($i-1)->getHauteur();
          switch ($diff) {
          case 12 :
    	$signature.= "C"; break;
          case 11 :
    	$signature.= "B"; break;
          case 10 :
    	$signature.= "A"; break;
          default :
    	$signature.= $diff;
          }
        }
        return $signature;
      }
    
      /**
       * @access private
       * @return array le résumé les effectifs de chaque couleur
       */
      private function couleurs(): array {
        $couleurs = array(0,0,0,0,0);
        for ($i=0; $i<sizeof($this->cardList); $i++) {
          $couleurs[$this->getCarte($i)->getCouleur()] +=1;
        }
        return $couleurs;
      }
    
      /**
       * @access public
       * @return int le niveau de la combinaison
       */
      public function combinaison(): int {
        $signature = $this->signature();
        $nbZeros = substr_count($signature,"0");
        $nbUns = substr_count($signature,"1");
    
        if ($nbUns == 4 || $signature == "1119") {
          if (in_array(5,$this->couleurs())) {
    	return 8; // Quinte flush
          }
          return 4; // Quinte;
        }
        else {
          if (in_array(5,$this->couleurs())) {
    	return 5; // Couleur;
          }
          else {
    	if ($nbZeros == 3) {
    	  if ($signature[0] != '0' || $signature[3] != '0') {
    	    return 7; // Carre;
    	  }
    	  else {
    	    return 6; // Full;
    	  }
    	}
    	else {
    	  if ($nbZeros == 2) {
    	    if (substr_count($signature,"00")) {
    	      return 3; //"Brelan";
    	    }
    	    else {
    	      return 2; //"Double Paire";
    	    }
    	  }
    	  else {
    	    if ($nbZeros == 1) {
    	      return 1; //"Paire";
    	    }
    	  }
    	}
          }
          return 0; //"Carte isolee";
        }
      }
    
      /**
       * @access public
       * @return string le nom de la combinaison
       */
      public function nomCombinaison(): string {
        switch ($this->combinaison()) {
        case 8 :
          return "Quinte flush";
        case 7 :
          return "Carre";
        case 6 :
          return "Full";
        case 5 :
          return "Couleur";
        case 4 :
          return "Suite";
        case 3 :
          return "Brelan";
        case 2 :
          return "Double Paire";
        case 1 :
          return "Paire";
        default :
          return "Carte Isolee";
    
        }
      }
    
      /**
       * @access public
       * @return array
       */
      public function evalueMain(): array {
        $signature = $this->signature();
        $combinaison = $this->combinaison();
        $evaluation = array();
        $indEval = 0;
        $evaluation[$indEval++] = $combinaison;
    
        switch($combinaison) {
        case 8 : // Quinte Flush
        case 5 : // Couleur
        case 4 : // Suite
        case 0 : // Carte Isolee
          for($i=4;$i>=0;$i--)
    	$evaluation[$indEval++]=$this->cardList[$i]->getHauteur();
          break;
        case 6 : // Full
          $pos = strpos($signature,"00");
          $evaluation[$indEval++]=$this->cardList[$pos]->getHauteur();
          //      AAABB 0 AABBB 2
          break;
        case 7: // Carre
          $pos = strpos($signature,"000");
          $evaluation[$indEval++]=$this->cardList[$pos]->getHauteur();
          break;
    
        case 3: // Brelan
          $pos = strpos($signature,"00");
          $evaluation[$indEval++]=$this->cardList[$pos]->getHauteur();
          break;
    
        case 2: // Double Paire
          $pos1 = strrpos($signature,"0");
          $evaluation[$indEval++]=$this->cardList[$pos1]->getHauteur();
          $pos2 = strpos($signature,"0");
          $evaluation[$indEval++]=$this->cardList[$pos2]->getHauteur();
          for($i=4;$i>=0;$i--)
    	if ($i != $pos1 && $i != ($pos1+1) && $i != $pos2 && $i != ($pos2+1))
    	  $evaluation[$indEval++]=$this->cardList[$i]->getHauteur();
          break;
    
        case 1: // Paire
          $pos = strpos($signature,"0");
          $evaluation[$indEval++]=$this->cardList[$pos]->getHauteur();
          for($i=4;$i>=0;$i--)
    	if ($i != $pos && $i != ($pos+1))
    	  $evaluation[$indEval++]=$this->cardList[$i]->getHauteur();
          break;
        default:
          echo "BUG";
        }
        return $evaluation;
      }
    
      /**
       * @param Main $m
       * @access public
       * @return int un entier comparant la valeur de $this et $m
       */
      public function compareMain(Main $m): int {
        $evalThis = $this->evalueMain();
        $evalM = $m->evalueMain();
        $parcours = 0;
    
        while($evalThis[$parcours] == $evalM[$parcours] && $parcours < sizeof($evalThis)) {
          $parcours++;
        }
        return $evalThis[$parcours] - $evalM[$parcours];
      }
    }
    ?>