home /
            
                fornax /
            
            
                fornax-v4-0 /
            
                src /
            
                supplementary /
            
            perft.cpp
            perft.cpp
            
            
                
                
                
                
                //
//  perft.cpp
//  fornax3
//
//  Created by Anders on 24/12/2020.
//
#include <stdio.h>
#include "perft.hpp"
#include "../moving/movegen.hpp"
#include "../moving/makemove.hpp"
#include "../libs/stopwatch.h"
template<bool printmoves, color active>
static long perft_templ(Board* board, int depth) {
  constexpr color opp = COLOR_OPPOSITE(active);
  
  if (depth == 0) {
    return 1;
  }
  else if (depth == 1 && !printmoves) {
    evalmove moves[128];
    uint8_t length = movegen_generate<active>(board, moves);
    return length;
  }
  
  long count = 0;
  
  evalmove moves[128];
  uint8_t length = movegen_generate<active>(board, moves);
  for (uint8_t i = 0; i < length; ++i) {
    if (printmoves) parsing_printmove((move) moves[i]);
    makemove_make<active>(board, (move) moves[i]);
    long local = perft_templ<false, opp>(board, depth - 1);
    makemove_takeback<opp>(board, (move) moves[i]);
    count += local;
    if (printmoves) printf(" = %ld\n", local);
  }
  return count;
}
long perft(const Board* board, int depth, bool printmoves) {
  long start = stopwatch_wall_start();
  Board copy = *board;
  long total = board->active == WHITE
  ? (printmoves ? perft_templ<true, WHITE>(©, depth) : perft_templ<false, WHITE>(©, depth))
  : (printmoves ? perft_templ<true, BLACK>(©, depth) : perft_templ<false, BLACK>(©, depth));
  
  long time = stopwatch_wall_stop(start);
  if (printmoves) {
    printf("total = %ld", total);
    if (time > 0) printf(" (time = %.3fs mps = %ld)", (double) time / 1000, total * 1000 / time);
    printf("\n");
  }
  return total;
}