// Game of Fanorona // David Eppstein, UC Irvine, 11 Jun 1997 // // Bit manipulation // // We represent Fanorona positions using two bitboards (64-bit longs) // one for the pieces of each player. The bits in the bitboard form // six 10-bit groups: an empty group followed by one for each row of the board. // Each row has an empty bit followed by a bit for each position in the row. // The empty bits help avoid extra range checking while finding captures. // // The top four bits are free for other purposes; we use one // to determine which color pieces are on each side, and one to determine // whether the side on move's most recent move was a capture. // // This class is not instantiable; instead it consists of constants // for various board configurations, used in game setup, move generation, // and evaluation. public abstract class Bits { public static final long IS_WHITE = 0x4000000000000000L; // 1L << 62 public static final long CAPTURED = 0x8000000000000000L; // 1L << 63; sign bit speeds tests public static final long INITIAL_BOT = 000000001225776777L; public static final long INITIAL_TOP = 017767772450000000L; public static final long TOP_ROW = 017760000000000000L; public static final long BOTTOM_ROW = 000000000000000777L; public static final long LEFT_COL = 010004002001000400L; public static final long RIGHT_COL = 000020010004002001L; public static final long DIAGONAL = 012522522524524525L; public static final long ON_BOARD = 017767773775776777L; public static final long CENTER = 000000000760000000L; // turn screen coordinates into bit position public static final long at(int row, int col) { return 1L << (10*(4-row)) + (8-col); } // isolate one of the bits from a bitboard public static final long lastBit(long bitboard) { return bitboard & -bitboard; } // how much to shift from coordinates public static final int SHIFT_VERTICAL = 10; public static final int SHIFT_HORIZONTAL = 1; public static final int SHIFT_SLANT = 11; public static final int SHIFT_BACKSLANT = 9; // count number of set bits in a word static final long ONES = 0x5555555555555555L; static final long TWOS = 0x3333333333333333L; static final int FOURS = 0x0f0f0f0f; public static final int count(long set) { set -= (set >>> 1) & ONES; set = (set & TWOS) + ((set >>> 2) & TWOS); int result = (int) set + (int) (set >>> 32); return (((result & FOURS) + ((result >>> 4) & FOURS)) * 0x01010101) >>> 24; } }