-1

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

1 Answers1

0

In order to get the first move from your recursion, you can try to save it alongside with bestValue. When you have selected the best move and are about to return from recursion, you can return both bestValue and the first move, using, for example, std::pair, so that your method signature is

std::pair<int, int> minimaxAlphaBeta(...);

To restore food, you save cell content in a char variable prevValue, overwrite the cell content, call recursion, restore the original cell value from prevValue. The schema is

char prevValue = mazeTemp[sr][sc];
mazeTemp[sr][sc] = ' ';
minimaxAlphaBeta(...);
minimaxAlphaBeta = prevValue;

I am not sure if alpha-beta pruning is suitable here. It is suited for 2-player games where both players "do the same thing". In this game this is not the case.

  • So i think ive done it well no? when is player 4 pacman if it has food i write, passage and after recursion in case i have to restore i restore to food again.... About std pair shouldnt be easier to have all the path as im trying ? – EDUARDO JOSE GUTIERREZ PASCUAL Feb 04 '16 at 11:06
  • Yes, part of storing that "there was food" seems OK. Your way of storing complete "best" path is harder to implement properly. If you go that way, you need an auxiliary vector for storing best sequence for "current beginning sequence" of moves. – Anatolijs Gorbunovs Feb 04 '16 at 11:28
  • The return bestValue is clear, what i dont know is what direction to return and where.... Also another solution could be generate the first call to minimax from direction i know and then compare the 4 values of every minimax, and get the result. – EDUARDO JOSE GUTIERREZ PASCUAL Feb 04 '16 at 18:45