denkspuren / BitboardC4

The Design of Bitboards for use in Connect Four
MIT License
62 stars 8 forks source link

ideas for listMoves() #3

Open LazyMammal opened 3 years ago

LazyMammal commented 3 years ago

These new versions of listMoves() depart somewhat from the original Fhourstones code. Perhaps the ideas included are worth exploring.

// this version is same speed as original (it just uses a couple more bitboard ideas)
int[] listMoves() {
    int[] moves;
    long TOP = 0b0100000_0100000_0100000_0100000_0100000_0100000_0100000L; // top playable row
    long bb = bitboard[0] | bitboard[1]; // combine both players
    for(int col = 0; col <= 6; col++) {
        if ((bb & 0b0100000) == 0) moves.push(col);  // check single column
        bb >>= 7; // shift next column into left-most position
    }
    return moves;
}

// this version is slower in the worst case (but potentially much faster on larger boards with many full columns)
int[] listMoves() {
    int[] moves;
    long TOP = 0b0100000_0100000_0100000_0100000_0100000_0100000_0100000L; // top playable row
    long bb = bitboard[0] | bitboard[1]; // combine both players
    bb ~= bb;  // invert bits (0 for piece, 1 for empty)
    bb &= TOP; // mask player pieces with TOP row bits
    bb >>= 5;  // bring top row bits to bottom row
    while(bb != 0) { // loop over bits (not columns)
        int index = numberOfTrailingZeros(bb); // count zeros before first set bit (e.g. __builtin_ctzll)
        moves.push(index / 7);  // convert index to column number
        bb &= bb - 1;  // clear first set bit (e.g. 0b11100 - 1 == 0b11011)
    }
    return moves;
}

// same but four lines written as one line
int[] listMoves() {
    int[] moves;
    long TOP = 0b0100000_0100000_0100000_0100000_0100000_0100000_0100000L; // top playable row
    long bb = (~(bitboard[0] | bitboard[1]) & TOP) >> 5; // combine, invert, mask, shift
    while(bb != 0) { // loop over bits (not columns)
        int index = numberOfTrailingZeros(bb); // count zeros before first set bit (e.g. __builtin_ctzll)
        moves.push(index / 7);  // convert index to column number
        bb &= bb - 1;  // clear first set bit (e.g. 0b11100 - 1 == 0b11011)
    }
    return moves;
}
denkspuren commented 3 years ago

Thanks for the comment. I need to look into it more closely, probably next month.