bibi/bitboard

The bibi/bitboard module provides the ability to create and manipulate bitboards. Bitboards have a defined width and height, and an integer that represents the state of the bitboard when in binary

Suppose you are representing a game of tic-tac-toe that looks like

X | O | _
- + - + -
O | X | _
- + - + -
O | _ | X

Representing the X’s as a bitboard, it would look like

100
010
001

In binary, this would be 001010100, which translates to 84

Notice that the positions of the 1’s when the bitboard is translated into its binary integer format

The following diagram shows how the individual bits are ordered from right to left

6 7 8
3 4 5
0 1 2

To disambiguate between the bitwise shift operations in the int modules and bitboard shifts we use cardinal directions when describing and manipulating bitboards.

     north

      000
west  000  east
      000

     south

Types

pub type Bitboard {
  Bitboard(width: Int, height: Int, val: Int)
}

Constructors

  • Bitboard(width: Int, height: Int, val: Int)

Functions

pub fn antidiagonal(
  bitboard: Bitboard,
  antidiagonal_no: Int,
) -> Result(Bitboard, String)

Antidiagonals are made up of squares that touch at thr corners, and stretch from the south eastern corner and towards the north western corner.

In rectangular bitboards, the anti-diagonals will appear as follows

1000
0100
0010

Antidiagonals are indexed in the rank + file. In a bitboard of width 3 and height 4, the anti-diagonals will be indexed as

. . 5
. . 4
. . 3
0 1 2

A anti-diagonal of index 3 in the above bitboard will look like this

100
010
001
000
pub fn bitboard_and(
  bitboard_1: Bitboard,
  bitboard_2: Bitboard,
) -> Result(Bitboard, String)

Perfroms the and operation on two bitboards and returns a new bitboard. If a square is occupied on both bitboards, it will be occupied in the resulting bitboard. Both bitboards must have the same width and height.

010     000     000
010 and 111 --> 010
010     000     000
pub fn bitboard_not(bitboard: Bitboard) -> Bitboard

Performs the not operation on a bitboard. All occupied squares will become unoccupied, and vice versa.

i.e.

010    101
101 -> 010
010    101
pub fn bitboard_or(
  bitboard_1: Bitboard,
  bitboard_2: Bitboard,
) -> Result(Bitboard, String)

Perfroms the or operation on two bitboards and returns a new bitboard. If a square is occupied on both bitboards, it will be occupied in the resulting bitboard. Both bitboards must have the same width and height.

010     000     010
010 and 111 --> 111
010     000     010
pub fn bitboard_xor(
  bitboard_1: Bitboard,
  bitboard_2: Bitboard,
) -> Result(Bitboard, String)

Perfroms the xor operation on two bitboards and returns a new bitboard. If a square is occupied only on on of the two bitboards, it will be occupied in the resulting bitboard. Both bitboards must have the same width and height.

010     000     010
010 and 111 --> 101
010     000     010
pub fn diagonal(
  bitboard: Bitboard,
  diagonal_no: Int,
) -> Result(Bitboard, String)

Diagonals are made up of squares that touch at thr corners, and stretch from the south eastern corner and towards the north western corner.

In rectangular bitboards, the diagonals will appear as follows

0010
0100
1000

Diagonals are indexed in the width + rank - file. In a bitboard of width 3 and height 4, the diagonals will be indexed as

5 . .
4 . .
3 . .
2 1 0

A diagonal of index 3 in the above bitboard will look like this

001
010
100
000
pub fn file(
  bitboard: Bitboard,
  file_no: Int,
) -> Result(Bitboard, String)

Returns a bitboard with the nth file occupied of the provided bitboard Files are indexed from 0 to width - 1, and start from the west side of the board

i.e.

                             010
file(Bitboard(3, 3, 1)) --> 010
                             010
pub fn flip_horizontally(bitboard: Bitboard) -> Bitboard

Flips a bitboard horizontally

i.e

100    001
100 -> 001
100    001
pub fn flip_vertically(bitboard: Bitboard) -> Bitboard

Flips a bitboard vertically

i.e

111    000
000 -> 000
000    111
pub fn from_base2(
  width: Int,
  height: Int,
  bits: String,
) -> Result(Bitboard, String)

Create a bitboard of a given width and height, and a binary string

i.e. from_base2(3, 3, "000000111") –> Bitboard(width: 3, height: 3, val: 7)

pub fn from_coords(
  width: Int,
  height: Int,
  coords: Coords,
) -> Result(Bitboard, String)

Create a bitboard of a given width and height, and a Coords

i.e. from_coords(3, 3, Coords(0, 0)) –> Bitboard(width: 3, height: 3, val: 1)

pub fn from_list_of_coords(
  width: Int,
  height: Int,
  coords_list: List(Coords),
) -> Result(Bitboard, String)

Create a bitboard of a given width and height, and a list of Coords

i.e. from_coords(3, 3, [Coords(0, 0), Coords(1, 0)]) –> Bitboard(width: 3, height: 3, val: 3)

pub fn from_square(
  width: Int,
  height: Int,
  square: Int,
) -> Result(Bitboard, String)

Create a bitboard of a given with and height, and the nth square

i.e. from_square(3, 3, 1) –> Bitboard(width: 3, height: 3, val: 2)

Squares are indexed from bottom left to top right. A 3 by 3 bitboard will be indexed as follows

6 7 8
3 4 5
0 1 2
pub fn full_mask(b: Bitboard) -> Bitboard

This returns a bitboard that is fully occupied

i.e.

                                 111
full_mask(Bitboard(3, 3, 1)) --> 111
                                 111
pub fn new(width: Int, height: Int) -> Result(Bitboard, String)

Create an empty bitboard of a given width and height

pub fn rank(
  bitboard: Bitboard,
  rank_no: Int,
) -> Result(Bitboard, String)

Returns a bitboard with the nth rank occupied of the provided bitboard. Ranks are indexed from 0 to height - 1, and start from the north side of the board.

i.e.

                            000
rank(Bitboard(3, 3, 1)) --> 111
                            000
pub fn shift_east(
  bitboard: Bitboard,
  by i: Int,
) -> Result(Bitboard, String)

Shifts the entire board towards the east by i. Note that eastwards shifts will result in eastmost occupied squares to be removed completely

i.e. shift_east by 1

111    011
000 -> 000
000    000
pub fn shift_north(
  bitboard: Bitboard,
  by i: Int,
) -> Result(Bitboard, String)

Shifts the entire board towards the north by i

i.e. shift_north by 1

100    100
100 -> 100
100    000
pub fn shift_northeast(
  bitboard: Bitboard,
  by i: Int,
) -> Result(Bitboard, String)

Shifts the entire boards towards the northeast by i.

i.e. shift_northeast by 1

001    001
011 -> 000
000    000
pub fn shift_northwest(
  bitboard: Bitboard,
  by i: Int,
) -> Result(Bitboard, String)

Shifts the entire boards towards the northwest by i.

i.e. shift_northwest by 1

001    110
011 -> 000
000    000
pub fn shift_south(
  bitboard: Bitboard,
  by i: Int,
) -> Result(Bitboard, String)

Shifts the entire board towards the south by i

i.e. shift_south by 1

100    000
100 -> 100
100    100
pub fn shift_southeast(
  bitboard: Bitboard,
  by i: Int,
) -> Result(Bitboard, String)

Shifts the entire boards towards the southeast by i.

i.e. shift_southeast by 1

001    000
011 -> 000
000    001
pub fn shift_southwest(
  bitboard: Bitboard,
  by i: Int,
) -> Result(Bitboard, String)

Shifts the entire boards towards the southwest by i.

i.e. shift_southwest by 1

001    000
011 -> 010
000    110
pub fn shift_west(
  bitboard: Bitboard,
  by i: Int,
) -> Result(Bitboard, String)

Shifts the entire board towards the west by i. Note that westwards shifts will result in westmost occupied squares to be removed completely

i.e. shift_west by 1

111    110
000 -> 000
000    000
pub fn to_bools(b: Bitboard) -> List(Bool)

Convers a bitboard into a list of booleans representing where a square is occupied

i.e to_bools(Bitboard(width: 3, height: 3, val: 3)) –> [True, True, False,... ] (False repeats 7 times in this example)

pub fn to_squares(b: Bitboard) -> List(Int)

Converts a bitboard into a list of integers representing where a square is occupied

i.e to_squares(Bitboard(width: 3, height: 3, val: 3)) –> [0, 1]

pub fn to_string(bitboard: Bitboard) -> String

Converts a bitboard into a width * height, breakpoint separated string of 1s and 0s

i.e. to_string(Bitboard(width: 3, height: 3, val: 2)) –>

000
000
010
Search Document