[FIX] Chess Castling Fix

Rick McGeer rick at mcgeer.com
Sat Sep 18 23:26:13 UTC 2004


The Change set is on squeak map ( 
http://map1.squeakfoundation.org/sm/accountbyid/efec5a58-7329-4ea4-94aa-09897ab0bef8/files/ChessCastlingFix.6.cs) 
and attached here.

Cheers
Rick
-------------- next part --------------
'From Squeak3.6 of ''6 October 2003'' [latest update: #5424] on 16 September 2004 at 8:07:27 pm'!
SharedPool subclass: #ChessConstants
	instanceVariableNames: ''
	classVariableNames: 'A1 A2 A3 A4 A5 A6 A7 A8 B1 B2 B3 B4 B5 B6 B7 B8 Bishop BishopMovers BishopMoves C1 C2 C3 C4 C5 C6 C7 C8 CastlingDisableAll CastlingDisableKingSide CastlingDisableQueenSide CastlingDone CastlingEnableKingSide CastlingEnableQueenSide D1 D2 D3 D4 D5 D6 D7 D8 E1 E2 E3 E4 E5 E6 E7 E8 EmptySquare F1 F2 F3 F4 F5 F6 F7 F8 Foo G1 G2 G3 G4 G5 G6 G7 G8 H1 H2 H3 H4 H5 H6 H7 H8 King KingMoves Knight KnightMoves Pawn PieceCenterScores PieceValues Queen Rook RookMovers RookMoves '
	poolDictionaries: ''
	category: 'Morphic-Games-Chess'!

!ChessConstants class methodsFor: 'pool initialization' stamp: 'RM 9/16/2004 14:34'!
initialize
	"ChessConstants initialize"
	self initializePieceConstants.
	self initializeCastlingConstants.
	self initializePieceValues.
	self initializeMoves.
	self initializeCenterScores.
	self initializeBishopMovers.
	self initializeRookMovers.
	self initializeSquareConstants.! !

!ChessConstants class methodsFor: 'pool initialization' stamp: 'RM 9/16/2004 19:38'!
initializeBishopMovers.
	BishopMovers _ Set new.
	BishopMovers add:Bishop.
	BishopMovers add:Queen.! !

!ChessConstants class methodsFor: 'pool initialization' stamp: 'RM 9/16/2004 19:38'!
initializeRookMovers.
	RookMovers _ Set new.
	RookMovers add:Rook.
	RookMovers add:Queen.! !

!ChessConstants class methodsFor: 'pool initialization' stamp: 'RM 9/16/2004 14:34'!
initializeSquareConstants
	A1_1. B1_2. C1_3. D1_4. E1_5. F1_6. G1_7. H1_8.
	A2_9. B2_10. C2_11. D2_12. E2_13. F2_14. G2_15. H2_16.
	A3_17. B3_18. C3_19. D3_20. E3_21. F3_22. G3_23. H3_24.
	A4_25. B4_26. C4_27. D4_28. E4_29. F4_30. G4_31. H4_32.
	A5_33. B5_34. C5_35. D5_36. E5_37. F5_38. G5_39. H5_40.
	A6_41. B6_42. C6_43. D6_44. E6_45. F6_46. G6_47. H6_48.
	A7_49. B7_50. C7_51. D7_52. E7_53. F7_54. G7_55. H7_56.
	A8_57. B8_58. C8_59. D8_60. E8_61. F8_62. G8_63. H8_64.! !


!ChessMoveGenerator methodsFor: 'support' stamp: 'RM 9/16/2004 19:28'!
canCastleBlackKingSide
	(castlingStatus bitAnd: CastlingEnableKingSide) = 0 ifFalse:[^false].
	"Quickly check if all the squares are zero"
	((myPieces at: G8) + (myPieces at: F8) + (itsPieces at: G8) + (itsPieces at: F8) = 0) ifFalse:[^false].
	"Check for castling squares under attack..  See canCastleBlackQueenSide for details"
	(self checkAttack:{H7. H6. H5. H4. H3. H2. H1} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{G7. G6. G5. G4. G3. G2. G1} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{F7. F6. F5. F4. F3. F2. F1} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{E7. E6. E5. E4. E3. E2. E1.} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{D8. C8. B8. A8} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{G7. F6. E5. D4. C3. B2. A1} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{F7. E6. D5. C4. B3. A2} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{E7. D6. C5. B4. A3} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{D7. C6. B5. A4} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{F7. G6. H5} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{G7. H6} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{H7} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkUnprotectedAttack:{H7. G7. F7. E7. D7. C7. H6. G6. F6. E6. D6} fromPiece:Knight) ifTrue:[^false].
	(self checkUnprotectedAttack:{H7. G7. F7. E7. D7} fromPiece:Pawn) ifTrue:[^false].
	^true.
	
	
	
	
	! !

!ChessMoveGenerator methodsFor: 'support' stamp: 'RM 9/16/2004 19:26'!
canCastleBlackQueenSide
	(castlingStatus bitAnd: CastlingEnableQueenSide) = 0 ifFalse:[^false].
	"Quickly check if all the squares are zero"
	((myPieces at: B8) +  (myPieces at: C8) +  (myPieces at: D8) +
		(itsPieces at: B8) + (itsPieces at: C8) + (itsPieces at: D8) 
			= 0) ifFalse:[^false].
	"Check to see if any of the squares involved in castling are under attack.  First
	check for vertical (rook-like) attacks"
	(self checkAttack:{A7. A6. A5. A4. A3. A2. A1} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{B7. B6. B5. B4. B3. B2. B1} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{C7. C6. C5. C4. C3. C2. C1} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{D7. D6. D5. D4. D3. D2. D1} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{E7. E6. E5. E4. E3. E2. E1} fromPieces:RookMovers) ifTrue:[^false].
	"Check for a rook attack from the baseline"
	(self checkAttack:{F8. G8. H8} fromPieces:RookMovers) ifTrue:[^false].
	"Check for bishop attacks from the diagonals"
	(self checkAttack:{B7. C6. D5. E4. F3. G2. H1} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{C7. D6. E5. F4. G3. H2} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{D7. E6. F5. G4. H3} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{E7. F6. G5. H4} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{F7. G6. H5} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{A7} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{B7. A6} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{C7. B6. A5} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{D7. C6. B5. A4} fromPieces:BishopMovers) ifTrue:[^false].
	"Check for a knight attack"
	(self checkUnprotectedAttack:{A7. B7. C7. D7. E7. F7. G7. A6. B6. C6. D6. E6. F6} fromPiece:Knight) ifTrue:[^false].
	"check for a pawn attack"
	(self checkUnprotectedAttack:{A7. B7. C7. D7. E7. F7} fromPiece:Pawn) ifTrue:[^false].
	"check for a king attack"
	(self checkUnprotectedAttack:{B7. C7. } fromPiece:King) ifTrue:[^false].
	^true.
! !

!ChessMoveGenerator methodsFor: 'support' stamp: 'RM 9/16/2004 19:28'!
canCastleWhiteKingSide
	(castlingStatus bitAnd: CastlingEnableKingSide) = 0 ifFalse: [^false].
	"Quickly check if all the squares are zero"
	((myPieces at:G1) + (myPieces at:F1) + (itsPieces at:G1) + (itsPieces at:F1) = 0) ifFalse:[^false].
	"Check for castling squares under attack..  See canCastleBlackQueenSide for details"
	(self checkAttack:{H2. H3. H4. H5. H6. H7. H8} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{G2. G3. G4. G5. G6. G7. G8} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{F2. F3. F4. F5. F6. F7. F8} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{E2. E3. E4. E5. E6. E7. E8} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{A1. A2. A3. A4} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{G2. F3. E4. D5. C6. B7. A8} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{F2. E3. D4. C5. B6. A7} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{E2. D3. C4. B5. A6} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{D2. C3. B4. A5} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{F2. G3. H4} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{G2. H3} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{H2} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkUnprotectedAttack:{H2. G2. F2. E2. D2. C2. H3. G3. F3. E3. D3} fromPiece:Knight) ifTrue:[^false].
	(self checkUnprotectedAttack:{H2. G2. F2. E2. D2} fromPiece:Pawn) ifTrue:[^false].
	(self checkUnprotectedAttack:{G2} fromPiece:King) ifTrue:[^false].
	^true.! !

!ChessMoveGenerator methodsFor: 'support' stamp: 'RM 9/16/2004 19:28'!
canCastleWhiteQueenSide
	(castlingStatus bitAnd: CastlingEnableQueenSide) = 0 ifFalse: [^false].
	"Quickly check if all the squares are zero"
	((myPieces at:B1) + (myPieces at:C1) + (myPieces at:D1) +
	 (itsPieces at:B1) + (itsPieces at:C1) + (itsPieces at:D1) = 0) ifFalse:[^false].
	"Check for castling squares under attack..  See canCastleBlackQueenSide for details"
	(self checkAttack:{A2. A3. A4. A5. A6. A7. A8} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{B2. B3. B4. B5. B6. B7. B8} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{C2. C3. C4. C5. C6. C7. C8} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{D2. D3. D4. D5. D6. D7. D8} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{E2. E3. E4. E5. E6. E7. E8} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{F1. G1. H1} fromPieces:RookMovers) ifTrue:[^false].
	(self checkAttack:{B2. C3. D4. E5. F6. G7. H8} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{C2. D3. E4. F5. G6. H7} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{D2. E3. F4. G5. H6} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{E2. F3. G4. H5} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{F2. G3. H4} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{A2} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{B2. A3} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{C2. B3. A4} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkAttack:{D2. C3. B4. A5} fromPieces:BishopMovers) ifTrue:[^false].
	(self checkUnprotectedAttack:{A2. B2. C2. D2. E2. F2. G2. A3. B3. C3. D3. E3. F3} fromPiece:Knight) ifTrue:[^false].
	(self checkUnprotectedAttack:{A2. B2. C2. D2. E2. F2} fromPiece:Pawn) ifTrue:[^false].
	(self checkUnprotectedAttack:{B2. C2} fromPiece:King) ifTrue:[^false].
	^true.! !

!ChessMoveGenerator methodsFor: 'support' stamp: 'RM 9/16/2004 19:37'!
checkAttack:squares fromPieces:pieces
	"check for an unprotected attack along squares by one of pieces.  Squares is a list of 
	squares such that any piece in pieces can attack unless blocked by another piece.
	E.g., a Bishop of Queen on the file  B7 C6 D5 E4 F3 G2 H1 can attack A8 unless blocked by
	another piece.  To find out if A8 is under attack along B7 C6 D5 E4 F3 G2 H1, use
	checkAttack:{B7. C6.D5. E4. F3. G2. H1} fromPieces:BishopMovers.  Note the order is important;
	squares must be listed in increasing distance from the square of interest"

	squares do:[:sqr|
		"invariant: no piece has been seen on this file at all"
		"one of my pieces blocks any attack"
		(myPieces at:sqr) = 0 ifFalse:[^false].
		"One of its pieces blocks an attack unless it is the kind of piece that can move along this
		file: a Bishop or Queen for a diagonal and a Rook or Queen for a Horizontal or
		Verrtical File"
		(itsPieces at:sqr) = 0 ifFalse:[
			^pieces includes:(itsPieces at:sqr).
		].
		
	].
	"no pieces along file, no attack"
	^false.
	
	
! !

!ChessMoveGenerator methodsFor: 'support' stamp: 'RM 9/16/2004 19:38'!
checkUnprotectedAttack:squares fromPiece:piece
	"check to see if my opponent has a piece of type piece on any of squares.  In general, this
	is used because that piece could launch an attack on me from those squares".
	squares do:[:sqr|
		(itsPieces at:sqr) = piece ifTrue:[^true].
	].
	^false.
	
	
! !

ChessMoveGenerator removeSelector: #checkAttack:!
ChessMoveGenerator removeSelector: #checkAttacks:!
ChessMoveGenerator removeSelector: #checkBishopAttack:!
ChessMoveGenerator removeSelector: #checkKnightAttack:!
ChessMoveGenerator removeSelector: #checkPawnAttack:!
ChessMoveGenerator removeSelector: #checkRookAttack:!
ChessConstants initialize!
SharedPool subclass: #ChessConstants
	instanceVariableNames: ''
	classVariableNames: 'A1 A2 A3 A4 A5 A6 A7 A8 B1 B2 B3 B4 B5 B6 B7 B8 Bishop BishopMovers BishopMoves C1 C2 C3 C4 C5 C6 C7 C8 CastlingDisableAll CastlingDisableKingSide CastlingDisableQueenSide CastlingDone CastlingEnableKingSide CastlingEnableQueenSide D1 D2 D3 D4 D5 D6 D7 D8 E1 E2 E3 E4 E5 E6 E7 E8 EmptySquare F1 F2 F3 F4 F5 F6 F7 F8 G1 G2 G3 G4 G5 G6 G7 G8 H1 H2 H3 H4 H5 H6 H7 H8 King KingMoves Knight KnightMoves Pawn PieceCenterScores PieceValues Queen Rook RookMovers RookMoves '
	poolDictionaries: ''
	category: 'Morphic-Games-Chess'!


More information about the Squeak-dev mailing list