Présentation
Le Tic-tac-toe est un jeu de réflexion se pratiquant à deux joueurs au tour par tour et dont le but est de créer le premier un alignement. Il se joue sur une grille carrée de 3×3 cases contrairement au Morpion avec lequel il est souvent confondu et qui se joue sur des grille de 5×5 cases. Deux joueurs s’affrontent et doivent remplir chacun à leur tour une case de la grille avec le symbole qui leur est attribué. Le gagnant est celui qui arrive à aligner trois symboles identiques, horizontalement, verticalement ou en diagonale.
En raison du nombre de combinaisons limité, l’analyse complète du jeu est facile à réaliser, et c’est ce qui va nous intéresser ici. Tout comme le PONG, le code du jeu est très simple, mais il fait appel à une ébauche d’intelligence artificielle pour jouer contre un ordinateur. C’est le point important que nous allons développer aujourd’hui.
Je n’ai pas pensé à le dire lors des précédents exercices, mais le but du jeu est qu’à partir de l’étude préliminaire vous essayiez vous même de résoudre le problème avant de lire l’exercice. J’ai en effet utilisé ma propre méthode, mais votre approche de la chose est tout aussi importante que la lecture de l’exercice, comparer votre résultat et le mien vous donnera bien plus d’informations que de lire simplement la solution
Le code Javascript
// variables var canvas; var ctx; // variables var W = 480; var H = 480; var J = 1; var T = 160; var C = 3; var P = 0; // tableaux var stock = []; var valid = []; var libre = []; // charger les images du jeu var grille = new Image(); var tileO = new Image(); var tileX = new Image(); grille.src = "assets/grille.jpg"; tileO.src = "assets/TileO.jpg"; tileX.src = "assets/TileX.jpg"; window.onload = function() { canvas = document.getElementById('canvas'); ctx = canvas.getContext('2d'); canvas.width = W; canvas.height = H; init(); } // initialisation du jeu function init() { J = 1; P = 0; stock = [0,0,0,0,0,0,0,0,0]; valid = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]]; libre = [0,1,2,3,4,5,6,7,8]; render(); canvas.addEventListener("click", remplir, false); } // quel joueur joue function remplir(e){ if(J==1) { var index = parseInt(e.clientX/T)+parseInt(e.clientY/T)*C; if(stock[index]==0) { stock[index] = 1; libre.splice(libre.indexOf(index),1); render(); checkGagne(); setTimeout(tourOrdi, 500); return; } } if(J==2) { stock[P] = 2; libre.splice(libre.indexOf(P),1); render(); checkGagne(); } } // l'ordi choisi une case function tourOrdi(e){ var tab = stock.concat(); var i; for (i in libre) if (verifieCase(tab,2,libre[i])) return; for (i in libre) if (verifieCase(tab,1,libre[i])) return; remplirOrdi(libre[parseInt(Math.random()*libre.length)]); } // l'ordi vérifie si la case est gagnante function verifieCase(tab, id, b){ tab[b] = id; for (var c=0; c<valid.length; c++){ var w = true; for (var i=0; i<valid.length; i++) w = w && tab[valid[i]] == id; if (w){ remplirOrdi(b); return true; } } tab[b] = 0; return false; } // l'ordi joue son coup function remplirOrdi(p){ P = p; remplir(null); } // vérifie si un joueur gagne function checkGagne(){ for(var c=0; c< valid.length; c++){ var w = true; for (var i=0; i<valid.length; i++) w = w && stock[valid[i]] == J; if (w){ if(J==1) alert("Vous gagnez, cliquez pour rejouer."); if(J==2) alert("L'ordinateur gagne, cliquez pour rejouer."); init(); return; } } if (libre.length==0) { alert("Egalité, cliquez pour rejouer."); init(); return; } J==1 ? J=2 : J=1; } // Dessine le jeu function render() { ctx.drawImage(grille,0,0); for(var i=0; i<stock.length; i++){ if(stock[i]==2) ctx.drawImage(tileX, i%C*T, parseInt(i/C)*T); if(stock[i]==1) ctx.drawImage(tileO, i%C*T, parseInt(i/C)*T); } }