Skip to content

Commit 15cc544

Browse files
authored
test: Add TestCastlingInteractions to validate castling behavior with pawn presence. (#83)
1 parent cc2b8b7 commit 15cc544

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

game_test.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2261,3 +2261,115 @@ func TestIgnoreInsufficientMaterialDraw(t *testing.T) {
22612261
t.Fatal("ignoreInsufficientMaterialDraw should be true after being ignored")
22622262
}
22632263
}
2264+
2265+
func TestCastlingInteractions(t *testing.T) {
2266+
tests := []struct {
2267+
name string
2268+
fen string
2269+
firstMove string
2270+
secondMove string
2271+
shouldAllow bool
2272+
}{
2273+
// No Pawns (Blocked)
2274+
{
2275+
name: "No Pawns: White O-O then Black O-O",
2276+
fen: "r3k2r/8/8/8/8/8/8/R3K2R w KQkq - 0 1",
2277+
firstMove: "O-O",
2278+
secondMove: "O-O",
2279+
shouldAllow: false,
2280+
},
2281+
{
2282+
name: "No Pawns: White O-O-O then Black O-O-O",
2283+
fen: "r3k2r/8/8/8/8/8/8/R3K2R w KQkq - 0 1",
2284+
firstMove: "O-O-O",
2285+
secondMove: "O-O-O",
2286+
shouldAllow: false,
2287+
},
2288+
{
2289+
name: "No Pawns: Black O-O then White O-O",
2290+
fen: "r3k2r/8/8/8/8/8/8/R3K2R b KQkq - 0 1",
2291+
firstMove: "O-O",
2292+
secondMove: "O-O",
2293+
shouldAllow: false,
2294+
},
2295+
{
2296+
name: "No Pawns: Black O-O-O then White O-O-O",
2297+
fen: "r3k2r/8/8/8/8/8/8/R3K2R b KQkq - 0 1",
2298+
firstMove: "O-O-O",
2299+
secondMove: "O-O-O",
2300+
shouldAllow: false,
2301+
},
2302+
// With Pawns (Allowed)
2303+
{
2304+
name: "With Pawns: White O-O then Black O-O",
2305+
fen: "r3k2r/5p2/8/8/8/8/5P2/R3K2R w KQkq - 0 1", // Pawns at f2, f7
2306+
firstMove: "O-O",
2307+
secondMove: "O-O",
2308+
shouldAllow: true,
2309+
},
2310+
{
2311+
name: "With Pawns: White O-O-O then Black O-O-O",
2312+
fen: "r3k2r/3p4/8/8/8/8/3P4/R3K2R w KQkq - 0 1", // Pawns at d2, d7
2313+
firstMove: "O-O-O",
2314+
secondMove: "O-O-O",
2315+
shouldAllow: true,
2316+
},
2317+
{
2318+
name: "With Pawns: Black O-O then White O-O",
2319+
fen: "r3k2r/5p2/8/8/8/8/5P2/R3K2R b KQkq - 0 1", // Pawns at f2, f7
2320+
firstMove: "O-O",
2321+
secondMove: "O-O",
2322+
shouldAllow: true,
2323+
},
2324+
{
2325+
name: "With Pawns: Black O-O-O then White O-O-O",
2326+
fen: "r3k2r/3p4/8/8/8/8/3P4/R3K2R b KQkq - 0 1", // Pawns at d2, d7
2327+
firstMove: "O-O-O",
2328+
secondMove: "O-O-O",
2329+
shouldAllow: true,
2330+
},
2331+
}
2332+
2333+
for _, tt := range tests {
2334+
t.Run(tt.name, func(t *testing.T) {
2335+
fen, err := FEN(tt.fen)
2336+
if err != nil {
2337+
t.Fatalf("Invalid FEN: %v", err)
2338+
}
2339+
g := NewGame(fen)
2340+
2341+
// Make first move
2342+
pos := g.Position()
2343+
m1, err := AlgebraicNotation{}.Decode(pos, tt.firstMove)
2344+
if err != nil {
2345+
t.Fatalf("Failed to decode first move %s: %v", tt.firstMove, err)
2346+
}
2347+
if err := g.Move(m1, nil); err != nil {
2348+
t.Fatalf("Failed to make first move %s: %v", tt.firstMove, err)
2349+
}
2350+
2351+
// Check if second move is valid
2352+
validMoves := g.ValidMoves()
2353+
isAllowed := false
2354+
2355+
// Determine expected tag based on second move string
2356+
var expectedTag MoveTag
2357+
if tt.secondMove == "O-O" {
2358+
expectedTag = KingSideCastle
2359+
} else {
2360+
expectedTag = QueenSideCastle
2361+
}
2362+
2363+
for _, m := range validMoves {
2364+
if m.HasTag(expectedTag) {
2365+
isAllowed = true
2366+
break
2367+
}
2368+
}
2369+
2370+
if isAllowed != tt.shouldAllow {
2371+
t.Errorf("Castling allowed: %v, want: %v", isAllowed, tt.shouldAllow)
2372+
}
2373+
})
2374+
}
2375+
}

0 commit comments

Comments
 (0)