-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathscript.js
More file actions
173 lines (159 loc) · 6.1 KB
/
Copy pathscript.js
File metadata and controls
173 lines (159 loc) · 6.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// Game Modele base on https://www.freecodecamp.com
// 1. Bassic Setup
// 2. Determine Winner
// 3. Implementation of Ai and Winner notification
// 4. Minimax Algorithm logic (hard part)
// 4. Minimax function composition description (fonction recurssive)
/* A Minimax algorithm can be best defined as
a recursive function that does the following things:
1. Return a value if a terminal state is found (+10, 0, -10)
2. Go through available spots on the board
3. Call the minimax function on each available spot (recursion)
4. Evaluate returning values from function calls
5. And return the best value
*/
var origBoard; // Variable pour la grille
const huPlayer = 'O'; // Player 1
const aiPlayer = 'X'; // Player 2
const winCombos = [ // tous les combos possible pour gagne
[0,1,2],
[3,4,5],
[6,7,8],
[0,3,6],
[1,4,7],
[2,5,8],
[0,4,8],
[6,4,2]
];
// les cellules seront selectionner avec la variable reference cells
const cells = document.querySelectorAll('.cell');
startGame();
function startGame(){
// on vient s'assurer d'enlever l'affichage de fin du jeu
document.querySelector(".endgame").style.display = "none";
origBoard = Array.from(Array(9).keys()); // pour creer un tableau de 9 elements pour avoir des cles de 0-9
for(var i =0 ; i < cells.length; i++){ // Reset le jeu avant de commencer
cells[i].innerText = "";
cells[i].style.removeProperty('background-color');
cells[i].addEventListener('click',turnClick,false); // on place un listener pour gerer les evenements de click
}
}
// fonction pour detecter les click et declancher l'evenement
function turnClick(square){
// console.log(square.target.id); // pour afficher le numero de la case
if (typeof origBoard[square.target.id] == 'number'){
turn(square.target.id, huPlayer); // la fonction pour faire apparaitre le symbole du joueur
if (!checkTie()) turn(bestSpot(),aiPlayer);
}
}
// la fonction pour faire apparaitre le symbole du joueur
function turn(squareId, player){
origBoard[squareId] = player; // on associe la case au joueur
document.getElementById(squareId).innerText = player; // on affiche sur la case le symbole du joueur
let gameWon = checkWin(origBoard, player);
if (gameWon) // si la game est remporte par un jouer alors gameOver
gameOver(gameWon)
}
//**************************************************/
// On va verifier avec toute les combo si le jouer a une des combinaisons
// inputs : board and player
// outputs: return gameWon if player win
// plays represente toutes les actions faites par le joueur
//**************************************************/
function checkWin(board, player) {
let plays = board.reduce((a, e, i) =>
(e === player) ? a.concat(i) : a, []);
let gameWon = null;
for (let [index, win] of winCombos.entries()) {
if (win.every(elem => plays.indexOf(elem) > -1)) {
gameWon = {index: index, player: player};
break;
}
}
return gameWon;
}
// va nous permettre darreter le jeu si le joueur gagne
function gameOver(gameWon) {
for (let index of winCombos[gameWon.index]) {
document.getElementById(index).style.backgroundColor =
gameWon.player == huPlayer ? "blue" : "red";
}
for (var i = 0; i < cells.length; i++) {
cells[i].removeEventListener('click', turnClick, false);
}
declareWinner(gameWon.player == huPlayer ? "Vous avez gagné!" : "Vous avez perdu!")
}
// affichage du message pour le gagnant, le perdant ou match nul.
function declareWinner(message){
document.querySelector(".endgame").style.display = "block";
document.querySelector(".endgame .text").innerText = message;
}
function emptySquares(){
return origBoard.filter(s => typeof s == 'number');
}
// AiPlayer sous forme de selection par defaut
function bestSpot(){
//return emptySquares()[0]; // joue sur le prochain espace libre
return minimax(origBoard, aiPlayer).index; // appel du nouveau algo
}
function checkTie(){
if (emptySquares().length == 0) {
for(var i = 0 ; i< cells.length; i++){
cells[i].style.backgroundColor = "green";
cells[i].removeEventListener('click',turnClick,false);
}
declareWinner("Match nul!");
return true;
}
return false;
}
// Fonction pour l'algo
function minimax( newBoard, player){
// 1. on verifie toutes les place libre pour voir si le robot peut gagner ce tour
// on lui donner les place libre sur la grille
var availableSpots = emptySquares(newBoard);
if(checkWin(newBoard,player)){
return {score:-10}; // beast mode -10 sinon -5
}else if(checkWin(newBoard,aiPlayer)){
return {score:10}; // beast mode 10 sinon 10
}else if(availableSpots.length === 0){
return {score: 0}; // beast mode 0 sinon -1
}
// 2. Debut de la boucle pour verifier et attribue un score a chaque place libre
var moves = [];
for(var i=0; i < availableSpots.length; i++){
var move = {};
move.index = newBoard[availableSpots[i]];
newBoard[availableSpots[i]] = player;
if (player == aiPlayer){
var result = minimax(newBoard, huPlayer); // revient a l'etape 1.
move.score = result.score * Math.random(); // a ete ajouter pour un a effet aleatoir
}else {
var result = minimax(newBoard, aiPlayer); // revient a l'etape 1.
move.score = result.score * Math.random();
}
//reset le newbord comme avant
newBoard[availableSpots[i]] = move.index;
// on place les mouvements pour les enregistrer
moves.push(move);
}
var bestMove;
if(player === aiPlayer){
var bestScore = -10000;
for(var i=0; i < moves.length; i++){
if(moves[i].score > bestScore){
bestScore = moves[i].score;
bestMove = i;
}
}
}else{
var bestScore = 10000;
for(var i=0; i < moves.length; i++){
if(moves[i].score < bestScore){
bestScore = moves[i].score;
bestMove = i;
}
}
}
return moves[bestMove]; // le choix du AI
}