Skip to content

Commit 320ac5b

Browse files
optimize EvadesCheck()
1 parent c4a0db2 commit 320ac5b

File tree

1 file changed

+30
-38
lines changed

1 file changed

+30
-38
lines changed

move_validation.go

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,7 @@ func (brd *Board) LegalMove(m Move, inCheck bool) bool {
1919
// Moves generated while in check should already be legal, since we determine this
2020
// as a side-effect of generating evasions.
2121
func (brd *Board) AvoidsCheck(m Move, inCheck bool) bool {
22-
// return inCheck || brd.PseudolegalAvoidsCheck(m)
23-
if inCheck && !brd.PseudolegalAvoidsCheck(m) {
24-
fmt.Println("{!}")
25-
}
26-
return brd.PseudolegalAvoidsCheck(m)
22+
return inCheck || brd.PseudolegalAvoidsCheck(m)
2723
}
2824

2925
func (brd *Board) PseudolegalAvoidsCheck(m Move) bool {
@@ -36,6 +32,8 @@ func (brd *Board) PseudolegalAvoidsCheck(m Move) bool {
3632
} else {
3733
return pinnedCanMove(brd, m.From(), m.To(), brd.c, brd.Enemy())
3834
}
35+
case KNIGHT: // Knights can never move when pinned.
36+
return isPinned(brd, brd.AllOccupied(), m.From(), brd.c, brd.Enemy()) == BB(ANY_SQUARE_MASK)
3937
case KING:
4038
return !isAttackedBy(brd, brd.AllOccupied(), m.To(), brd.Enemy(), brd.c)
4139
default:
@@ -50,40 +48,38 @@ func (brd *Board) EvadesCheck(m Move) bool {
5048

5149
if piece == KING {
5250
return !isAttackedBy(brd, occAfterMove(brd.AllOccupied(), from, to), to, e, c)
53-
} else {
54-
occ := brd.AllOccupied()
55-
kingSq := brd.KingSq(c)
56-
threats := colorAttackMap(brd, occ, kingSq, e, c)
57-
58-
// TODO: EvadesCheck() called from non-check position in rare cases. Examples:
59-
// 5r1k/1b3p1p/pp3p1q/3n4/1P2R3/P2B1PP1/7P/6K1 w - - 0 1
60-
// 8/PPKR4/1Bn4P/3P3R/8/2p4r/pp4p1/r6k w - - 5 2 (r h3h5 x r)...?
51+
}
52+
occ := brd.AllOccupied()
53+
kingSq := brd.KingSq(c)
54+
threats := colorAttackMap(brd, occ, kingSq, e, c)
6155

62-
if threats == 0 {
63-
fmt.Println("info string EvadesCheck() called from non-check position!")
64-
brd.Print()
65-
m.Print()
66-
return brd.PseudolegalAvoidsCheck(m)
67-
}
56+
// TODO: EvadesCheck() called from non-check position in rare cases. Examples:
57+
// 5r1k/1b3p1p/pp3p1q/3n4/1P2R3/P2B1PP1/7P/6K1 w - - 0 1
58+
// 8/PPKR4/1Bn4P/3P3R/8/2p4r/pp4p1/r6k w - - 5 2 (r h3h5 x r)...?
6859

69-
if popCount(threats) > 1 {
70-
return false // only king moves can escape from double check.
71-
}
72-
if (threats|intervening[furthestForward(e, threats)][kingSq])&sqMaskOn[to] == 0 {
73-
return false // the moving piece must kill or block the attacking piece.
60+
if threats == 0 {
61+
fmt.Println("info string EvadesCheck() called from non-check position!")
62+
brd.Print()
63+
m.Print()
64+
fmt.Printf("King sq: %d\n", kingSq)
65+
fmt.Println(brd.InCheck())
66+
if !isBoardConsistent(brd) {
67+
panic("inconsistent board state")
7468
}
75-
if !pinnedCanMove(brd, from, to, c, e) {
76-
return false // the moving piece can't be pinned to the king.
77-
}
78-
if brd.enpTarget != SQ_INVALID && piece == PAWN && m.CapturedPiece() == PAWN && // En-passant
79-
brd.TypeAt(to) == EMPTY {
80-
occ = occAfterMove(occ, from, to) & sqMaskOff[brd.enpTarget]
69+
return brd.PseudolegalAvoidsCheck(m)
70+
}
8171

82-
return colorAttackMap(brd, occ, kingSq, e, c) == 0
83-
// return attacks_after_move(brd, occ, occ&brd.occupied[e], king_sq, e, c) == 0
84-
}
72+
if popCount(threats) > 1 {
73+
return false // only king moves can escape from double check.
74+
}
75+
if (threats|intervening[furthestForward(e, threats)][kingSq])&sqMaskOn[to] == 0 {
76+
return false // the moving piece must kill or block the attacking piece.
77+
}
78+
if brd.enpTarget != SQ_INVALID && piece == PAWN && m.CapturedPiece() == PAWN && // En-passant
79+
brd.TypeAt(to) == EMPTY {
80+
return isPinned(brd, occ&sqMaskOff[brd.enpTarget], from, c, e)&sqMaskOn[to] > 0
8581
}
86-
return true
82+
return pinnedCanMove(brd, from, to, c, e) // the moving piece can't be pinned to the king.
8783
}
8884

8985
// Determines if a move is otherwise legal for brd, without considering king safety.
@@ -95,10 +91,6 @@ func (brd *Board) ValidMove(m Move, inCheck bool) bool {
9591
piece, from, to, capturedPiece := m.Piece(), m.From(), m.To(), m.CapturedPiece()
9692
// Check that the piece is of the correct type and color.
9793
if brd.TypeAt(from) != piece || brd.pieces[c][piece]&sqMaskOn[from] == 0 {
98-
// if brd.TypeAt(from) == piece {
99-
// brd.Print()
100-
// m.Print()
101-
// }
10294
// fmt.Printf("No piece of this type available at from square!{%s}", m.ToString())
10395
return false
10496
}

0 commit comments

Comments
 (0)