21P — Un casino virtuel
Par admin le mardi, mai 11 2021, 12:00 - 2020–2021 - Lien permanent
Ce projet a été réalisé par LACHAT, Mariano Philippe (3M4).
1. Introduction
Selon un article du MarketWatch, publié en décembre 2020, le poker en ligne a connu un essor important dû aux restrictions à la mobilité liées à la pandémie de Covid-19. Ainsi, l'état du New Jersey atteignait un record pour ses revenus mensuels provenant du poker et des casinos en ligne, chiffré à 93,5 millions de dollars au mois d'octobre dernier. C'est une hausse de 106,7 % par rapport à octobre 2019.
Comme chacun le sait, les jeux d'argents possèdent des règles qui empêchent de gagner sur le long terme, afin d'assurer des revenus aux casinos. Par ailleurs, ces types de jeux se révèlent très addictifs pour certaines personnes.
Le but de ce projet est de réaliser un casino virtuel reposant sur de l'argent fictif et permettant de jouer au poker (variante Texas Hold’em) ainsi qu’à d’autres mini-jeux de casino (tels que machine à sous) avec l'objectif d'offrir une alternative sans risques mais amusante aux différents jeux d'argents.
Le fait qu'un poker nécessite pour le moins un semblant de temps réel constitue un enjeu important du projet. Une autre question importante à considérer est l’aspect multi-joueurs du projet. En effet, pour éviter aux visiteurs du site web d’attendre que d’autres joueurs soient en ligne pour être en mesure de lancer une partie de poker, il faudrait idéalement programmer des intelligences artificielles, ce qui représente une charge de travail conséquente. La présence d’autres mini-jeux plus faciles à programmer dans le casino virtuel permettrait de varier un peu et d'illustrer la règle d'or des casinos: Au final, c'est toujours la maison qui gagne!
2. Matériel et méthodes
2.1 Matériel
Il vous faut un ordinateur avec les logiciels suivants:
- Un éditeur de texte
- Un navigateur
- Apache, PHP et MySQL (ou bien n'importe quel logiciel combinant les trois et permettant de mettre en place un serveur Web local)
- L'application web phpMyAdmin
2.2 Méthode
2.2.1 Base de données
Commencer par télécharger la base de données ci-jointe, puis importer le fichier dans phpMyAdmin:
Les différentes tables contenues dans la base de données peuvent paraître hors du commun. En effet, la plupart d'entre elles servent à contrôler des éléments de jeu. Il s'ensuit qu'elles garderont toujours le même nombre de lignes. Par ailleurs, la table players
contenant la liste de tous les joueurs n'a pas d'identifiant numérique unique. C'est un choix volontaire, afin d'obliger les nouveaux arrivants à prendre un pseudonyme inexistant.
2.2.2 Structure du site web
Créer les dossiers suivants à l'intérieur d'un dossier principal contenant tous les fichiers du projet:
- php
- css
- fonts
- images
- audio
Les instructions en CSS sont inscrites dans des fichiers distincts, situés dans le dossier css
.
De même, le code PHP et les requêtes MySQL seront séparés de la structure en HTML et iront dans des fichiers séparés au sein du dossier php
. Appliquer au minimum ces quelques mesures permet de s'y retrouver plus facilement.
Dès lors, écrire dans un fichier db.inc.php
(à mettre dans le dossier php
) les quelques lignes suivantes permettant de se connecter à notre base de données. Ce fichier sera à appeler partout où l'on désire faire des requêtes MySQL.
//Connexion en local $db = mysqli_connect("localhost", "root", "root", "casino");
//Connexion sur le serveur dev.gyre.ch include("../../../etc/mysql.inc.php");$db = mysqli_connect($MYSQL_SERVER, $MYSQL_USER, $MYSQL_PASS, "paqc_marianolachat");
Créer aussi un fichier functions.inc.php
dans le dossier php
. Il contiendra les fonctions principales nécessaires au bon fonctionnement du site web.
2.2.3 Le Poker
2.2.3.1 Un algorithme essentiel
Avant même de commencer à programmer la gestion des tours de mises et des règles du poker, il est important d'avoir un algorithme permettant de classer les mains des joueurs. Il y a de nombreux cas à prendre en compte. Voici deux fonctions opérationnelles à ajouter dans le fichier functions.inc.php
:
function find_card($x, $serie) { $offset = 0; $allpos = array(); while !== FALSE) { $offset = $pos + 1; $allpos = $pos; } $result = implode($allpos); return $result; }
function rate_deck($i, $ii, $iii, $iv, $v, $vi, $vii) { $value = 0; $hand = 'none'; $A='A'; $K='K'; $Q='Q'; $J='J'; $ten='X'; $nine='9'; $eight='8'; $seven='7'; $six='6'; $five='5'; $four='4'; $three='3'; $two='2'; $Carreau='Ca'; $Coeur='Co'; $Pique='Pi'; $Trefle='Tr'; $rang0 = substr($i,-5,1); $rang1 = substr($ii,-5,1); $rang2 = substr($iii,-5,1); $rang3 = substr($iv,-5,1); $rang4 = substr($v,-5,1); $rang5 = substr($vi,-5,1); $rang6 = substr($vii,-5,1); $rank = implode($rang); $couleur0 = substr($i,0,2); $couleur1 = substr($ii,0,2); $couleur2 = substr($iii,0,2); $couleur3 = substr($iv,0,2); $couleur4 = substr($v,0,2); $couleur5 = substr($vi,0,2); $couleur6 = substr($vii,0,2); $suit = implode($couleur); $code = $rang0.$couleur0.$rang1.$couleur1.$rang2.$couleur2.$rang3. $couleur3.$rang4.$couleur4.$rang5.$couleur5.$rang6.$couleur6; $posA = find_card($A, $rank); $posK = find_card($K, $rank); $posQ = find_card($Q, $rank); $posJ = find_card($J, $rank); $posX = find_card($ten, $rank); $pos9 = find_card($nine, $rank); $pos8 = find_card($eight, $rank); $pos7 = find_card($seven, $rank); $pos6 = find_card($six, $rank); $pos5 = find_card($five, $rank); $pos4 = find_card($four, $rank); $pos3 = find_card($three, $rank); $pos2 = find_card($two, $rank); $nA = strlen($posA); $nK = strlen($posK); $nQ = strlen($posQ); $nJ = strlen($posJ); $nX = strlen($posX); $n9 = strlen($pos9); $n8 = strlen($pos8); $n7 = strlen($pos7); $n6 = strlen($pos6); $n5 = strlen($pos5); $n4 = strlen($pos4); $n3 = strlen($pos3); $n2 = strlen($pos2); //Quinte flush royal if ($nA>=1 && $nK>=1 && $nQ>=1 && $nJ>=1 && $nX>=1) { print $code; $posA = intval($posA); $posK = intval($posK); $posQ = intval($posQ); $posJ = intval($posJ); $posX = intval($posX); $pos9 = intval($pos9); $pos8 = intval($pos8); $pos7 = intval($pos7); $pos6 = intval($pos6); $pos5 = intval($pos5); $pos4 = intval($pos4); $pos3 = intval($pos3); $pos2 = intval($pos2); print ' - '.$posA.' '.$posK.' '.$posQ.' '.$posJ.' '.$posX; $posA = $posA+$posA*2+1; $posK = $posK+$posK*2+1; $posQ = $posQ+$posQ*2+1; $posJ = $posJ+$posJ*2+1; $posX = $posX+$posX*2+1; $pos9 = $pos9+$pos9*2+1; $pos8 = $pos8+$pos8*2+1; $pos7 = $pos7+$pos7*2+1; $pos6 = $pos6+$pos6*2+1; $pos5 = $pos5+$pos5*2+1; $pos4 = $pos4+$pos4*2+1; $pos3 = $pos3+$pos3*2+1; $pos2 = $pos2+$pos2*2+1; $p1 = substr($code, $posA, 2); $p2 = substr($code, $posK, 2); $p3 = substr($code, $posQ, 2); $p4 = substr($code, $posJ, 2); $p5 = substr($code, $posX, 2); if ($p1 == $p2 && $p2 == $p3 && $p3 == $p4 && $p4 == $p5) { $value = 1000000000000; $hand = 'royal_flush'; } } //Quinte flush if ($value == 0) { if (strpos($code, 'KCa') !== FALSE && strpos($code, 'QCa') !== FALSE && strpos($code, 'JCa') !== FALSE && strpos($code, 'XCa') !== FALSE && strpos($code, '9Ca') !== FALSE) { $value = 900000000000; $hand = 'straight_flush'; }elseif (strpos($code, 'KCo') !== FALSE && strpos($code, 'QCo') !== FALSE && strpos($code, 'JCo') !== FALSE && strpos($code, 'XCo') !== FALSE && strpos($code, '9Co') !== FALSE) { $value = 900000000000; $hand = 'straight_flush'; }elseif (strpos($code, 'KPi') !== FALSE && strpos($code, 'QPi') !== FALSE && strpos($code, 'JPi') !== FALSE && strpos($code, 'XPi') !== FALSE && strpos($code, '9Pi') !== FALSE) { $value = 900000000000; $hand = 'straight_flush'; }elseif (strpos($code, 'KTr') !== FALSE && strpos($code, 'QTr') !== FALSE && strpos($code, 'JTr') !== FALSE && strpos($code, 'XTr') !== FALSE && strpos($code, '9Tr') !== FALSE) { $value = 900000000000; $hand = 'straight_flush'; }elseif (strpos($code, 'QCa') !== FALSE && strpos($code, 'JCa') !== FALSE && strpos($code, 'XCa') !== FALSE && strpos($code, '9Ca') !== FALSE && strpos($code, '8Ca') !== FALSE) { $value = 800000000000; $hand = 'straight_flush'; }elseif (strpos($code, 'QCo') !== FALSE && strpos($code, 'JCo') !== FALSE && strpos($code, 'XCo') !== FALSE && strpos($code, '9Co') !== FALSE && strpos($code, '8Co') !== FALSE) { $value = 800000000000; $hand = 'straight_flush'; }elseif (strpos($code, 'QPi') !== FALSE && strpos($code, 'JPi') !== FALSE && strpos($code, 'XPi') !== FALSE && strpos($code, '9Pi') !== FALSE && strpos($code, '8Pi') !== FALSE) { $value = 800000000000; $hand = 'straight_flush'; }elseif (strpos($code, 'QTr') !== FALSE && strpos($code, 'JTr') !== FALSE && strpos($code, 'XTr') !== FALSE && strpos($code, '9Tr') !== FALSE && strpos($code, '8Tr') !== FALSE) { $value = 800000000000; $hand = 'straight_flush'; }elseif (strpos($code, 'JCa') !== FALSE && strpos($code, 'XCa') !== FALSE && strpos($code, '9Ca') !== FALSE && strpos($code, '8Ca') !== FALSE && strpos($code, '7Ca') !== FALSE) { $value = 700000000000; $hand = 'straight_flush'; }elseif (strpos($code, 'JCo') !== FALSE && strpos($code, 'XCo') !== FALSE && strpos($code, '9Co') !== FALSE && strpos($code, '8Co') !== FALSE && strpos($code, '7Co') !== FALSE) { $value = 700000000000; $hand = 'straight_flush'; }elseif (strpos($code, 'JPi') !== FALSE && strpos($code, 'XPi') !== FALSE && strpos($code, '9Pi') !== FALSE && strpos($code, '8Pi') !== FALSE && strpos($code, '7Pi') !== FALSE) { $value = 700000000000; $hand = 'straight_flush'; }elseif (strpos($code, 'JTr') !== FALSE && strpos($code, 'XTr') !== FALSE && strpos($code, '9Tr') !== FALSE && strpos($code, '8Tr') !== FALSE && strpos($code, '7Tr') !== FALSE) { $value = 700000000000; $hand = 'straight_flush'; }elseif (strpos($code, 'XCa') !== FALSE && strpos($code, '9Ca') !== FALSE && strpos($code, '8Ca') !== FALSE && strpos($code, '7Ca') !== FALSE && strpos($code, '6Ca') !== FALSE) { $value = 600000000000; $hand = 'straight_flush'; }elseif (strpos($code, 'XCo') !== FALSE && strpos($code, '9Co') !== FALSE && strpos($code, '8Co') !== FALSE && strpos($code, '7Co') !== FALSE && strpos($code, '6Co') !== FALSE) { $value = 600000000000; $hand = 'straight_flush'; }elseif (strpos($code, 'XPi') !== FALSE && strpos($code, '9Pi') !== FALSE && strpos($code, '8Pi') !== FALSE && strpos($code, '7Pi') !== FALSE && strpos($code, '6Pi') !== FALSE) { $value = 600000000000; $hand = 'straight_flush'; }elseif (strpos($code, 'XTr') !== FALSE && strpos($code, '9Tr') !== FALSE && strpos($code, '8Tr') !== FALSE && strpos($code, '7Tr') !== FALSE && strpos($code, '6Tr') !== FALSE) { $value = 600000000000; $hand = 'straight_flush'; }elseif (strpos($code, '9Ca') !== FALSE && strpos($code, '8Ca') !== FALSE && strpos($code, '7Ca') !== FALSE && strpos($code, '6Ca') !== FALSE && strpos($code, '5Ca') !== FALSE) { $value = 500000000000; $hand = 'straight_flush'; }elseif (strpos($code, '9Co') !== FALSE && strpos($code, '8Co') !== FALSE && strpos($code, '7Co') !== FALSE && strpos($code, '6Co') !== FALSE && strpos($code, '5Co') !== FALSE) { $value = 500000000000; $hand = 'straight_flush'; }elseif (strpos($code, '9Pi') !== FALSE && strpos($code, '8Pi') !== FALSE && strpos($code, '7Pi') !== FALSE && strpos($code, '6Pi') !== FALSE && strpos($code, '5Pi') !== FALSE) { $value = 500000000000; $hand = 'straight_flush'; }elseif (strpos($code, '9Tr') !== FALSE && strpos($code, '8Tr') !== FALSE && strpos($code, '7Tr') !== FALSE && strpos($code, '6Tr') !== FALSE && strpos($code, '5Tr') !== FALSE) { $value = 500000000000; $hand = 'straight_flush'; }elseif (strpos($code, '8Ca') !== FALSE && strpos($code, '7Ca') !== FALSE && strpos($code, '6Ca') !== FALSE && strpos($code, '5Ca') !== FALSE && strpos($code, '4Ca') !== FALSE) { $value = 400000000000; $hand = 'straight_flush'; }elseif (strpos($code, '8Co') !== FALSE && strpos($code, '7Co') !== FALSE && strpos($code, '6Co') !== FALSE && strpos($code, '5Co') !== FALSE && strpos($code, '4Co') !== FALSE) { $value = 400000000000; $hand = 'straight_flush'; }elseif (strpos($code, '8Pi') !== FALSE && strpos($code, '7Pi') !== FALSE && strpos($code, '6Pi') !== FALSE && strpos($code, '5Pi') !== FALSE && strpos($code, '4Pi') !== FALSE) { $value = 400000000000; $hand = 'straight_flush'; }elseif (strpos($code, '8Tr') !== FALSE && strpos($code, '7Tr') !== FALSE && strpos($code, '6Tr') !== FALSE && strpos($code, '5Tr') !== FALSE && strpos($code, '4Tr') !== FALSE) { $value = 400000000000; $hand = 'straight_flush'; }elseif (strpos($code, '7Ca') !== FALSE && strpos($code, '6Ca') !== FALSE && strpos($code, '5Ca') !== FALSE && strpos($code, '4Ca') !== FALSE && strpos($code, '3Ca') !== FALSE) { $value = 300000000000; $hand = 'straight_flush'; }elseif (strpos($code, '7Co') !== FALSE && strpos($code, '6Co') !== FALSE && strpos($code, '5Co') !== FALSE && strpos($code, '4Co') !== FALSE && strpos($code, '3Co') !== FALSE) { $value = 300000000000; $hand = 'straight_flush'; }elseif (strpos($code, '7Pi') !== FALSE && strpos($code, '6Pi') !== FALSE && strpos($code, '5Pi') !== FALSE && strpos($code, '4Pi') !== FALSE && strpos($code, '3Pi') !== FALSE) { $value = 300000000000; $hand = 'straight_flush'; }elseif (strpos($code, '7Tr') !== FALSE && strpos($code, '6Tr') !== FALSE && strpos($code, '5Tr') !== FALSE && strpos($code, '4Tr') !== FALSE && strpos($code, '3Tr') !== FALSE) { $value = 300000000000; $hand = 'straight_flush'; }elseif (strpos($code, '6Ca') !== FALSE && strpos($code, '5Ca') !== FALSE && strpos($code, '4Ca') !== FALSE && strpos($code, '3Ca') !== FALSE && strpos($code, '2Ca') !== FALSE) { $value = 200000000000; $hand = 'straight_flush'; }elseif (strpos($code, '6Co') !== FALSE && strpos($code, '5Co') !== FALSE && strpos($code, '4Co') !== FALSE && strpos($code, '3Co') !== FALSE && strpos($code, '2Co') !== FALSE) { $value = 200000000000; $hand = 'straight_flush'; }elseif (strpos($code, '6Pi') !== FALSE && strpos($code, '5Pi') !== FALSE && strpos($code, '4Pi') !== FALSE && strpos($code, '3Pi') !== FALSE && strpos($code, '2Pi') !== FALSE) { $value = 200000000000; $hand = 'straight_flush'; }elseif (strpos($code, '6Tr') !== FALSE && strpos($code, '5Tr') !== FALSE && strpos($code, '4Tr') !== FALSE && strpos($code, '3Tr') !== FALSE && strpos($code, '2Tr') !== FALSE) { $value = 200000000000; $hand = 'straight_flush'; }elseif (strpos($code, '5Ca') !== FALSE && strpos($code, '4Ca') !== FALSE && strpos($code, '3Ca') !== FALSE && strpos($code, '2Ca') !== FALSE && strpos($code, 'ACa') !== FALSE) { $value = 100000000000; $hand = 'straight_flush'; }elseif (strpos($code, '5Co') !== FALSE && strpos($code, '4Co') !== FALSE && strpos($code, '3Co') !== FALSE && strpos($code, '2Co') !== FALSE && strpos($code, 'ACo') !== FALSE) { $value = 100000000000; $hand = 'straight_flush'; }elseif (strpos($code, '5Pi') !== FALSE && strpos($code, '4Pi') !== FALSE && strpos($code, '3Pi') !== FALSE && strpos($code, '2Pi') !== FALSE && strpos($code, 'APi') !== FALSE) { $value = 100000000000; $hand = 'straight_flush'; }elseif (strpos($code, '5Tr') !== FALSE && strpos($code, '4Tr') !== FALSE && strpos($code, '3Tr') !== FALSE && strpos($code, '2Tr') !== FALSE && strpos($code, 'ATr') !== FALSE) { $value = 100000000000; $hand = 'straight_flush'; } } //Carré if ($nA==4 || $nK==4 || $nQ==4 || $nJ==4 || $nX==4 || $n9==4 || $n8==4 || $n7==4 || $n6==4 || $n5==4 || $n4==4 || $n3==4 || $n2==4) { $hand = '4_of_a_kind'; if ($nA == 4) { $value = 41400000000; }elseif ($nK == 4) { $value = 41300000000; }elseif ($nQ == 4) { $value = 41200000000; }elseif ($nJ == 4) { $value = 41100000000; }elseif ($nX == 4) { $value = 41000000000; }elseif ($n9 == 4) { $value = 40900000000; }elseif ($n8 == 4) { $value = 40800000000; }elseif ($n7 == 4) { $value = 40700000000; }elseif ($n6 == 4) { $value = 40600000000; }elseif ($n5 == 4) { $value = 40500000000; }elseif ($n4 == 4) { $value = 40400000000; }elseif ($n3 == 4) { $value = 40300000000; }elseif ($n2 == 4) { $value = 40200000000; } } //Full if ($value == 0) { if ($nA==3 || $nK==3 || $nQ==3 || $nJ==3 || $nX==3 || $n9==3 || $n8==3 || $n7==3 || $n6==3 || $n5==3 || $n4==3 || $n3==3 || $n2==3) { if ($nA==2 || $nK==2 || $nQ==2 || $nJ==2 || $nX==2 || $n9==2 || $n8==2 || $n7==2 || $n6==2 || $n5==2 || $n4==2 || $n3==2 || $n2==2) { $hand = 'full_house'; if ($nA == 3) { $value = 31400000000; }elseif ($nK == 3) { $value = 31300000000; }elseif ($nQ == 3) { $value = 31200000000; }elseif ($nJ == 3) { $value = 31100000000; }elseif ($nX == 3) { $value = 31000000000; }elseif ($n9 == 3) { $value = 30900000000; }elseif ($n8 == 3) { $value = 30800000000; }elseif ($n7 == 3) { $value = 30700000000; }elseif ($n6 == 3) { $value = 30600000000; }elseif ($n5 == 3) { $value = 30500000000; }elseif ($n4 == 3) { $value = 30400000000; }elseif ($n3 == 3) { $value = 30300000000; }elseif ($n2 == 3) { $value = 30200000000; } if ($nA == 2) { $value = $value + 1400000; }elseif ($nK == 2) { $value = $value + 1300000; }elseif ($nQ == 2) { $value = $value + 1200000; }elseif ($nJ == 2) { $value = $value + 1100000; }elseif ($nX == 2) { $value = $value + 1000000; }elseif ($n9 == 2) { $value = $value + 900000; }elseif ($n8 == 2) { $value = $value + 800000; }elseif ($n7 == 2) { $value = $value + 700000; }elseif ($n6 == 2) { $value = $value + 600000; }elseif ($n5 == 2) { $value = $value + 500000; }elseif ($n4 == 2) { $value = $value + 400000; }elseif ($n3 == 2) { $value = $value + 300000; }elseif ($n2 == 2) { $value = $value + 200000; } } } } //Couleur if ($value == 0) { $posA = intval($posA); $posK = intval($posK); $posQ = intval($posQ); $posJ = intval($posJ); $posX = intval($posX); $pos9 = intval($pos9); $pos8 = intval($pos8); $pos7 = intval($pos7); $pos6 = intval($pos6); $pos5 = intval($pos5); $pos4 = intval($pos4); $pos3 = intval($pos3); $pos2 = intval($pos2); $posA = $posA+$posA*2+1; $posK = $posK+$posK*2+1; $posQ = $posQ+$posQ*2+1; $posJ = $posJ+$posJ*2+1; $posX = $posX+$posX*2+1; $pos9 = $pos9+$pos9*2+1; $pos8 = $pos8+$pos8*2+1; $pos7 = $pos7+$pos7*2+1; $pos6 = $pos6+$pos6*2+1; $pos5 = $pos5+$pos5*2+1; $pos4 = $pos4+$pos4*2+1; $pos3 = $pos3+$pos3*2+1; $pos2 = $pos2+$pos2*2+1; $p0 = substr($code, 1, 2); $p1 = substr($code, 4, 2); $p2 = substr($code, 7, 2); $p3 = substr($code, 10, 2); $p4 = substr($code, 13, 2); $p5 = substr($code, 16, 2); $p6 = substr($code, 19, 2); sort($p); $d = implode($p); $check = 'no'; if (strpos($d, 'CaCaCaCaCa') !== FALSE) { $value = 900000000; $hand = 'flush'; $letters = 'Ca'; $check = 'yes'; }elseif (strpos($d, 'CoCoCoCoCo') !== FALSE) { $value = 900000000; $hand = 'flush'; $letters = 'Co'; $check = 'yes'; }elseif (strpos($d, 'PiPiPiPiPi') !== FALSE) { $value = 900000000; $hand = 'flush'; $letters = 'Pi'; $check = 'yes'; }elseif (strpos($d, 'TrTrTrTrTr') !== FALSE) { $value = 900000000; $hand = 'flush'; $letters = 'Tr'; $check = 'yes'; } if ($check == 'yes') { if (strpos($code, 'A'.$letters) !== FALSE) { $value = $value + 14000; } if (strpos($code, 'K'.$letters) !== FALSE) { $value = $value + 13000; } if (strpos($code, 'Q'.$letters) !== FALSE) { $value = $value + 12000; } if (strpos($code, 'J'.$letters) !== FALSE) { $value = $value + 11000; } if (strpos($code, 'X'.$letters) !== FALSE) { $value = $value + 10000; } if (strpos($code, '9'.$letters) !== FALSE) { $value = $value + 9000; } if (strpos($code, '8'.$letters) !== FALSE) { $value = $value + 8000; } if (strpos($code, '7'.$letters) !== FALSE) { $value = $value + 7000; } if (strpos($code, '6'.$letters) !== FALSE) { $value = $value + 6000; } if (strpos($code, '5'.$letters) !== FALSE) { $value = $value + 5000; } if (strpos($code, '4'.$letters) !== FALSE) { $value = $value + 4000; } if (strpos($code, '3'.$letters) !== FALSE) { $value = $value + 3000; } if (strpos($code, '2'.$letters) !== FALSE) { $value = $value + 2000; } } } //Suite if ($nA>=1 && $nK>=1 && $nQ>=1 && $nJ>=1 && $nX>=1 && $value == 0) { $value = 100000000; $hand = 'straight'; }elseif ($nK>=1 && $nQ>=1 && $nJ>=1 && $nX>=1 && $n9>=1 && $value == 0) { $value = 90000000; $hand = 'straight'; }elseif ($nQ>=1 && $nJ>=1 && $nX>=1 && $n9>=1 && $n8>=1 && $value == 0) { $value = 80000000; $hand = 'straight'; }elseif ($nJ>=1 && $nX>=1 && $n9>=1 && $n8>=1 && $n7>=1 && $value == 0) { $value = 70000000; $hand = 'straight'; }elseif ($nX>=1 && $n9>=1 && $n8>=1 && $n7>=1 && $n6>=1 && $value == 0) { $value = 60000000; $hand = 'straight'; }elseif ($n9>=1 && $n8>=1 && $n7>=1 && $n6>=1 && $n5>=1 && $value == 0) { $value = 50000000; $hand = 'straight'; }elseif ($n8>=1 && $n7>=1 && $n6>=1 && $n5>=1 && $n4>=1 && $value == 0) { $value = 40000000; $hand = 'straight'; }elseif ($n7>=1 && $n6>=1 && $n5>=1 && $n4>=1 && $n3>=1 && $value == 0) { $value = 30000000; $hand = 'straight'; }elseif ($n6>=1 && $n5>=1 && $n4>=1 && $n3>=1 && $n2>=1 && $value == 0) { $value = 20000000; $hand = 'straight'; }elseif ($n5>=1 && $n4>=1 && $n3>=1 && $n2>=1 && $nA>=1 && $value == 0) { $value = 10000000; $hand = 'straight'; } //Brelan if ($value == 0) { if ($nA==3 || $nK==3 || $nQ==3 || $nJ==3 || $nX==3 || $n9==3 || $n8==3 || $n7==3 || $n6==3 || $n5==3 || $n4==3 || $n3==3 || $n2==3) { $hand = '3_of_a_kind'; if ($nA == 3) { $value = 3140000; }elseif ($nK == 3) { $value = 3130000; }elseif ($nQ == 3) { $value = 3120000; }elseif ($nJ == 3) { $value = 3110000; }elseif ($nX == 3) { $value = 3100000; }elseif ($n9 == 3) { $value = 3090000; }elseif ($n8 == 3) { $value = 3080000; }elseif ($n7 == 3) { $value = 3070000; }elseif ($n6 == 3) { $value = 3060000; }elseif ($n5 == 3) { $value = 3050000; }elseif ($n4 == 3) { $value = 3040000; }elseif ($n3 == 3) { $value = 3030000; }elseif ($n2 == 3) { $value = 3020000; } } } //Deux paires - Une paire if ($value == 0) { if ($nA==2 || $nK==2 || $nQ==2 || $nJ==2 || $nX==2 || $n9==2 || $n8==2 || $n7==2 || $n6==2 || $n5==2 || $n4==2 || $n3==2 || $n2==2) { if ($nA == 2) { $value = $value + 514000; } if ($nK == 2) { $value = $value + 513000; } if ($nQ == 2) { $value = $value + 512000; } if ($nJ == 2) { $value = $value + 511000; } if ($nX == 2) { $value = $value + 510000; } if ($n9 == 2) { $value = $value + 509000; } if ($n8 == 2) { $value = $value + 508000; } if ($n7 == 2) { $value = $value + 507000; } if ($n6 == 2) { $value = $value + 506000; } if ($n5 == 2) { $value = $value + 505000; } if ($n4 == 2) { $value = $value + 504000; } if ($n3 == 2) { $value = $value + 503000; } if ($n2 == 2) { $value = $value + 502000; } if ($value >= 1000000) { $hand = 'two_pair'; }else{ $hand = 'one_pair'; } } } //Carte Haute if ($value == 0) { $hand = 'high_card'; } if ($nA>=1) { $value = $value + 8192; } if ($nK>=1) { $value = $value + 4095; } if ($nQ>=1) { $value = $value + 2047; } if ($nJ>=1) { $value = $value + 1023; } if ($nX>=1) { $value = $value + 511; } if ($n9>=1) { $value = $value + 255; } if ($n8>=1) { $value = $value + 127; } if ($n7>=1) { $value = $value + 63; } if ($n6>=1) { $value = $value + 31; } if ($n5>=1) { $value = $value + 15; } if ($n4>=1) { $value = $value + 7; } if ($n3>=1) { $value = $value + 3; } if ($n2>=1) { $value = $value + 1; } $hv = array(0 => $hand, 1 => $value); return $hv; }
Les deux fonctions opèrent ensemble pour attribuer une valeur numérique plus ou moins haute à une main donnée. Pour déterminer un gagnant, utiliser la fonction rate_deck()
et comparer les nombres obtenus.
2.2.3.2 Intelligences artificielles
Pour permettre à un seul joueur de s'amuser, trois intelligences artificielles sont présentes dans le jeu. Leur principe de fonctionnement est modifiable à souhait. Dans ce projet, les décisions sont soit prises au hasard, soit orchestrées en comparant les mains des trois intelligences artificielles et en gardant le meilleur jeu dans la course.
2.2.4 La machine à sous
2.2.4.1 Principe sous-jacent
Comme mentionné dans l'introduction, le jeu de la machine à sous fonctionne de manière à ce que les joueurs perdent sur le long terme comme dans un véritable casino. Voici les calculs qui le démontrent:
Cas favorables:
777 = 1/1000 * (77777) CCC = 1/1000 * (5000) PPP = 1/1000 * (2500) FFF = 6/1000 * (1000)
77 = 24/1000 * (777) CC = 24/1000 * (500) PP = 24/1000 * (250) FF = 144/1000 * (100)
C = Chapeau, P = Pistolet, F = Fruit
Cas défavorables:
N = 243/1000 * (-5) NN = 27/1000 * (-2500) NNN = 1/1000 * (-5000)
Prix = 1000/1000 * (-5)
N = Cactus, Prix = Chaque fois que l'on joue
Total Gagnant: 72,325
Total Perdant: 78,715
On voit que si chaque combinaison survient équitablement, le joueur va perdre de l'argent à la longue.
2.2.4.1 Le mécanisme astucieux
Afin de donner l'illusion des rouleaux en rotation qui s'arrêtent, concevoir trois animations (fichier .gif
) avec des vitesses légèrement différentes. Le script suivant permet d'ajouter des images représentant la position d'arrêt au-dessus des animations, ce qui donne l'impression que les rouleaux se sont arrêtés:
<script type="text/javascript"> setTimeout(function(){ document.getElementById('win_1').style.display = 'block'; }, 1200); setTimeout(function(){ document.getElementById('win_2').style.display = 'block'; }, 2300); setTimeout(function(){ document.getElementById('win_3').style.display = 'block'; }, 3400); setTimeout(function(){ document.getElementById("spin").disabled = false; }, 3500); </script>
2.2.5 Éléments additionnels
Pour le design, les images ou certains bruitages manquants, faire appel à sa propre créativité et laisser libre cours à son imagination.
3. Résultats
Le jeu de poker comporte des bugs surgissants de manière aléatoire. Les intelligences artificielles notamment, provoquent parfois des réactions hasardeuses. Malgré tout, il reste possible de jouer des parties seul ou à plusieurs. Voici pour exemple une partie en solitaire contre les ordinateurs qui a bien démarré. Avec une très bonne main, je n'ai pas hésité à miser de fortes sommes. Au final, tout le monde s'étant couché, la victoire m'est revenue par défaut:
Figure 3.1. — Exemple d'une partie de poker
La machine à sous est en revanche une véritable en réussite:
Figure 3.2. — Démonstration du fonctionnement de la machine à sous
Enfin un dernier résultat important: L'implémentation d'un classement permettant de lister tous les joueurs sur plusieurs pages en fonction de leur argent. Une manière de motiver les visiteurs à jouer ici plutôt qu'avec leur véritable argent!
Figure 3.3. — Liste des joueurs les plus riches
4. Discussion
Ce qu'il faut expliquer en premier lieu, c'est que le développement d'un jeu de poker multi-joueurs est plutôt complexe. Au début, j'avais pensé que le plus dur serait de concevoir l'algorithme d'évaluation des mains. Mais finalement, cette partie (loin d'être facile à mettre en place) s'est quand même révélée plus simple à faire que la gestion du jeu en lui-même. Ce que j'ai produit est donc une version simplifiée du poker Texas Hold'em (voir Références).
La première simplification s'est faite au niveau des blinds: D'ordinaire, les blinds forcent ceux qui les ont à miser quelque chose. Normalement, après chaque partie, les blinds changent de joueur ainsi que le bouton du dealer, afin que tout le monde puisse y passer. Dans mon jeu, ce sont toujours les intelligences artificielles qui occupent ces rôles afin de ne pas avoir trop de choses à gérer.
Ensuite, j'ai réduit les actions permises à un joueur qui en est à son tour. Il ne peut pas «checker» (faire parole) et n'a pas la possibilité de miser l'intégralité de son argent (le fameux «tapis»). Étant donné que mon casino virtuel a aussi un penchant éducatif, j'ai fais en sorte qu'un compte puisse passer dans le négatif et continuer à jouer. La notion de tapis en résulte peu pertinente.
Malgré ces simplifications, le code reste très lourd et comporte des erreurs que je ne suis pas parvenu à corriger entièrement. Certains jours, il m'était possible de chercher pendant une ou deux heures la cause d'un problème avant de parvenir à une solution. Ce que j'ai appris durant tout le processus, c'est l'importance d'un code bien commenté. En effet, lorsque mon fichier poker.inc.php
s'est dangereusement mis à faire un millier de lignes de code, j'ai réalisé qu'il aurait été très utile de commenter chaque morceau afin de mieux m'y retrouver. Car en l'espace de quelques jours, on oublie ce qu'on avait fait.
5. Conclusion
L'objectif initial, qui était de créer un espace de jeux d'argent fictif contenant un poker comme alternative aux vrais jeux d'argents (et comme moyen de sensibilisation) a été partiellement atteint. En effet, le jeu de poker rencontre régulièrement quelques problèmes.
Cela implique une baisse de l'attractivité du site web, puisque les personnes ne s'amusent pas beaucoup avec un jeu qui a de la peine à fonctionner. D'autant plus qu'il est presque impossible d'y jouer sur un téléphone mobile, la page du poker n'étant pas "responsive" contrairement au reste du site web. Heureusement, les autres implémentations (machine à sous et classement des joueurs) contribuent à l'intérêt des utilisateurs.
À partir de là, il y a beaucoup d'améliorations qui peuvent être mises en place. Non seulement on pourrait rendre ce jeu de poker fonctionnel et "responsive", mais il serait très intéressant de mettre à disposition des visiteurs d'autres jeux de casino pour augmenter l'attractivité du site web. De cette manière, on pourrait trouver sur le site web tout le plaisir des multiples jeux de casinos sans aucun risques.
Annexes
Références
Article du MarketWatch:
BLASI, Weston, «Online poker companies continue to make more money than ever during the pandemic», 4 décembre 2020, "MarketWatch"
https://www.marketwatch.com/story/online-poker-companies-continue-to-make-more-money-than-ever-during-the-pandemic-11607090841 (Consulté le 10 mai 2021)
Police d'écriture dans la machine à sous:
«LED LCD 123» par zanatlija, "Dafont.com"
https://www.dafont.com/fr/led-lcd-123.font (Consulté le 10 mai 2021)
Effets sonores:
«Slot Machine Sound Effects» par All Sounds, "YouTube"
https://www.youtube.com/watch?v=OXfpMWau-mE&t=36s (Consulté le 10 mai 2021)
«Slot Machine Jackpot - Sound Effect for Editing» par Sound Library, "YouTube"
https://www.youtube.com/watch?v=UpkC0vMxdDU (Consulté le 10 mai 2021)
«Success Sound Effects» par All Sounds, "YouTube"
https://www.youtube.com/watch?v=wBv9mmpERV8&t=24s (Consulté le 10 mai 2021)
Cartes du jeu de Poker:
«Poker (cards deck)», "Wikimedia Commons"
https://commons.wikimedia.org/wiki/Poker_(cards_deck) (Consulté le 10 mai 2021)
Règles du Poker Texas Hold'em:
«Texas hold'em», "Wikipedia"
https://fr.wikipedia.org/wiki/Texas_hold%27em#R%C3%A8gles (Consulté le 10 mai 2021)