我正在尝试检测检查和将死,并通过拿走检查的棋子,移动到检查的棋子前面或将国王从检查中移开来阻止检查。
当我在黑色棋子上尝试时,Check 和 Checkmate 也不起作用。
这个是一个程序没有检测到将死的例子。程序说它是 check 但不是 checkmate
照片中的董事会状态:
chessboard = [
[" ", "BN", "BB", " ", "BK", " ", "BN", " "],
[" ", "BP", "BP", "BP", " ", "BP", " ", " "],
[" ", " ", " ", " ", "BP", " ", " ", "BP"],
["BP", " ", " ", " ", " ", " ", "BP", " "],
[" ", "BB", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " ", " "],
["WP", "WP", "WP", "BQ", " ", "BR", " ", "WP"],
["WR", " ", " ", " ", "WK", "BR", " ", " "]]
检查和将死的功能:
def is_king_in_check(chessboard, king_color):
"""
Given a chessboard and the color of the king (either 'W' for white or 'B' for black),
returns True if the king is in check, False otherwise.
"""
# Find the king's location on the board
for row in range(8):
for col in range(8):
piece = chessboard[row][col]
if piece == king_color + 'K':
king_location = (row, col)
break
# Check if any of the opponent's pieces can attack the king
opponent_color = 'B' if king_color == 'W' else 'W'
for row in range(8):
for col in range(8):
piece = chessboard[row][col]
if piece[0] == opponent_color:
if is_legal_pawn_move(row, col, king_location[0], king_location[1], chessboard):
# King is in check
return True
# King is not in check
return False
def is_checkmate(chessboard, king_color):
"""
Given a chessboard and the color of the king (either 'W' for white or 'B' for black),
returns True if the king is in checkmate, False otherwise.
"""
# Find the king's location on the board
for row in range(8):
for col in range(8):
piece = chessboard[row][col]
if piece == king_color + 'K':
king_location = (row, col)
break
# Check if the king can move to a safe square
for i in range(king_location[0] - 1, king_location[0] + 2):
for j in range(king_location[1] - 1, king_location[1] + 2):
if (i, j) == king_location or i < 0 or i > 7 or j < 0 or j > 7:
continue
if is_legal_pawn_move(king_location[0], king_location[1], i, j, chessboard):
# King can move to safety
return False
# Check if any of the king's pieces can capture the checking piece
opponent_color = 'B' if king_color == 'W' else 'W'
for row in range(8):
for col in range(8):
piece = chessboard[row][col]
if piece[0] == king_color:
if is_legal_pawn_move(row, col, king_location[0], king_location[1], chessboard):
# Another piece can capture the checking piece or block the check
return False
# King is in
print('mate')
return True
完整节目:
import pygame
import os
import sys
import pygame_gui
# Define some colors
BLACK = ('#B58863')
WHITE = ('#F0D9B5')
# Set the dimensions of the chessboard squares
WIDTH = 80
HEIGHT = 80
WK_moved = False
BK_moved = False
BR_moved = False
WR_moved = False
BR_moved_1 = False
WR_moved_1 = False
Move_History = []
check = 0
pygame.mixer.init()
move_sound = pygame.mixer.Sound("move.mp3")
# Initialize pygame
pygame.init()
# Set the size of the window and create it
size = (WIDTH * 8, HEIGHT * 8)
screen = pygame.display.set_mode(size)
# Draw the chessboard
# Define the initial state of the chessboard
chessboard = [
["BR", "BN", "BB", "BQ", "BK", "BB", "BN", "BR"],
["BP", "BP", "BP", "BP", "BP", "BP", "BP", "BP"],
[" ", " ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " ", " "],
["WP", "WP", "WP", "WP", "WP", "WP", "WP", "WP"],
["WR", "WN", "WB", "WQ", "WK", "WB", "WN", "WR"]
]
# Load the piece images
piece_images = {}
for file_name in os.listdir("."):
if file_name.endswith(".png"):
piece_name = file_name.split(".")[0].upper()
piece_images[piece_name] = pygame.image.load(file_name).convert_alpha()
piece_images[piece_name] = pygame.transform.scale(piece_images[piece_name], (WIDTH, HEIGHT))
# Define a function to draw the chessboard
def redraw_board():
for row in range(8):
for column in range(8):
if (row + column) % 2 == 0:
color = WHITE
else:
color = BLACK
pygame.draw.rect(screen, color, [WIDTH * column, HEIGHT * row, WIDTH, HEIGHT])
# Color the square of the previously moved piece
if row == prev_drag_row and column == prev_drag_col:
if (row + column) % 2 == 0:
pygame.draw.rect(screen, ('#C9D868'), [WIDTH * column, HEIGHT * row, WIDTH, HEIGHT])
else:
pygame.draw.rect(screen, ('#A4A937'), [WIDTH * column, HEIGHT * row, WIDTH, HEIGHT])
# Color the square of the current moved piece
if row == drag_row and column == drag_col:
if (row + column) % 2 == 0:
pygame.draw.rect(screen, ('#C9D868'), [WIDTH * column, HEIGHT * row, WIDTH, HEIGHT])
else:
pygame.draw.rect(screen, ('#A4A937'), [WIDTH * column, HEIGHT * row, WIDTH, HEIGHT])
# Draw the row numbers
if column == 0:
font = pygame.font.SysFont('robotomedium', 15)
if row % 2 == 0:
number_label = font.render(str(8 - row), True, BLACK)
else:
number_label = font.render(str(8 - row), True, WHITE)
screen.blit(number_label, (5, HEIGHT * row + 5))
# Draw the column letters
if row == 7:
font = pygame.font.SysFont('robotomedium', 15)
if column % 2 == 0:
letter_label = font.render(chr(97 + column), True, WHITE)
else:
letter_label = font.render(chr(97 + column), True, BLACK)
screen.blit(letter_label, (WIDTH * column + 68, HEIGHT * row + 60))
# Draw the pieces
piece = chessboard[row][column]
if piece != " ":
img = piece_images[piece]
screen.blit(img, (WIDTH * column, HEIGHT * row))
def check_promotion(legal_move_, start_row, start_col, end_col, end_row):
global legal_move
if piece[1] == "P" and (end_row == 0 or end_row == 7) and legal_move == True:
legal_move = False
# Promote the pawn
promotion = input("Choose a piece to promote to (Q, R, B, or N): ")
while promotion not in ["Q", "R", "B", "N"]:
promotion = input("Invalid choice. Choose a piece to promote to (Q, R, B, or N): ")
if piece[0] == "W":
if promotion == "Q":
chessboard[end_row][end_col] = "WQ"
chessboard[start_row][start_col] = " "
elif promotion == "R":
chessboard[end_row][end_col] = "WR"
chessboard[start_row][start_col] = " "
elif promotion == "B":
chessboard[end_row][end_col] = "WB"
chessboard[start_row][start_col] = " "
else:
chessboard[end_row][end_col] = "WN"
chessboard[start_row][start_col] = " "
else:
print(start_row,start_col)
print(end_row,end_col)
if promotion == "Q":
chessboard[end_row][end_col] = "BQ"
chessboard[start_row][start_col] = " "
elif promotion == "R":
chessboard[end_row][end_col] = "BR"
chessboard[start_row][start_col] = " "
elif promotion == "B":
chessboard[end_row][end_col] = "BB"
chessboard[start_row][start_col] = " "
else:
chessboard[end_row][end_col] = "BN"
chessboard[start_row][start_col] = " "
def is_king_in_check(chessboard, king_color):
"""
Given a chessboard and the color of the king (either 'W' for white or 'B' for black),
returns True if the king is in check, False otherwise.
"""
# Find the king's location on the board
for row in range(8):
for col in range(8):
piece = chessboard[row][col]
if piece == king_color + 'K':
king_location = (row, col)
break
# Check if any of the opponent's pieces can attack the king
opponent_color = 'B' if king_color == 'W' else 'W'
for row in range(8):
for col in range(8):
piece = chessboard[row][col]
if piece[0] == opponent_color:
if is_legal_pawn_move(row, col, king_location[0], king_location[1], chessboard):
# King is in check
return True
# King is not in check
return False
def is_checkmate(chessboard, king_color):
"""
Given a chessboard and the color of the king (either 'W' for white or 'B' for black),
returns True if the king is in checkmate, False otherwise.
"""
# Find the king's location on the board
for row in range(8):
for col in range(8):
piece = chessboard[row][col]
if piece == king_color + 'K':
king_location = (row, col)
break
# Check if the king can move to a safe square
for i in range(king_location[0] - 1, king_location[0] + 2):
for j in range(king_location[1] - 1, king_location[1] + 2):
if (i, j) == king_location or i < 0 or i > 7 or j < 0 or j > 7:
continue
if is_legal_pawn_move(king_location[0], king_location[1], i, j, chessboard):
# King can move to safety
return False
# Check if any of the king's pieces can capture the checking piece
opponent_color = 'B' if king_color == 'W' else 'W'
for row in range(8):
for col in range(8):
piece = chessboard[row][col]
if piece[0] == king_color:
if is_legal_pawn_move(row, col, king_location[0], king_location[1], chessboard):
# Another piece can capture the checking piece or block the check
return False
# King is in
print('mate')
return True
def is_legal_pawn_move(start_row, start_col, end_row, end_col, chessboard):
global WK_moved, BK_moved, WR_moved, WR_moved_1, BR_moved, BR_moved_1, legal_move
piece = chessboard[start_row][start_col]
legal_move = False
# Check for legal pawn moves
if piece == "WK" or piece == "BK":
# Check for legal king moves, including castling
if abs(start_row - end_row) <= 1 and abs(start_col - end_col) <= 1:
if chessboard[end_row][end_col][0] != piece[0]:
if piece == 'WK':
WK_moved = True
elif piece == 'BK':
BK_moved = True
return True, BK_moved, WK_moved
else:
return False
elif start_row == end_row and abs(start_col - end_col) == 2:
# Castling move
if piece == "WK" and start_row == 7 and WK_moved == False:
if start_col == 4 and end_col == 6 and chessboard[7][5] == " " and chessboard[7][6] == " " and chessboard[7][7] == "WR" and WR_moved == False:
chessboard[7][5] = "WR"
chessboard[7][7] = " "
WK_moved = True
return True
elif start_col == 4 and end_col == 2 and chessboard[7][1] == " " and chessboard[7][2] == " " and chessboard[7][3] == " " and chessboard[7][0] == "WR" and WR_moved_1 == False:
chessboard[7][3] = "WR"
chessboard[7][0] = " "
WK_moved = True
return True
else:
return False
elif piece == "BK" and start_row == 0 and BK_moved == False:
if start_col == 4 and end_col == 6 and chessboard[0][5] == " " and chessboard[0][6] == " " and chessboard[0][7] == "BR" and BR_moved == False:
chessboard[0][5] = "BR"
chessboard[0][7] = " "
BK_moved = True
return True
elif start_col == 4 and end_col == 2 and chessboard[0][1] == " " and chessboard[0][2] == " " and chessboard[0][3] == " " and chessboard[0][0] == "BR" and BR_moved_1 == False:
chessboard[0][3] = "BR"
chessboard[0][0] = " "
BK_moved = True
return True
else:
return False
else:
return False
else:
return False
elif piece == "WQ" or piece == "BQ":
# Queen moves can be a combination of rook and bishop moves
if start_row == end_row:
# Horizontal move
if start_col < end_col:
# Moving right
for col in range(start_col + 1, end_col):
if chessboard[start_row][col] != " ":
return False
else:
# Moving left
for col in range(start_col - 1, end_col, -1):
if chessboard[start_row][col] != " ":
return False
if chessboard[end_row][end_col][0] != piece[0] or chessboard[end_row][end_col] == " ":
return True
else:
return False
elif start_col == end_col:
# Vertical move
if start_row < end_row:
# Moving down
for row in range(start_row + 1, end_row):
if chessboard[row][start_col] != " ":
return False
else:
# Moving up
for row in range(start_row - 1, end_row, -1):
if chessboard[row][start_col] != " ":
return False
if chessboard[end_row][end_col][0] != piece[0] or chessboard[end_row][end_col] == " ":
return True
else:
return False
elif abs(start_row - end_row) == abs(start_col - end_col):
# Diagonal move
if start_row < end_row:
# Moving down
if start_col < end_col:
# Moving right
for i in range(1, end_row - start_row):
if chessboard[start_row + i][start_col + i] != " ":
return False
else:
# Moving left
for i in range(1, end_row - start_row):
if chessboard[start_row + i][start_col - i] != " ":
return False
else:
# Moving up
if start_col < end_col:
# Moving right
for i in range(1, start_row - end_row):
if chessboard[start_row - i][start_col + i] != " ":
return False
else:
# Moving left
for i in range(1, start_row - end_row):
if chessboard[start_row - i][start_col - i] != " ":
return False
if chessboard[end_row][end_col][0] != piece[0] or chessboard[end_row][end_col] == " ":
return True
else:
return False
elif piece == "WR" or piece == "BR":
if start_row == end_row:
# Horizontal move
if start_col < end_col:
# Moving right
for col in range(start_col + 1, end_col):
if chessboard[start_row][col] != " ":
return False
else:
# Moving left
for col in range(start_col - 1, end_col, -1):
if chessboard[start_row][col] != " ":
return False
if chessboard[end_row][end_col][0] != piece[0] or chessboard[end_row][end_col] == " ":
if start_row == end_row or start_col == end_col:
if piece[0] == 'W':
if start_row == 7 and start_col == 0:
WR_moved_1 = True
elif start_row == 7 and start_col == 7:
WR_moved = True
return True, WR_moved, BR_moved
else:
if start_row == 0 and start_col == 0:
BR_moved_1 = True
elif start_row == 0 and start_col == 7:
BR_moved = True
return True, WR_moved, BR_moved
else:
return False
elif start_col == end_col:
# Vertical move
if start_row < end_row:
# Moving down
for row in range(start_row + 1, end_row):
if chessboard[row][start_col] != " ":
return False
else:
# Moving up
for row in range(start_row - 1, end_row, -1):
if chessboard[row][start_col] != " ":
return False
if chessboard[end_row][end_col][0] != piece[0] or chessboard[end_row][end_col] == " ":
if start_row == end_row or start_col == end_col:
if piece[0] == 'W':
if start_row == 7 and start_col == 0:
WR_moved_1 = True
elif start_row == 7 and start_col == 7:
WR_moved = True
return True, WR_moved, BR_moved
else:
if start_row == 0 and start_col == 0:
BR_moved_1 = True
elif start_row == 0 and start_col == 7:
BR_moved = True
return True, WR_moved, BR_moved
else:
return False
elif piece == "WP":
if start_col == end_col and end_row == start_row - 1 and chessboard[end_row][end_col] == " ":
legal_move = True
elif start_col == end_col and start_row == 6 and end_row == 4 and chessboard[4][end_col] == " " and chessboard[5][end_col] == " ":
legal_move = True
elif abs(start_col - end_col) == 1 and end_row == start_row - 1 and chessboard[end_row][end_col] != " " and chessboard[end_row][end_col][0] == "B":
legal_move = True
else:
legal_move = False
# Check if it is the pawn's first move
if start_row == 6 and end_row == 4 and start_col == end_col and chessboard[4][end_col] == " " and chessboard[5][end_col] == " ":
legal_move = True
check_promotion(legal_move, start_row, start_col, end_col, end_row)
elif piece == "BP":
if start_col == end_col and end_row == start_row + 1 and chessboard[end_row][end_col] == " ":
legal_move = True
elif start_col == end_col and start_row == 1 and end_row == 3 and chessboard[3][end_col] == " " and chessboard[2][end_col] == " ":
legal_move = True
elif abs(start_col - end_col) == 1 and end_row == start_row + 1 and chessboard[end_row][end_col] != " " and chessboard[end_row][end_col][0] == "W":
legal_move = True
else:
legal_move = False
# Check if it is the pawn's first move
if start_row == 1 and end_row == 3 and start_col == end_col and chessboard[3][end_col] == " " and chessboard[2][end_col] == " ":
legal_move = True
check_promotion(legal_move, start_row, start_col, end_col, end_row)
elif piece == "WN" or piece == "BN":
if (abs(start_row - end_row) == 2 and abs(start_col - end_col) == 1) or \
(abs(start_row - end_row) == 1 and abs(start_col - end_col) == 2):
# Knight moves two squares in one direction and one square perpendicular to that direction
if chessboard[end_row][end_col][0] != piece[0] or chessboard[end_row][end_col] == " ":
legal_move = True
else:
legal_move = False
else:
legal_move = False
elif piece == "BB" or piece == "WB":
if abs(start_row - end_row) == abs(start_col - end_col):
# Bishop moves diagonally
if start_row < end_row:
# Bishop moves down
if start_col < end_col:
# Bishop moves down-right
for i in range(1, end_row - start_row):
if chessboard[start_row + i][start_col + i] != " ":
return False
else:
# Bishop moves down-left
for i in range(1, end_row - start_row):
if chessboard[start_row + i][start_col - i] != " ":
return False
else:
# Bishop moves up
if start_col < end_col:
# Bishop moves up-right
for i in range(1, start_row - end_row):
if chessboard[start_row - i][start_col + i] != " ":
return False
else:
# Bishop moves up-left
for i in range(1, start_row - end_row):
if chessboard[start_row - i][start_col - i] != " ":
return False
# Check if the bishop is taking an opponent's piece
if chessboard[end_row][end_col][0] != piece[0] or chessboard[end_row][end_col] == " ":
return True
else:
return False
else:
return False
else:
legal_move = False
return legal_move
def save_move(start_row, start_col, end_row, end_col):
global Move_History
piece = chessboard[end_row][end_col]
#os.system('cls')
rows = {0: '8', 1: '7', 2: '6', 3: '5', 4: '4', 5: '3', 6: '2', 7: '1'}
columns = {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f', 6: 'g', 7: 'h'}
row = rows[end_row]
col = columns[end_col]
if piece[1] == 'P':
move = col + row
else:
move = piece[1] + col + row
if move == 'Kg1' or move == 'Kg8':
move = 'O-O'
if move == 'Kc1' or move == 'Kc8':
move = 'O-O-O'
Move_History.append(move)
return move
# Main loop
running = True
dragging = False
prev_drag_row = -1
prev_drag_col = -1
drag_row = -1
drag_col = -1
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse_x, mouse_y = event.pos
row = mouse_y // HEIGHT
col = mouse_x // WIDTH
piece = chessboard[row][col]
if piece != " ":
dragging = True
drag_row = row
drag_col = col
img_path = os.path.join(f"{piece}.png")
img = pygame.image.load(img_path)
img = pygame.transform.scale(img, (WIDTH, HEIGHT))
elif event.type == pygame.MOUSEBUTTONUP:
if dragging:
mouse_x, mouse_y = event.pos
end_row = mouse_y // HEIGHT
end_col = mouse_x // WIDTH
if drag_row != end_row or drag_col != end_col:
if is_legal_pawn_move(drag_row, drag_col, end_row, end_col, chessboard):
chessboard[end_row][end_col] = chessboard[drag_row][drag_col]
chessboard[drag_row][drag_col] = " "
move_sound.play()
save_move(drag_row, drag_col, end_row, end_col)
#print('================================================','\n' + '# Move:',save_move(drag_row, drag_col, end_row, end_col),
# '\n'+'================================================')
#print(*chessboard, sep='\n')
print(is_king_in_check(chessboard,'W'))
print(is_checkmate(chessboard,'W'))
if is_king_in_check(chessboard,'W') == 'Check':
print('check')
else:
# Illegal move
pass
dragging = False
pygame.mixer.Sound.play(move_sound)
elif event.type == pygame.MOUSEMOTION and dragging:
mouse_x, mouse_y = event.pos
# Draw the dragged piece
img_rect = img.get_rect(center=(mouse_x, mouse_y))
screen.fill(BLACK)
redraw_board()
screen.blit(img, img_rect)
pygame.display.update()
# Redraw the board only if not dragging
if not dragging:
screen.fill(BLACK)
redraw_board()
pygame.display.update()
pygame.quit()
sys.exit()
我尝试了多种检测将死的方法。但它总是检测到它是将军,但事实并非如此。
我也可能会尝试使用 Chess 库,以便使用
.is_checkmate()
函数更容易检测将死。