Загрузка данных


            # 4. Захват кадра
            # Берем именно current_roi (выделенную рамку доски), чтобы координаты кликов совпадали
            sct_img = sct.grab(current_roi)
            frame = cv2.cvtColor(np.array(sct_img), cv2.COLOR_BGRA2BGR)

            cropped_board = crop_chess_board(frame)
            matrix, _ = scan_frame(cropped_board, color_database, templates_hog, ALL_PIECES)

            is_black = (active_color_code == 'b')

            if is_black:
                standard_matrix = flip_matrix_180(matrix)
            else:
                standard_matrix = matrix

            current_matrix = matrix

            if not is_valid_position(standard_matrix):
                change_timestamp = time.time()
                time.sleep(0.05)
                continue

            base_fen = matrix_to_fen(standard_matrix)
            raw_current_fen = f"{base_fen} {active_color_code} - - 0 1"

            current_opponent_state = extract_opponent_pieces(standard_matrix, active_color_code)

            # 5. ДЕТЕКТОР СТАБИЛЬНОСТИ
            if raw_current_fen != stable_fen:
                stable_fen = raw_current_fen
                change_timestamp = time.time()

            # 6. ТАЙМЕР ПОСЛЕ ИЗМЕНЕНИЯ ФИГУР ПРОТИВНИКА
            if (time.time() - change_timestamp) >= OPPONENT_MOVE_DELAY and stable_fen != last_analyzed_fen:
                if last_opponent_state is None:
                    opponent_moved = True
                else:
                    current_count = count_opponent_pieces(current_opponent_state)
                    last_count = count_opponent_pieces(last_opponent_state)
                    
                    # Противник сходил, если его состояние изменилось
                    # и количество его фигур не уменьшилось (т.е. это не мы съели его фигуру)
                    opponent_moved = (current_opponent_state != last_opponent_state) and (current_count >= last_count)

                last_opponent_state = current_opponent_state

                if opponent_moved:
                    if engine.enabled:
                        status_msg = "Противник сходил! Анализ Stockfish..."
                        status_str = "ВКЛ"
                        print_board(current_matrix, stable_fen, None, "Думает...", status_str, player_color_str, is_black=is_black, status_msg=status_msg)
                        
                        best_move, evaluation = engine.analyze_fen(stable_fen)
                        last_analyzed_fen = stable_fen
                        status_msg = "Ход найден! Наш ход."

                        # === ВЫПОЛНЕНИЕ АВТО-ХОДА ===
                        if best_move:
                            execute_move(best_move, current_roi, is_black=is_black)

                    else:
                        best_move, evaluation = None, "Движок отключен [S]"
                        last_analyzed_fen = stable_fen
                        status_msg = "Движок отключен"
                        
                    status_str = "ВКЛ" if engine.enabled else "ВЫКЛ"
                    print_board(current_matrix, stable_fen, best_move, evaluation, status_str, player_color_str, is_black=is_black, status_msg=status_msg)

            elapsed = time.time() - start_time
            time.sleep(max(0.001, 0.05 - elapsed))