I am writing a chess engine, and I'm understanding how chess engines store game positions (in 64-bit bitboards) and how to generate moves from them. When you get your final bitboard of moves, how do you know what piece moves where? For example, take a white knight. You can easily bitshift the white knight bitboard to get the squares the knight/s would move to, and then use other binary operators to make sure that those squares are not occupied by your own pieces and the knight did not move out of bounds. If this is the white knight bitboard:
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0
you can figure out that these are the legal moves (assuming there are no friendly pieces on the squares but they are irrelevant for this example)
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 1 0 1 0 0 0 0
1 0 1 0 1 0 0 0
0 0 * 1 0 0 0 0
1 * 0 0 1 0 0 0
0 1 0 1 0 0 0 0
(*s are used for the knight's positions, just so it's easier to visualize). Now that you know that a knight can move to e2, what does that do? How do you know which white knight. How do you know that both white knights could move to d1? The binary and bitboard operators are used because they are very efficient, but I cannot see how they help getting a final list of legal moves.