javascriptbitboard

How can I check for symmetry along the mid column in the board of Connect 4 in javascript when using bitboards?


I have the bitboard representation like this for each player:

00000000 0000000 0000001 0000010 0000100 0010001 0000101 0000000 0000001

00000000 0000000 0000000 0000001 0000011 0001110 0000010 0000000 0000000

Where every section is a column, the rightmost section with 7 bits represents the first column. The rightmost bit in each section represents the first row.

I have a height array that keeps track of the height of where I can place a piece.

I use BigInt in javascript to represent the boards. One for each player.

bitboard = [0n, 0n];
heightBB = [0, 7, 14, 21, 28, 35, 42];

Here is how I make the moves:

playMoveBB(state, col, player) {     
    let move = 1n << BigInt(state.heightBB[col]);
    state.heightBB[col]++;
    state.bitboard[player] = state.bitboard[player] ^  move;
}

Here is how I check for wins:

__isWin(bitboard) {
    if ((bitboard & (bitboard >> 6n) & (bitboard >> 12n) & (bitboard >> 18n)) !== 0n) return true; // diagonal \
    if ((bitboard & (bitboard >> 8n) & (bitboard >> 16n) & (bitboard >> 24n)) !== 0n) return true; // diagonal /
    if ((bitboard & (bitboard >> 7n) & (bitboard >> 14n) & (bitboard >> 21n)) !== 0n) return true; // horizontal
    if ((bitboard & (bitboard >> 1n) & (bitboard >>  2n) & (bitboard >>  3n)) !== 0n) return true; // vertical
    return false;
}   

How can I check for symmetry along the mid column? So that left side of the board is the same as right side of the board, from the perspective of mid column.

How can I achieve this using this bitboard representation of a Connect 4 game?


Solution

  • This is a matter of shifting the three right (higher-bit) columns to their mirrored positions at the low end, and compare that with the three left (lower-bit) columns:

    const isSymmetrical = (bitboard) => bitboard.every(b => 
        (b & 0x1FFFFFn) === ((b >> 42n) & 0x00007Fn | 
                             (b >> 28n) & 0x003F80n | 
                             (b >> 14n) & 0x1FC000n)
    );
    

    Explanation:

    Here is the same code, but using binary notation for the bitmasks:

    const isSymmetrical = (bitboard) => bitboard.every(b => 
        (b & 0b111111111111111111111n) === ((b >> 42n) & 0b000000000000001111111n | 
                                            (b >> 28n) & 0x000000011111110000000n | 
                                            (b >> 14n) & 0x111111100000000000000n)
    );