@@ -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.
2121func (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
2925func (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