Pawn move generation in bitboards

Discussion of chess software programming and technical issues.

Moderators: Harvey Williamson, bob, hgm

Forum rules
This textbox is used to restore diagrams posted with the [d] tag before the upgrade.
Post Reply
AlvaroBegue
Posts: 925
Joined: Tue Mar 09, 2010 2:46 pm
Location: New York
Full name: Álvaro Begué (RuyDos)

Re: Pawn move generation in bitboards

Post by AlvaroBegue » Thu Dec 05, 2019 4:02 am

Just a note on C++ style. Using a few features from modern C++, you can make the code look quite clean. For instance, you can write wrappers around basic integer types to represent squares and bitboards, so you can print then naturally with `std::cout <<'. You can also make use of range-based for loops to iterate over the bits in a bitboard. I just put something together for your example of moving white pawns forward one step:

Code: Select all

#include <iostream>
#include <cstdint>

struct Square {
  int x;

  Square(int x) : x(x) { }
};

std::ostream &operator<<(std::ostream &os, Square sq) {
  if (sq.x >= 0 && sq.x < 64)
    os << char('h' - (sq.x % 8)) << char('1' + (sq.x / 8));
  else	
    os << "??";
  return os;
}

struct Bitboard {
  struct Iterator {
    uint64_t x;

    Iterator(uint64_t x) : x(x) { }
    Square operator*() const { return Square(__builtin_ctzll(x)); }
    Iterator &operator++() { x &= x - 1; return *this; }
    bool operator==(Iterator other) { return x == other.x; }
    bool operator!=(Iterator other) { return x != other.x; }
  };
  
  uint64_t x;
  
  Bitboard(uint64_t x) : x(x) { }

  Iterator begin() const { return Iterator(x); }
  Iterator end() const { return Iterator(0ull); }
};

Bitboard operator&(Bitboard bb1, Bitboard bb2) {
  return Bitboard(bb1.x & bb2.x);
}

Bitboard South(Bitboard bb) { return Bitboard(bb.x >> 8); }
Bitboard North(Bitboard bb) { return Bitboard(bb.x << 8); }
Bitboard East(Bitboard bb) { return Bitboard((bb.x & 0xfefefefefefefefeull) >> 1); }
Bitboard West(Bitboard bb) { return Bitboard((bb.x & 0x7f7f7f7f7f7f7f7full) << 1); }

Square South(Square sq) { return Square(sq.x - 8); }
Square North(Square sq) { return Square(sq.x + 8); }
Square East(Square sq) { return Square(sq.x - 1); }
Square West(Square sq) { return Square(sq.x + 1); }

int main() {
  Bitboard white_pawns = 0x000000000000ff00ull, empties = 0x0000ffffffff0000ull;
  
  for(auto from_square : white_pawns & South(empties))
    std::cout << from_square << North(from_square) << '\n';
}


Post Reply