Handmade Hero»Forums»Game
Tobias Wolf
9 posts / 1 project
How to properly have an idea if your game sux?
Replying to da447m (#25934)

Sorry, I forgot to check in here.

Well, in MinMax you normally stop after a few levels of recursion and evalute how good you think a specific position is (or often, you actually abort a lot earlier if you see what you are doing is either way too bad (e.g. you loose your Queen; that's probably something you won't do) or too good (e.g. you capture a queen); in that case, the player before would not allow this move). However, how to evaluate a game state is obviously super game-dependent and requires you to be somehow good at the game (which is obviously not quite the case when prototyping), you could switch to Monte-Carlo-Tree-Search maybe.

64 posts
How to properly have an idea if your game sux?
Edited by da447m on
Replying to Mega Wolf (#25951)

Yeah,I might have made a mistake somewhere, but honestly I believe that my minmax funcs are correct. Just for the sake of completeness, I'll past them [as-is] below:

constexpr int16_t MAX_EVAL = 25000;
constexpr int16_t MIN_EVAL = -MAX_EVAL;

///Minmax evaluation with alpha beta pruning
int16_t minmax_ab(GPosition& position, uint8_t plies, int16_t alpha, int16_t beta, bool isMaximizer)
{
    if (plies == 0) {
        return get_position_value(position);
    }

    invert_color(GEval::EvalTurn);

    std::vector<PMove> validMoves = get_all_valid_moves(position);

    Pid capturedID;

    if (isMaximizer) {
        for (auto move : validMoves) {
            capturedID = Pid::NO_PIECE;
            perform_move(position, move, capturedID);
            alpha = std::max(alpha, minmax_ab(position, plies - 1, alpha, beta, false) );
            undo_move(position, move, capturedID);
            if (alpha >= beta) {
                return beta;
            }
        }
        return alpha;
    }
    else {
        for (auto move : validMoves) {
            capturedID = Pid::NO_PIECE;
            perform_move(position, move, capturedID);
            beta = std::min(beta, minmax_ab(position, plies - 1, alpha, beta, true) );
            undo_move(position, move, capturedID);
            if (beta <= alpha) {
                return alpha;
            }
        }
        return beta;
    }
}

PMove minmax_root(uint8_t plies)
{
    auto position = Board;

    std::vector<PMove> validMoves = get_all_valid_moves(position);

    /// assert((!validMoves.empty() && "no valid moves in minmax_root"));

    PMove bestmove = validMoves.back();

    Pid capturedID;
    perform_move(position, bestmove, capturedID);
    int16_t besteval = get_position_value(position);
    undo_move(position, bestmove, capturedID);

    for (auto move : validMoves) {
        capturedID = Pid::NO_PIECE;
        perform_move(position, bestmove, capturedID);
        int16_t eval = minmax_ab(position, plies - 1, MIN_EVAL, MAX_EVAL, false);
        undo_move(position, bestmove, capturedID);
        if (eval > besteval) {
            besteval = eval;
            bestmove = move;
        }
    }
    return bestmove;
}
Tobias Wolf
9 posts / 1 project
How to properly have an idea if your game sux?
Edited by Tobias Wolf on Reason: Typo
Replying to da447m (#25953)

I normally prefer the NegaMax variant; that's easier to read since on does not have two different cases.

Does the invert_color function do something to a global state? If yes, I somehow have the feeling that one should invert back when leaving the function again, no?

64 posts
How to properly have an idea if your game sux?
Replying to Mega Wolf (#25954)

Yes you are right, I guess I didn't notice the bug because I was always passing an even number of plies.

Thanks bud!