What's the right approach of storing moves generated using bitboards? I am building a chess engine from scratch using bitboards and, so far I am able to generate pawns moves. But, I am stuck on what should I do after finding all possible moves for pawns.

Right now the current function is generating QUIETS moves pushing pawns ONE or TWO squares. Later i will deal with en passant and validations.

My question is, Am I doing right generating all pawns moves at once? And, I would like to know what is the right approach of storing the moves? What information need to saved and what data type should I use?

Here my code (C++):

#include "moves.h"

//Pawns moves
Bitboard single_push(Color color, Bitboard pawns, Bitboard empty) { // EmptyBoardBB
   return color == WHITE ?  north(pawns) &amp; empty : 
                            south(pawns) &amp; empty;
}

// also used for en-passant 
Bitboard double_push(Color color, Bitboard pawns, Bitboard empty) {
   return color == WHITE ?  north_north(pawns) &amp; empty &amp; Rank4BB : 
                            south_south(pawns) &amp; empty &amp; Rank5BB;
}

// Right now just testing pushing pawns 1-2 squares
Bitboard generate_pawn_moves(Color color, GenType type, Bitboard Us, Bitboard Them)
{
    Bitboard bb, empty;
    empty = ~Them;

    if (type == QUIETS) 
    {
        bb = single_push(color, Us, empty);
    }

    return bb;
}


Thanks in advance for any info that can take me on the right path.
Q1: Should I generate all pawn moves at once?

Yes. There's no reason not to do that. But... your code wouldn't work because you're returning a bitboard in your function. You should instead return a list, Stockfish does that:


  https://github.com/official-stockfish/Stockfish/blob/master/src/movegen.cpp
  
  ExtMove* generate_pawn_moves(const Position&amp; pos, ExtMove* moveList, Bitboard target);


The function generate_pawn_moves takes a position object and append new pawn moves into a list (ExtMove*). You shouldn't just return a bitboard because:


It's not a convenient data structure for looping over moves (you'll need to loop over moves while doing your engine search)
It doesn't tell you where you pawn starts and thus you can't undo a move
By squeezing all the pawn moves into a single integer, you lose important information. For example, if you have a pawn on c4 and e4 and you can capture on d5. You need to save c4-d5 and e4-d5, not just d5.


Your function should look like:

void generate_pawn_moves(List *moves, Color color, GenType type, Bitboard Us, Bitboard Them);
{
    if (type == QUIETS) 
    {
        for (... all single push ...)
           moves++ = &lt;single push move&gt;

        for (... all double push ...)
           moves++ = &lt;double push move&gt;
    }
    else
    {
        for (... all captures ...)
           moves++ = &lt;captures move&gt;
    }
}


You will need to allocate enough memory for the moves pointer, there're other ways to do that but C++ discussion is off-topic here.

Later on, you'll need to do a search (otherwise why'd you generate the moves?). Like this:

  for (auto move : moves)
  {
       &lt;make the move to the internal board&gt;

       ..... search and evaluate the position after the move ....

       &lt;undo the move&gt;
  }


You see, you'll need to undo the move and it's only possible if you know where your pawn starts.

Q2: What do I need to save a move?

Let's take a look at Stockfish.


  https://github.com/official-stockfish/Stockfish/blob/master/src/types.h


/// A move needs 16 bits to be stored
///
/// bit  0- 5: destination square (from 0 to 63)
/// bit  6-11: origin square (from 0 to 63)
/// bit 12-13: promotion piece type - 2 (from KNIGHT-2 to QUEEN-2)
/// bit 14-15: special move flag: promotion (1), en passant (2), castling (3)
/// NOTE: EN-PASSANT bit is set only when a pawn can be captured
///



Destination
Origin
Promotion
En Passpant
Castling