Загрузка данных
import time
import keyboard
from analysis import ChessAnalyzer
import crop
class ChessLogic:
def __init__(self):
self.analyzer = ChessAnalyzer()
# Внутреннее состояние доски 8x8 в формате FEN символов ('P', 'n', ''...)
self.board_state = []
# Матрица булевых значений (True/False) от crop.py для сравнения изменений
self.last_crop_matrix = None
self.is_analyzed = False
self.active_color = 'w' # 'w' - белые, 'b' - черные
def convert_coords_to_notation(self, row, col):
"""Переводит индексы (0..7, 0..7) в шахматную нотацию (a8...h1)"""
files = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
ranks = ['8', '7', '6', '5', '4', '3', '2', '1']
return f"{files[col]}{ranks[row]}"
def start_initial_analysis(self):
"""Запускается ЕДИНОЖДЫ при нажатии клавиши 'S'"""
print("\n[!] Нажата 'S'. Первичный анализ фигур через analysis.py...")
# 1. Получаем расстановку фигур от analysis.py
self.board_state = self.analyzer.analyze_initial_board()
if self.board_state:
# 2. Фиксируем начальную матрицу занятости клеток от crop.py
crop_matrix, _ = crop.find_chessboard_strictly_1to1()
self.last_crop_matrix = crop_matrix
self.is_analyzed = True
print("[✓] Начальная позиция успешно зафиксирована!")
self.print_board()
print(f"Начальный FEN: {self.get_fen_string()}")
print("\n[*] Переход в режим авто-отслеживания ходов через crop.py...\n")
else:
print("[!] Ошибка: не удалось проанализировать доску.")
def get_fen_string(self):
"""Генерация строки FEN из текущего состояния памяти"""
if not self.board_state:
return ""
fen_rows = []
for row in self.board_state:
empty_count = 0
row_fen = ""
for cell in row:
if cell == "":
empty_count += 1
else:
if empty_count > 0:
row_fen += str(empty_count)
empty_count = 0
row_fen += cell
if empty_count > 0:
row_fen += str(empty_count)
fen_rows.append(row_fen)
position_fen = "/".join(fen_rows)
return f"{position_fen} {self.active_color} KQkq - 0 1"
def print_board(self):
"""Красивый вывод доски в консоль"""
if not self.board_state:
return
print("\n a b c d e f g h")
print(" +-------------------------------+")
for i, row in enumerate(self.board_state):
rank = 8 - i
row_str = " | ".join([p if p != "" else "." for p in row])
print(f"{rank} | {row_str} | {rank}")
print(" +-------------------------------+")
print(" a b c d e f g h\n")
def track_board_changes(self):
"""
Постоянный быстрой опрос от crop.py.
Сравнивает текущие True/False с предыдущими и определяет ход.
"""
if not self.is_analyzed or self.last_crop_matrix is None:
return
# Берем свежий статус занятости клеток от crop.py (работает быстро)
new_crop_matrix, _ = crop.find_chessboard_strictly_1to1()
if new_crop_matrix is None:
return
from_cells = [] # Клетки, где фигура пропала (True -> False)
to_cells = [] # Клетки, где фигура появилась (False -> True)
for r in range(8):
for c in range(8):
old_val = self.last_crop_matrix[r][c]
new_val = new_crop_matrix[r][c]
if old_val and not new_val:
from_cells.append((r, c))
elif not old_val and new_val:
to_cells.append((r, c))
# Ход считается завершенным, когда одна клетка освободилась и одна занялась
if len(from_cells) == 1 and len(to_cells) == 1:
from_row, from_col = from_cells[0]
to_row, to_col = to_cells[0]
moved_piece = self.board_state[from_row][from_col]
if moved_piece != "":
from_not = self.convert_coords_to_notation(from_row, from_col)
to_not = self.convert_coords_to_notation(to_row, to_col)
print(f"[⚡ CHESS MOVE]: {moved_piece} c {from_not} на {to_not}")
# Передвигаем фигуру в памяти logic.py
self.board_state[to_row][to_col] = moved_piece
self.board_state[from_row][from_col] = ""
# Меняем цвет очередности хода
self.active_color = 'b' if self.active_color == 'w' else 'w'
# Запоминаем новое состояние от crop
self.last_crop_matrix = new_crop_matrix
# Выводим обновившуюся доску и FEN
self.print_board()
print(f"Новый FEN: {self.get_fen_string()}\n")
# Если сменилась позиция при взятии (например, True -> True) или при рокировке,
# просто обновляем снимок матрицы, когда доска успокоится
elif len(from_cells) == 0 and len(to_cells) == 0:
pass
def run(self):
"""Главный цикл бота"""
print("=========================================")
print(" Шахматный бот запущен.")
print(" Нажмите 'S' для первоначального анализа.")
print("=========================================")
# Горячая клавиша для запуска анализа
keyboard.add_hotkey('s', self.start_initial_analysis)
try:
while True:
# Если анализ уже был — регулярно проверяем изменения через crop
if self.is_analyzed:
self.track_board_changes()
# Небольшая пауза между проверками (чтобы не перегружать ЦП)
time.sleep(0.15)
except KeyboardInterrupt:
print("\nПрограмма завершена.")
if __name__ == '__main__':
logic = ChessLogic()
logic.run()