Well i have the pacman game with a global vector CharactersLocation with row, column of each character...( ex: character[0] is row of ghost1, character[1] is column of ghost1, character[2] the row of ghost2...and character[8] and character[9] are pacman row and column.
My minimaxalphabeta implementation is :
int minimaxAlphaBeta ( int mazeTemp[][COLUMNS], int alpha, int beta, int score, int direction, int depth, int jugador)
{
int bestValue, childValue;
int playerRow=2*jugador;
int playerColumn=(2*jugador)+1;
int sr= CharactersLocationsMaze[playerRow];
int sc= CharactersLocationsMaze[playerColumn];
bool restore=false;
if(mazeTemp[sr][sc] == WALL) //You cannot visit it, or is wall or is @ visited
return 0;
if( depth > 0)
{
//El fantasma gana ya que esta en la misma posicion que el pacman
if (sr == CharactersLocationsMaze.at(8) && sc == CharactersLocationsMaze.at(9) )
{
bestValue=10000;
return bestValue;
}
else if ( PacmanWin(mazeTemp))
{
bestValue=-10000;
return bestValue;
}
}
else if (depth==0)
{
bestValue= abs( CharactersLocationsMaze.at(0)- CharactersLocationsMaze.at(8) ) +
abs( CharactersLocationsMaze.at(2)- CharactersLocationsMaze.at(8) ) +
abs( CharactersLocationsMaze.at(4)- CharactersLocationsMaze.at(8) ) +
abs( CharactersLocationsMaze.at(6)- CharactersLocationsMaze.at(8) ) +
abs( CharactersLocationsMaze.at(1)- CharactersLocationsMaze.at(9) ) +
abs( CharactersLocationsMaze.at(3)- CharactersLocationsMaze.at(9) ) +
abs( CharactersLocationsMaze.at(5)- CharactersLocationsMaze.at(9) ) +
abs( CharactersLocationsMaze.at(7)- CharactersLocationsMaze.at(9));
// score se podria modificar ( penalizas mas perder puntos o alejarte del pacman
bestValue=((1/bestValue)*Number_MAX_VALUE)-(score*10);
return bestValue;
}
//puntuacion pacman si consigue puntos
else if (jugador < 4)
{ // Jugadores 0,1,2,3 son fantasmas maximizan valor
bestValue = alpha; //bestvalue es lmax y childValue l
bestMovementPath.push_back(direction);
//Row -- Norte: jugador Actualizo el valor de lmin porque l es menor que lmin
CharactersLocationsMaze[playerRow]=sr-1;
CharactersLocationsMaze[playerColumn]=sc;
childValue = minimaxAlphaBeta( mazeTemp, bestValue, beta, score, 1, depth-1, jugador+1);
if(childValue > bestValue) bestValue = childValue;
//Row ++ Sur
CharactersLocationsMaze[playerRow]=sr+1;
CharactersLocationsMaze[playerColumn]=sc;
childValue = minimaxAlphaBeta( mazeTemp, bestValue, beta, score, 2, depth-1, jugador+1);
if(childValue > bestValue) bestValue = childValue;
//Column -- Oeste West
CharactersLocationsMaze[playerRow]=sr;
CharactersLocationsMaze[playerColumn]=sc-1;
childValue = minimaxAlphaBeta( mazeTemp, bestValue, beta, score, 3, depth-1, jugador+1);
if(childValue > bestValue) bestValue = childValue;
//Column ++ Este
CharactersLocationsMaze[playerRow]=sr;
CharactersLocationsMaze[playerColumn]=sc+1;
childValue = minimaxAlphaBeta( mazeTemp, bestValue, score, 4, beta, depth-1, jugador+1);
if(childValue > bestValue)
{
bestValue = childValue;
if (beta <= bestValue) {
return bestValue; //00
}//Path.append("E");
}
//Restore
CharactersLocationsMaze[playerRow]=sr;
CharactersLocationsMaze[playerColumn]=sc;
bestMovementPath.pop_back();
return bestValue;
}
else if ( jugador == 4)
{ // jUGADOR MIN
bestValue = beta; //bestvalue es lmax y childValue l
bestMovementPath.push_back(direction);
if(mazeTemp[sr][sc] == FOOD)
{
score=score+1;
mazeTemp[sr][sc] == PASSAGE;
restore=true;
}
//Row -- Norte: jugador Actualizo el valor de lmin porque l es menor que lmin
CharactersLocationsMaze[playerRow]=sr-1;
CharactersLocationsMaze[playerColumn]=sc;
childValue = minimaxAlphaBeta( mazeTemp, alpha, bestValue, score, 1, depth-1, 0);
if(childValue < bestValue) bestValue = childValue;
//Row ++ Sur
CharactersLocationsMaze[playerRow]=sr+1;
CharactersLocationsMaze[playerColumn]=sc;
childValue = minimaxAlphaBeta( mazeTemp, alpha, bestValue, score, 2, depth-1,0);
if(childValue < bestValue) bestValue = childValue;
//Column -- Oeste
CharactersLocationsMaze[playerRow]=sr;
CharactersLocationsMaze[playerColumn]=sc-1;
childValue = minimaxAlphaBeta( mazeTemp, alpha, bestValue, score, 3, depth-1, 0);
if(childValue < bestValue) bestValue = childValue;
//Column ++ Este
CharactersLocationsMaze[playerRow]=sr;
CharactersLocationsMaze[playerColumn]=sc+1;
childValue = minimaxAlphaBeta( mazeTemp, alpha, bestValue, score, 4, depth-1,0);
if(childValue < bestValue)
{
bestValue = childValue;
if ( bestValue <= alpha) {
return bestValue;
}
}
//RESTORE MAZE !!!! restore score ???
CharactersLocationsMaze[playerRow]=sr;
CharactersLocationsMaze[playerColumn]=sc;
if ( restore) mazeTemp[sr][sc] == FOOD;
bestMovementPath.pop_back();
return bestValue; //if ( Path.size() > 2) Path.erase(Path.size() - 1);
}
}
Also if jugador (player=4), is pacman and if it has food in the maze it scores point.
I ve three doubts: How to obtain the first movement ( ive thought about using a global variable bestMovementpath and push each iteration the direction, and after restore). I dont know if its right or if there is another solution better and cleaner. Every time i call the function i clear bestvaluemovement vector.
And the other is how to restore the food in case pacman player ( jugador=4) is situated in a maze with food. Then i have to restore to Food again in other recursion works well.
The last question is about beta, alpha... i think ive to cut only once depending of the bestvalue, or if i have to cut after every comparison...
Any help would be apreciated...also i ve defined an heuristic if anyone could improve it in a easy way...
Thanks in advance