I store positions as bitboards and moves too, to make/unmake a move I XOR the 2 bitboard arrays together.
In Java I used an Arraylist of arrays to store moves and in C++ I used a vector of a struct.
Code: Select all
struct MOVE
{
U64 bm;
U64 bk;
U64 wm;
U64 wk;
int value;
};
std::vector<MOVE> moves;
The code for anyone interested
Code: Select all
#include <iostream>
#include <vector>
#include <chrono>
#define U64 unsigned long long
#define contains(bitboard, index) (bitboard & (1LL<<(index))) != 0
#define occupied(pos) pos[0] | pos[1] | pos[2] | pos[3] | 0b1111111111000000000010000000000100000000001000000000010000000000L;
struct MOVE
{
U64 bm;
U64 bk;
U64 wm;
U64 wk;
int value;
};
void printBoard(U64* pos){
U64 occupied = occupied(pos);
printf("+---+---+---+---+---+---+---+---+---+---+\n");
printf("| ");
int i;
for(i = 55; i>-1;i--){
if(!contains(occupied, i)){
printf("| | ");
}
if(contains(pos[0], i)){
printf("| b | ");
}
if(contains(pos[1],i)){
printf("| B | ");
}
if(contains(pos[2],i)){
printf("| w | ");
}
if(contains(pos[3],i)){
printf("| W | ");
}
if(i % 11 == 5){
printf("\n+---+---+---+---+---+---+---+---+---+---+\n");
}
if((i % 11 == 0) & (i != 55)){
printf("|\n");
printf("+---+---+---+---+---+---+---+---+---+---+\n");
if(i!=0){
printf("| ");
}
}
}
printf("\n");
}
void makeMove(U64* pos, MOVE option){
pos[0] ^= option.bm;
pos[1] ^= option.bk;
pos[2] ^= option.wm;
pos[3] ^= option.wk;
pos[4] = -pos[4];
}
void slide(U64* pos, std::vector<MOVE> &moves){
U64 occupied = occupied(pos);
int color = (int) pos[4];
if(color == 1){
// add white sliding moves
for(int i = 0; i < 49; i++){
if(contains(pos[2], i)){
if(!contains(occupied, i+5)){
MOVE next = {0, 0, (1LL<<i)+(1LL<<(i+5)), 0, 0};
moves.push_back(next);
}
if(!contains(occupied, i+6)){
MOVE next = {0, 0, (1LL<<i)+(1LL<<(i+6)), 0, 0};
moves.push_back(next);
}
}
}
} else {
for(int i = 5; i < 54; i++){
if(contains(pos[0], i)){
if(!contains(occupied, i-5)){
MOVE next = {(1LL<<i)+(1LL<<(i-5)), 0, 0, 0, 0};
moves.push_back(next);
}
if(!contains(occupied, i-6)){
MOVE next = {(1LL<<i)+(1LL<<(i-6)), 0, 0, 0, 0};
moves.push_back(next);
}
}
}
}
}
int perft(U64* pos, int depth){
if(depth == 0){
return 1;
}
int num = 0;
std::vector<MOVE> moves;
slide(pos, moves);
for(int i = 0; i<moves.size();i++){
makeMove(pos, moves[i]);
num += perft(pos, depth - 1);
makeMove(pos, moves[i]);
}
return num;
}
void printMoves(std::vector<MOVE> &moves){
std::cout<<"Printing moves\n";
for(int i = 0; i < (int) moves.size();i++){
std::cout <<"Move "<<i<<": " <<moves[i].bm<<" "<< moves[i].bk<<" "<< moves[i].wm<<" "<< moves[i].wk<<"\n";
}
}
int main()
{
U64 bm = 0b0000000000111111111101111111111000000000000000000000000000000000LL;
U64 bk = 0b0000000000000000000000000000000000000000000000000000000000000000LL;
U64 wm = 0b0000000000000000000000000000000000000000000111111111101111111111LL;
U64 wk = 0b0000000000000000000000000000000000000000000000000000000000000000LL;
U64 pos[5] = {bm, bk, wm, wk, 1};
printBoard(pos);
int total;
for(int i = 1; i<10;i++){
auto start = std::chrono::steady_clock::now();
total = perft(pos, i);
auto end = std::chrono::steady_clock::now();
int time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
if(time>0){
std::cout << "Perft("<< i <<")"<<" N = " << total << " Kn/s: " << total/time << "\n";
} else {
std::cout << "Perft("<< i <<")"<<" N = " << total << " Kn/s: 0\n";
}
}
return 0;
}