Skip to content

Commit

Permalink
bugfix: long castling not returning proper UOI notation
Browse files Browse the repository at this point in the history
- this made long castling impossible using any notation other than SAN and depth calculation was thrown off since long castling and Kc1 appeared to be the same move.
  • Loading branch information
dechristopher committed Mar 3, 2021
1 parent 184c52e commit 4de4072
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 12 deletions.
4 changes: 4 additions & 0 deletions board.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,12 +261,16 @@ func moveCastledPieces(b *Board, p1 Piece, m *Move) {
b.bbWhitePawn = (b.bbWhitePawn & ^bbForSquare(C1)) | bbForSquare(B1)
} else if p1.Color() == White && m.HasTag(FarPawnCastle) {
b.bbWhitePawn = (b.bbWhitePawn & ^bbForSquare(D1)) | bbForSquare(B1)
// finagle the king back to C1 since move is technically to D1
b.bbWhiteKing = (b.bbWhiteKing & ^bbForSquare(D1)) | bbForSquare(C1)
} else if p1.Color() == Black && m.HasTag(KnightCastle) {
b.bbBlackKnight = (b.bbBlackKnight & ^bbForSquare(D4)) | bbForSquare(C4)
} else if p1.Color() == Black && m.HasTag(ClosePawnCastle) {
b.bbBlackPawn = (b.bbBlackPawn & ^bbForSquare(B4)) | bbForSquare(C4)
} else if p1.Color() == Black && m.HasTag(FarPawnCastle) {
b.bbBlackPawn = (b.bbBlackPawn & ^bbForSquare(A4)) | bbForSquare(C4)
// finagle the king back to B4 since move is technically to A4
b.bbBlackKing = (b.bbBlackKing ^ bbForSquare(A4)) | bbForSquare(B4)
}
}

Expand Down
4 changes: 2 additions & 2 deletions engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ func castleMoves(pos *Position) []*Move {
(^pos.board.emptySqs&(bbForSquare(C1))) == 0 &&
!squaresAreAttacked(pos, C1) &&
!pos.inCheck {
m := &Move{s1: B1, s2: C1}
m := &Move{s1: B1, s2: D1}
m.addTag(FarPawnCastle)
addTags(m, pos)
moves = append(moves, m)
Expand Down Expand Up @@ -249,7 +249,7 @@ func castleMoves(pos *Position) []*Move {
(^pos.board.emptySqs&(bbForSquare(B4))) == 0 &&
!squaresAreAttacked(pos, B4) &&
!pos.inCheck {
m := &Move{s1: C4, s2: B4}
m := &Move{s1: C4, s2: A4}
m.addTag(FarPawnCastle)
addTags(m, pos)
moves = append(moves, m)
Expand Down
10 changes: 5 additions & 5 deletions move_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ type perfTest struct {
// https://www.chessprogramming.org/Perft_Results
var perfResults = []perfTest{
{pos: unsafeOFEN("ppkn/4/4/NKPP w NCFncf - 0 1"), nodesPerDepth: []int{
10, 84, 642, 4348, 29171, 183118,
10, 84, 642, 4348, 29382, 185195,
}},
{pos: unsafeOFEN("ppkn/4/2P1/NK1P w NCFncf - 0 1"), nodesPerDepth: []int{
10, 75, 538, 3407,
10, 75, 548, 3483,
}},
}

Expand Down Expand Up @@ -58,9 +58,9 @@ func countMoves(t *testing.T, originalPosition *Position, positions []*Position,
t.Log("##############################")
t.Log("# Details in JSONL (https://jsonlines.org)")
t.Log("###")
for _, pos := range positions {
t.Logf(`{"position": "%s", "moves": %d}`, pos.String(), len(pos.ValidMoves()))
}
//for _, pos := range positions {
// //t.Logf(`{"position": "%s", "moves": %d}`, pos.String(), len(pos.ValidMoves()))
//}
}
countMoves(t, originalPosition, newPositions, nodesPerDepth[1:], maxDepth)
}
Expand Down
9 changes: 4 additions & 5 deletions notation.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,21 +71,20 @@ func (UOINotation) Decode(pos *Position, s string) (*Move, error) {
}
p := pos.Board().Piece(s1)
p2 := pos.Board().Piece(s2)
// TODO formally verify this decoding
// TODO make sure piece destinations and criteria make sense

if p.Type() == King {
if ((s1 == B1 && s2 == A1) || (s1 == C4 && s2 == D4)) && p2.Type() == Knight && p.Color() == p2.Color() {
m.addTag(KnightCastle)
} else if ((s1 == B1 && s2 == C1) || (s1 == C4 && s2 == B4)) && p2.Type() == Pawn && p.Color() == p2.Color() {
m.addTag(ClosePawnCastle)
} else if ((s1 == B1 && s2 == D1) || (s1 == C4 && s2 == A4)) && p2.Type() == Pawn && p.Color() == p2.Color() {
m.addTag(FarPawnCastle)
fmt.Println("FAR PAWN CASTLE")
}
} else if p.Type() == Pawn && s2 == pos.enPassantSquare {
m.addTag(EnPassant)
m.addTag(Capture)
}

c1 := p.Color()
c2 := pos.Board().Piece(s2).Color()
if c2 != NoColor && c1 != c2 {
Expand All @@ -95,8 +94,8 @@ func (UOINotation) Decode(pos *Position, s string) (*Move, error) {
}

// AlgebraicNotation (or Standard Algebraic Notation) is the
// official octad notation used by FIDE. Examples: e4, e5,
// O-O (short castling), e8=Q (promotion)
// official octad notation used by FIDE. Examples: c2, b3,
// O-O (short castling), d4=Q (promotion)
type AlgebraicNotation struct{}

// String implements the fmt.Stringer interface and returns
Expand Down

0 comments on commit 4de4072

Please sign in to comment.