I am creating a connect four bot in unity c#, and the board is represented using a binary number (long data type). For example: long board = 0b0000000_0000000_0000000_0000100_0000100_0110110;
would be the same as:
0000000
0000000
0000000
0000100
0000100
0110110
a method like this would work:
bool isWin(long bitboard) {
if (bitboard & (bitboard >> 6) & (bitboard >> 12) & (bitboard >> 18) != 0) return true; // / diagonal
if (bitboard & (bitboard >> 8) & (bitboard >> 16) & (bitboard >> 24) != 0) return true; // diagonal
if (bitboard & (bitboard >> 7) & (bitboard >> 14) & (bitboard >> 21) != 0) return true; // vertical
if (bitboard & (bitboard >> 1) & (bitboard >> 2) & (bitboard >> 3) != 0) return true; // horizontal
return false;
}
But for a board like long board = 0b0000000_0000000_0000000_0000000_0000011_1100000;
it would still return true even though the row would go through the wall and clip onto the other side.
I’ve tried to fix it like this:
long pMask = 0b0000000_0000000_0000000_0000000_0000000_0000001;
long dMask = 0b0000111_0000111_0000111_0000111_0000111_0000111;
long bMask = 0b0000000_1110000_1110000_1110000_1110000_1110000;
if ((_board & (_board >> 7) & (_board >> 14) & (_board >> 21)) != 0) { return true; } // vertical
long hori = _board & (_board >> 1) & (_board >> 2) & (_board >> 3);
if (hori != 0 && (pMask << (int)Math.Log(hori, 2) & bMask) == 0) { return true; } // horizontal
long ddia = _board & (_board >> 8) & (_board >> 16) & (_board >> 24);
if (ddia != 0 && (pMask << (int)Math.Log(ddia, 2) & bMask) == 0) { return true; } // down diagonal
long udia = _board & (_board >> 6) & (_board >> 12) & (_board >> 18);
if (udia != 0 && (pMask << (int)Math.Log(udia, 2) & dMask) == 0) { return true; } // up diagonal
return false;
But there are still bugs, like if long board = 0b0101010_0110010_1000011_1111000_1010010_0110100;
it will still return false.
long board = 0b0000000_0000000_0000000_0000011_1100000_0000000;
would return false which is correct
long board = 0b0000000_0000000_0000000_1111001_1100000_0000000;
would return true which is also correct