Rev 33 | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 33 | pmbaty | 1 | #include "chess.h" |
| 2 | #include "data.h" |
||
| 3 | /* last modified 01/07/14 */ |
||
| 4 | /* |
||
| 5 | ******************************************************************************* |
||
| 6 | * * |
||
| 7 | * Attacks() is used to determine if <side> attacks <square>. The algorithm * |
||
| 8 | * is simple, and is based on the AttacksTo() algorithm, but, rather than * |
||
| 9 | * returning a bitmap of squares attacking <square> it returns a "1" as soon * |
||
| 10 | * as it finds anything that attacks <square>. * |
||
| 11 | * * |
||
| 12 | ******************************************************************************* |
||
| 13 | */ |
||
| 14 | int Attacks(TREE * RESTRICT tree, int side, int square) { |
||
| 15 | if ((rook_attacks[square] & (Rooks(side) | Queens(side))) |
||
| 16 | && (RookAttacks(square, |
||
| 17 | OccupiedSquares) & (Rooks(side) | Queens(side)))) |
||
| 18 | return 1; |
||
| 19 | if ((bishop_attacks[square] & (Bishops(side) | Queens(side))) |
||
| 20 | && (BishopAttacks(square, |
||
| 21 | OccupiedSquares) & (Bishops(side) | Queens(side)))) |
||
| 22 | return 1; |
||
| 23 | if (KnightAttacks(square) & Knights(side)) |
||
| 24 | return 1; |
||
| 25 | if (PawnAttacks(Flip(side), square) & Pawns(side)) |
||
| 26 | return 1; |
||
| 27 | if (KingAttacks(square) & Kings(side)) |
||
| 28 | return 1; |
||
| 29 | return 0; |
||
| 30 | } |
||
| 31 | |||
| 32 | /* last modified 01/07/14 */ |
||
| 33 | /* |
||
| 34 | ******************************************************************************* |
||
| 35 | * * |
||
| 36 | * AttacksTo() is used to produce a bitboard which is a map of all squares * |
||
| 37 | * that directly attack this <square>. The non-sliding pieces are trivial * |
||
| 38 | * to detect, but for sliding pieces, we use a bitboard trick. The idea is * |
||
| 39 | * to compute the squares a queen would attack, if it was standing on * |
||
| 40 | * <square> and then look at the last square attacked in each direction to * |
||
| 41 | * determine if it is a sliding piece that moves in the right direction. To * |
||
| 42 | * finish up, we simply need to Or() all these attackers together. * |
||
| 43 | * * |
||
| 44 | ******************************************************************************* |
||
| 45 | */ |
||
| 46 | uint64_t AttacksTo(TREE * RESTRICT tree, int square) { |
||
| 47 | uint64_t attacks = |
||
| 48 | (PawnAttacks(white, square) & Pawns(black)) | (PawnAttacks(black, |
||
| 49 | square) & Pawns(white)); |
||
| 50 | uint64_t bsliders = |
||
| 51 | Bishops(white) | Bishops(black) | Queens(white) | Queens(black); |
||
| 52 | uint64_t rsliders = |
||
| 53 | Rooks(white) | Rooks(black) | Queens(white) | Queens(black); |
||
| 54 | attacks |= KnightAttacks(square) & (Knights(black) | Knights(white)); |
||
| 55 | if (bishop_attacks[square] & bsliders) |
||
| 56 | attacks |= BishopAttacks(square, OccupiedSquares) & bsliders; |
||
| 57 | if (rook_attacks[square] & rsliders) |
||
| 58 | attacks |= RookAttacks(square, OccupiedSquares) & rsliders; |
||
| 59 | attacks |= KingAttacks(square) & (Kings(black) | Kings(white)); |
||
| 60 | return attacks; |
||
| 61 | } |
||
| 62 | |||
| 63 | /* last modified 01/07/14 */ |
||
| 64 | /* |
||
| 65 | ******************************************************************************* |
||
| 66 | * * |
||
| 67 | * AttacksFrom() is used to compute the set of squares the piece on <source> * |
||
| 68 | * attacks. * |
||
| 69 | * * |
||
| 70 | ******************************************************************************* |
||
| 71 | */ |
||
| 72 | uint64_t AttacksFrom(TREE * RESTRICT tree, int side, int source) { |
||
| 73 | |||
| 74 | switch (Abs(PcOnSq(source))) { |
||
| 75 | case queen: |
||
| 76 | return QueenAttacks(source, OccupiedSquares); |
||
| 77 | case rook: |
||
| 78 | return RookAttacks(source, OccupiedSquares); |
||
| 79 | case bishop: |
||
| 80 | return BishopAttacks(source, OccupiedSquares); |
||
| 81 | case knight: |
||
| 82 | return KnightAttacks(source); |
||
| 83 | case pawn: |
||
| 84 | return PawnAttacks(side, source); |
||
| 85 | case king: |
||
| 86 | return KingAttacks(source); |
||
| 87 | } |
||
| 88 | return 0; |
||
| 89 | } |
||
| 108 | pmbaty | 90 | |
| 91 | /* last modified 01/07/14 */ |
||
| 92 | /* |
||
| 93 | ******************************************************************************* |
||
| 94 | * * |
||
| 95 | * Attacked() is used to determine if <square> is attacked. It returns a * |
||
| 96 | * two bit value, 01 if <square> is attacked by <side>, 10 if <square> is * |
||
| 97 | * attacked by <enemy> and 11 if <square> is attacked by both sides. * |
||
| 98 | * * |
||
| 99 | ******************************************************************************* |
||
| 100 | */ |
||
| 101 | uint64_t Attacked(TREE * RESTRICT tree, int side, uint64_t squares) { |
||
| 102 | uint64_t bsliders, rsliders, set; |
||
| 103 | int square; |
||
| 104 | |||
| 105 | bsliders = Bishops(side) | Queens(side); |
||
| 106 | rsliders = Rooks(side) | Queens(side); |
||
| 107 | for (set = squares; set; set &= set - 1) { |
||
| 108 | square = LSB(set); |
||
| 109 | do { |
||
| 110 | if (KingAttacks(square) & Kings(side)) |
||
| 111 | break; |
||
| 112 | if (KnightAttacks(square) & Knights(side)) |
||
| 113 | break; |
||
| 114 | if (bishop_attacks[square] & bsliders && |
||
| 115 | BishopAttacks(square, OccupiedSquares) & bsliders) |
||
| 116 | break; |
||
| 117 | if (rook_attacks[square] & rsliders && |
||
| 118 | RookAttacks(square, OccupiedSquares) & rsliders) |
||
| 119 | break; |
||
| 120 | Clear(square, squares); |
||
| 121 | } while (0); |
||
| 122 | } |
||
| 123 | return squares; |
||
| 124 | } |