aboutsummaryrefslogtreecommitdiff
path: root/src/main.c
blob: 0272073b0133c32a786e4de5b49ebf0096e9d074 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include "unittest.h"
#include "board.h"
#include "bitboard.h"

int main() {
  start_test_section("Bitboards"); {
    unit_test(pop_count(0b01110) == 3, "Pop count of 01110 is 3");

    Bitboard bb = 0b1100;
    unit_test(bitscanAndReset(&bb) == 2, "Bitscan of 0b1100 is 2");
    unit_test(bb == 0b1000, "After bitscan with reset the LS1B is flipped");
  }

  start_test_section("Default FEN string"); {
    Board board = parse_FEN("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
    unit_test(pop_count(board.pieces[PAWN] | board.pieces[PAWN | BLACK]) == 16, "There are 16 pawns total");
    unit_test(pop_count(board.pieces[ROOK]) == 2, "There are 2 white rooks");
    // TODO
    unit_test(board.side == WHITE, "Side to move is white");
    unit_test(board.castling_rights == 0, "Both sides can castle");
    unit_test(board.en_passant_square == 0, "No en passant move is avaialble");
  }

  start_test_section("Test knight attacks"); {
    Bitboard attacks[64];
    precompute_knight_attack_table(attacks);

    int max_attacks = 0;
    for (int i = 0; i < 64; i++) {
      int attack_count = pop_count(attacks[i]);
      if (attack_count > max_attacks) max_attacks = attack_count;
    }
    unit_test(max_attacks == 8, "Max amount of knight attacks should be 8");

    unit_test(
        attacks[b7] == ((BIT << d8) | (BIT << d6) | (BIT << c5) | (BIT << a5)),
        "Knight on b7 attacks only d8, d6, c5, a5"
    );
  }

  start_test_section("Test king attacks"); {
    Bitboard attacks[64];
    precompute_king_attack_table(attacks);

    int max_attacks = 0;
    for (int i = 0; i < 64; i++) {
      int attack_count = pop_count(attacks[i]);
      if (attack_count > max_attacks) max_attacks = attack_count;
    }
    unit_test(max_attacks == 8, "Max amount of king attacks should be 8");

    unit_test(
        attacks[h2] == ((BIT << h1) | (BIT << g1) | (BIT << g2) | (BIT << g3) | (BIT << h3)),
        "King on h2 attacks only h1, g1, g2, g3, h3"
    );
  }

  start_test_section("Test pawn attacks"); {
    Bitboard white_attacks[64];
    Bitboard black_attacks[64];

    precompute_pawn_attack_table(white_attacks, WHITE);
    precompute_pawn_attack_table(black_attacks, BLACK);

    int is_same = 0;
    int max_attacks = 0;
    for (int i = 0; i < 64; i++) {
      int attack_count = pop_count(white_attacks[i]);
      if (attack_count > max_attacks) max_attacks = attack_count;
      if (white_attacks[i] == black_attacks[i]) is_same = 1;
    }
    unit_test(max_attacks == 2, "Max amount of pawn attacks should be 2");
    unit_test(is_same == 0, "Black and white pawns always move differently");
    unit_test(white_attacks[g2] == (BIT << h3 | BIT << f3), "White pawn on g2 attacks only h3 and f3");
  }

  report();
  return 0;
}