J'essaye de construire l'IA tic-tac-toe en utilisant l'algorithme min max. Je fais référence à ce post de geekforgeeks pour écrire mon code. Mais bizarrement quand j'utilise un tableau 1D au lieu d'un tableau 2D en modifiant le code comme indiqué ci-dessous, je ne reçois pas la bonne sortie de la fonction findBestMove. Il est supposé retourner l'index à 4, mais il renvoie toujours 2. Qu'est-ce que je fais de mal?tic-tac-toe: sortie différente en utilisant 1d-array sur 2d- array
function Move(x,y){
this.row = x,
this.col = y;
};
const player = 'o', opponent = 'x';
const isMovesLeft = (board) => {
for (let i = 0; i<3; i++)
for (let j = 0; j<3; j++)
if (board[i][j]=='_')
return true;
return false;
}
const isMovesLeft2 = (board) => {
for (let i = 0; i<9; i++)
if (board[i]=='_')
return true;
return false;
}
const evaluate = (b) =>{
for (let row = 0; row<3; row++)
{
if (b[row][0]==b[row][1] &&
b[row][1]==b[row][2])
{
if (b[row][0]==player)
return +10;
else if (b[row][0]==opponent)
return -10;
}
}
for (let col = 0; col<3; col++)
{
if (b[0][col]==b[1][col] &&
b[1][col]==b[2][col])
{
if (b[0][col]==player)
return +10;
else if (b[0][col]==opponent)
return -10;
}
}
if (b[0][0]==b[1][1] && b[1][1]==b[2][2])
{
if (b[0][0]==player)
return +10;
else if (b[0][0]==opponent)
return -10;
}
if (b[0][2]==b[1][1] && b[1][1]==b[2][0])
{
if (b[0][2]==player)
return +10;
else if (b[0][2]==opponent)
return -10;
}
return 0;
}
const evaluate2 = (b) =>{
for (let row = 0; row<3; row++)
{
if (b[row]==b[row+1] &&
b[row+1]==b[row+2])
{
if (b[row]==player)
return +10;
else if (b[row]==opponent)
return -10;
}
}
for (let col = 0; col<3; col++)
{
if (b[col]==b[col+3] &&
b[col+3]==b[col+6])
{
if (b[col]==player)
return +10;
else if (b[col]==opponent)
return -10;
}
}
if (b[0]==b[4] && b[4]==b[8])
{
if (b[0]==player)
return +10;
else if (b[0]==opponent)
return -10;
}
if (b[2]==b[4] && b[4]==b[6])
{
if (b[2]==player)
return +10;
else if (b[2]==opponent)
return -10;
}
return 0;
}
const minimax = (board , depth, isMax) => {
let score = evaluate(board);
if (score == 10)
return score;
if (score == -10)
return score;
if (isMovesLeft(board)==false)
return 0;
if (isMax)
{
let best = -1000;
for (let i = 0; i<3; i++)
{
for (let j = 0; j<3; j++)
{
if (board[i][j]=='_')
{
board[i][j] = player;
best = Math.max(best,
minimax(board, depth+1, !isMax));
board[i][j] = '_';
}
}
}
return best;
}
else
{
let best = 1000;
// Traverse all cells
for (let i = 0; i<3; i++)
{
for (let j = 0; j<3; j++)
{
if (board[i][j]=='_')
{
board[i][j] = opponent;
best = Math.min(best,
minimax(board, depth+1, !isMax));
board[i][j] = '_';
}
}
}
return best;
}
}
const minimax2 = (board , depth, isMax) => {
let score = evaluate2(board);
if (score == 10)
return score;
if (score == -10)
return score;
if (isMovesLeft2(board)==false)
return 0;
if (isMax)
{
let best = -1000;
for (let i = 0; i<9; i++)
{
if (board[i]=='_')
{
board[i] = player;
best = Math.max(best,
minimax2(board, depth+1, !isMax));
board[i] = '_';
}
}
return best;
}
else
{
let best = 1000;
for (let i = 0; i<9; i++)
{
if (board[i]=='_')
{
board[i] = opponent;
best = Math.min(best,
minimax2(board, depth+1, !isMax));
board[i] = '_';
}
}
return best;
}
}
const findBestMove = (board) =>{
let bestVal = -1000;
let bestMove = new Move(-1,-1);
for (let i = 0; i<3; i++)
{
for (let j = 0; j<3; j++)
{
if (board[i][j]=='_')
{
board[i][j] = player;
let moveVal = minimax(board, 0, false);
board[i][j] = '_';
if (moveVal > bestVal)
{
bestMove.row = i;
bestMove.col = j;
bestVal = moveVal;
}
}
}
}
return bestMove;
}
const findBestMove2 = (board) =>{
let bestVal = -1000;
let bestMove = -1;
for (let i = 0; i<9; i++)
{
if (board[i]=='_')
{
board[i] = player;
let moveVal = minimax2(board, 0, false);
board[i]= '_';
if (moveVal > bestVal)
{
bestMove = i
bestVal = moveVal;
}
}
}
return bestMove;
}
const test =() => {
const board = [['x','_','_'],
['_','_','_'],
['_','_','_']];
const board2 = ['x','_','_',
'_','_','_',
'_','_','_'];
console.log(findBestMove(board));
console.log(findBestMove2(board2));
}
test();
Lorsque le test() est exécuté en premier appel renvoie la fonction meilleure que déplacer (1,1) mais la deuxième fonction retourne 2. Il devrait être 4 idéalement.
Désolé Suneeth, nous ne pouvons pas aider à la recherche d'insectes. Quelle erreur obtenez vous? Qu'avez-vous cherché et essayé jusqu'à présent? – RaphaMex
il est difficile de dire ce qui ne va pas avec le code, sans le déboguer. Vous pouvez essayer d'utiliser le débogueur, en définissant des points d'arrêt, regarder des valeurs. – grepLines
@ R.Saban: la description a été mise à jour pour mieux expliquer mon problème. Je ne pouvais pas trouver de différence entre les deux ensembles de fonctions en dehors du type de tableau utilisé. ils renvoient toujours deux valeurs différentes. –