Fulvio wrote:Thanks for the reply, I should have stated clearly my objective.
I profiled SCID code when exporting a database to PGN and discovered that a lot of time is spent testing for check/mate.
The current code works mostly like you suggested: it is only missing the cutoff.
Exporting 1 million games to PGN takes 74 seconds on my computer with the current code.
Implementing the cutoff reduce the time to 71 secs.
Removing the mate test: 67 sec.
Removing both the check and mate test: 54 sec.
Considering that most games have few positions with checks, my intuition is that there should be some trick to make thing faster.
Maybe with bitboards based on the king position, i do not know, but someone may have already researched this problem.
That's why I'm asking for suggestions.
Rethinking the problem and assuming the moves are all valid, you need to know three things:
1. Are there multiple moves to the to square by the same piece type?
2. Does the move give direct or discovered check?
3. Does the move give mate?
You do not need to generate moves to answer any of these questions.
Create an array of structures[from][to]:
struct {
BITMAP between;
BITMAP extend;
int attack;
} atks[64][64];
attack is a set of bits for which piece types on the from square could attack the to square:
1 - wp
2 - bp
4 - n
8 - b
0x10 - r
0x20 - q
between is a bitmap of the squares between the from square and the to square which need to be empty for a slider to attack (0 for non-sliders).
extend is a bitmap of the squares behind the from square which could give a discovered attack on the to square.
Now disambguation is done by:
for all other pieces of the same type:
if atks[square][to].attack and piece type bit
if (!(board & atks[square][to].between))
disambguate (you can check if the piece is pinned in the same way as discovered checks)
direct checks can be done by:
if atks[to][king sq].attack and piece type bit
if (!(board & atks[square][to].between))
it is check
discovered checks can be done by:
if atks[from][king sq].extend
if (!(board & atks[from][king sq].between)) // need to make move on board first for case of pawn or king move toward opposing king
if ((queen bitmap | (atks[from][king sq].attack & 8) ? bishop bitmap : rook bitmap) & atks[from][king sq].extend)
test each possible to see if it gives check
A simple way to test for checkmate is:
if (last move in game & in check)
remove checked king from board (to attack square behind king)
generate attacks
if all squares adjacent to king attacked or occupied by same color pieces it is checkmate.