0

I am programming a 5x5 tictactoe game. I get an unexpected runtime error, which returns a ROW/COL bigger than 4.

Plays per player:

Player: 3,3
Computer: 0,0

Player: 1,3
Computer: 0,3

Player: 3,1
Computer: 0,1

Player: 0,2
Computer: 140735274172144, 4204747 <-- after blocking the computer's winning chance, my transposition table generates this as the best move.

My code:

void doCompMove(TicTacToe& t, bool firstMove) {
    TicTacToe::row_index bestRow;
    TicTacToe::column_index bestCol;

#ifndef ANALYSE
    static int gameNum(0);
    if (!(firstMove))
#else
    Stopwatch sw;
    sw.start();
#endif
    t.clearTrans();
    t.chooseMove(TicTacToe::COMPUTER, bestRow, bestCol);
#ifndef ANALYSE
    else {
        bestRow=gameNum%5;
        bestCol=(gameNum/5)%5;
        ++gameNum;
    }
#else
    sw.stop();
    //if(bestRow > 4) bestRow=rand()%5;
    //if(bestCol > 4) bestCol=rand()%5;
    cout<<"Tijdsduur: "<<sw<<endl;
    cout<<"Transposition table size is: "<<t.getTransSize()<<endl;
    cout<<"Moves considered: "<<t.getAndResetMovesConsidered()<<endl;
#endif
    cout<<"Computer plays: ROW = "<<bestRow<<" COL = "<<bestCol<<endl;
    t.playMove(TicTacToe::COMPUTER, bestRow, bestCol);
}

This is the chooseMove function:

TicTacToe::PositionVal TicTacToe::chooseMove(Side s, row_index& bestRow, column_index& bestColumn,
                     PositionVal alpha, PositionVal beta, int depth) {
#ifdef ANALYSE
    ++movesConsidered;
#endif
    static const int MAX_TABLE_DEPTH(5); //7
    static const int MIN_TABLE_DEPTH(3); //5

    if(depth>MAX_TABLE_DEPTH)
        return UNCLEAR;
    Position thisPosition(board);
    if (depth>=MIN_TABLE_DEPTH && depth<=MAX_TABLE_DEPTH) {
        MapItr itr(transpositions.find(thisPosition));
        if (itr!=transpositions.end())
            return (*itr).second;
    }
    Side opp(s==COMPUTER ? HUMAN : COMPUTER);
    PositionVal simpleEval(positionValue());
    if (simpleEval!=UNCLEAR)
        return simpleEval;
    PositionVal bestValue(s==COMPUTER ? alpha : beta);
    for (row_index row(0); alpha<beta && row<board.numrows(); ++row)
        for (column_index column(0); alpha<beta && column<board.numcols(); ++column)
            if (squareIsEmpty(row, column)) {
                place(row, column, s);
                row_index dr;
                column_index dc;
                PositionVal reply(chooseMove(opp, dr, dc, alpha, beta, depth+1));
                place(row, column, EMPTY);
                if (s==COMPUTER && reply>bestValue || s==HUMAN && reply<bestValue) {
                    bestValue=reply;
                    if (s==COMPUTER)
                        alpha=bestValue;
                    else
                        beta=bestValue;
                    bestRow=row;
                    bestColumn=column;
                }
            }
    if (depth>=MIN_TABLE_DEPTH && depth<=MAX_TABLE_DEPTH) {
        transpositions[thisPosition]=bestValue;
    }
    return bestValue;
}

Is it possible that the transposition table has reached maximum size?

MapItr itr(transpositions.find(thisPosition)); if (itr!=transpositions.end()) return (*itr).second;

HieiFCB
  • 11
  • 5

1 Answers1

0

Looks like your code has a path that does not select any move. Thus you get garbage result.

It is easy to identify, just change follows:

void doCompMove(TicTacToe& t, bool firstMove) {
    TicTacToe::row_index bestRow = -1;
    TicTacToe::column_index bestCol = -1;

And see what outcome you will have. After that you need to find a hole in the logic.

VladimirS
  • 600
  • 6
  • 14
  • Debugging would help, but first try to print out return value from chooseMove(). There are plenty of locations where those values not set. – VladimirS Nov 18 '15 at 20:00