-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcheck_analysis.py
111 lines (87 loc) · 4.02 KB
/
check_analysis.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import chess
import chess.pgn
import chess
import chess.pgn
def is_discovered_check(board, move):
"""
Determine if a move results in a discovered check.
A discovered check occurs when a piece moves, uncovering an attack by another piece (bishop, rook, or queen).
"""
# Copy the board state before the move
board_before_move = board.copy()
board_before_move.pop() # Undo the last move to analyze the position before the move
# Determine the side that gave the check
is_white_turn = board.turn # If it's White's turn, Black just moved
opponent_king_square = board_before_move.king(is_white_turn) # Opponent's king square
if opponent_king_square is None: # No king found (invalid state)
return False
# The square the moving piece moved from
moving_piece_square = move.from_square
for attacker_square, piece in board_before_move.piece_map().items():
if (
piece.color != board.turn # Rakip taşlar
and piece.piece_type in [chess.BISHOP, chess.ROOK, chess.QUEEN] # Açarak şahı oluşturabilecek taşlar
):
# Check if there's a direct line of attack to the king
ray = chess.SquareSet(chess.ray(attacker_square, opponent_king_square) or [])
if not ray: # No direct line
continue
if moving_piece_square in ray:
if board.is_attacked_by(piece.color, opponent_king_square):
if moving_piece_square != attacker_square:
print(f"Discovered check detected: Attacker {piece.symbol()} at {chess.square_name(attacker_square)}, King at {chess.square_name(opponent_king_square)}")
return True # Açarak şahı tespit edildis
return False
def is_double_check(board, move):
"""Check if the move results in a double check."""
board_before_move = board.copy()
board_before_move.pop()
king_square = board_before_move.king(not board_before_move.turn)
pre_move_attackers = list(board_before_move.attackers(not board_before_move.turn, king_square))
post_move_attackers = list(board.attackers(not board.turn, king_square))
# Double check happens if:
# 1. After the move, there are two or more attackers.
# 2. At least one of these attackers was NOT threatening the king before the move.
if len(post_move_attackers) > 1 and len(pre_move_attackers) < len(post_move_attackers):
return True
return False
def analyze_checks(game):
"""Analyze the game to count checks, double checks, and discovered checks."""
board = game.board()
white_checks = 0
black_checks = 0
white_double_checks = 0
black_double_checks = 0
white_discovered_checks = 0
black_discovered_checks = 0
wh_dc = []
bl_dc = []
for move in game.mainline_moves():
board.push(move)
if board.is_check():
# Debug: Print the move and the check
# print(f"Check detected: {move}, Turn: {'White' if board.turn else 'Black'}")
if not board.turn: # White gave check
white_checks += 1
if is_discovered_check(board, move):
wh_dc.append(move)
white_discovered_checks += 1
if is_double_check(board, move):
white_double_checks += 1
else: # Black gave check
black_checks += 1
if is_discovered_check(board, move):
bl_dc.append(move)
black_discovered_checks += 1
if is_double_check(board, move):
black_double_checks += 1
return {
"white_checks": white_checks,
"black_checks": black_checks,
"white_double_checks": white_double_checks,
"black_double_checks": black_double_checks,
"white_discovered_checks": white_discovered_checks,
"black_discovered_checks": black_discovered_checks,
"whdc" : wh_dc,
"bldc" : bl_dc
}