# BIgo Reader - Анализ частей доски и симметричных преобразований

## Дата: 21 октября 2025

---

## 📋 Краткое резюме

### ✅ Использование частей доски

**Статус:** Хранит информацию, но НЕ реализует отображение

**Найдено:**
- ✅ БД хранит `board_part` для каждой диаграммы
- ⚠️ Renderer НЕ использует эту информацию
- ⚠️ Всегда показывает Full Board

---

### ⚠️ Симметричные преобразования

**Статус:** Хранит информацию, но НЕ реализует преобразования

**Найдено:**
- ✅ БД хранит `symmetry` для каждой диаграммы
- ❌ Преобразования НЕ применяются при отображении
- ❌ Нет функций для работы с симметрией

---

## 🔍 Детальный анализ

### 1. Архитектура bigo_reader

```
bigo_reader/
├── data/
│   ├── db_manager.py           # SQLite (локальная БД)
│   ├── db_manager_pg.py        # PostgreSQL (сервер)
│   ├── flask_db_manager.py     # Flask API (study.baduk.org)
│   └── unified_manager.py      # Единый интерфейс
├── rendering/
│   └── board_renderer.py       # Упрощенный renderer (201 строка)
├── diagrams/
│   └── diagram_viewer.py       # Окно просмотра диаграмм (667 строк)
└── ui/
    └── main_window.py          # Главное окно
```

---

### 2. Хранение данных в БД

#### File: `bigo_reader/data/flask_db_manager.py` (line 291)

```python
return {
    'Diagram_ID': diagram.get('diagram_id'),
    'Diagram_Name': diagram.get('diagram_name', f'Diagram {diagram_id}'),
    'SGF': diagram.get('sgf_content', ''),
    'Board_Part': diagram.get('board_part', 'full'),  # ✅ Хранится
    'Width': diagram.get('width'),
    'Height': diagram.get('height'),
    'Symmetry': diagram.get('symmetry'),              # ✅ Хранится
    'Base_Language': diagram.get('base_language', 'en'),
}
```

**Вывод:**
- ✅ Flask API возвращает `board_part` и `symmetry`
- ✅ Данные доступны в diagram_data
- ❌ НО не используются при рендеринге!

---

### 3. Renderer - Упрощенная версия

#### File: `bigo_reader/rendering/board_renderer.py` (201 строка)

**Текущая реализация:**
```python
class GoBoardRenderer:
    """Simplified Go board renderer for diagram viewing."""
    
    def __init__(self, canvas, board, settings, cell_size=30, margin=40):
        self.canvas = canvas
        self.board = board
        self.settings = settings  # ⚠️ Не проверяет board_type
        self.cell_size = cell_size
        self.margin = margin
        
    def draw_board(self):
        """Draw the complete board with stones and markups."""
        # ❌ Всегда рисует полную доску
        # ❌ Не проверяет settings["board_type"]
        # ❌ Не использует board_part из БД
        
        board_width = (self.num_x - 1) * self.cell_size
        board_height = (self.num_y - 1) * self.cell_size
        
        # Рисует сетку для всей доски
        for i in range(self.num_x):  # ❌ Всегда от 0 до num_x
            # ...
```

**Проблемы:**
1. ❌ Не поддерживает `board_type` (Corner, Side, Center)
2. ❌ Не читает `board_part` из БД
3. ❌ Всегда показывает полную доску (Full Board)
4. ⚠️ Упрощенная версия (201 строка vs 660 в bigo_editor)

---

### 4. Diagram Viewer - Использование renderer

#### File: `bigo_reader/diagrams/diagram_viewer.py` (line 55)

```python
# Board settings
self.settings: Dict[str, Any] = {
    "board_type": "Full Board",    # ❌ Hardcoded!
    "cell_size": 32,
    "show_coordinates": True,
    "show_move_numbers": True,
}
```

**Проблема:**
- ❌ `board_type` всегда "Full Board"
- ❌ Не читает `board_part` из БД
- ❌ Игнорирует информацию о части доски

#### Где создается renderer (line 303):

```python
self.board_renderer = GoBoardRenderer(
    canvas=self.canvas,
    board=self.go_board,
    settings=self.settings,  # ⚠️ Всегда "Full Board"
    cell_size=self.settings.get("cell_size", 32),
    margin=40
)
```

---

### 5. Симметричные преобразования

#### БД хранит, но НЕ использует:

```python
# В flask_db_manager.py (line 294):
'Symmetry': diagram.get('symmetry'),  # ✅ Получено из API
```

**Проблемы:**
1. ❌ Нет функций для применения симметрии
2. ❌ SGF загружается "как есть" без преобразований
3. ❌ Значение `symmetry` игнорируется

#### Где нужно применять (diagram_viewer.py, line 232):

```python
def _parse_sgf(self, sgf_text: str):
    """Parse SGF text and create board."""
    # ❌ Здесь нужно применить symmetry ПЕРЕД парсингом!
    
    # Текущий код:
    parser = SGFParser(language=language)
    self.parsed_data = parser.parse(sgf_text)
    
    # ❌ Symmetry не применяется!
```

---

## 🔧 Что нужно исправить

### Проблема 1: Упрощенный renderer

**Текущий:**
- 201 строка
- Только Full Board
- Нет поддержки Corner/Side/Center

**Решение:**
```python
# Заменить на bigo_shared renderer:
from bigo_shared.rendering import GoBoardRenderer

# Он уже поддерживает все типы досок!
```

---

### Проблема 2: Игнорируется board_part из БД

**Где исправить:** `bigo_reader/diagrams/diagram_viewer.py`

**Текущий код (строки 240-243):**
```python
def _load_diagram_from_db(self):
    diagram_data = self.parent_window.db_manager.get_diagram(self.dia_id)
    sgf_text = diagram_data.get('SGF', '')
    # ❌ board_part НЕ используется!
    self._parse_sgf(sgf_text)
```

**Исправленный код:**
```python
def _load_diagram_from_db(self):
    diagram_data = self.parent_window.db_manager.get_diagram(self.dia_id)
    sgf_text = diagram_data.get('SGF', '')
    
    # ✅ Читаем board_part из БД
    board_part = diagram_data.get('Board_Part', 'full')
    
    # ✅ Конвертируем формат БД в формат renderer
    board_type, board_position = self._parse_board_part(board_part)
    
    # ✅ Обновляем settings
    self.settings['board_type'] = board_type
    self.settings['board_part'] = board_position
    
    self._parse_sgf(sgf_text)

def _parse_board_part(self, board_part_str: str) -> tuple[str, str]:
    """Convert DB format to renderer format.
    
    Args:
        board_part_str: 'full', 'corner_tl', 'side_left', etc.
        
    Returns:
        (board_type, board_part) tuple
        Example: ('Corner', 'Top Left')
    """
    mapping = {
        'full': ('Full Board', ''),
        'corner_tl': ('Corner', 'Top Left'),
        'corner_tr': ('Corner', 'Top Right'),
        'corner_bl': ('Corner', 'Bottom Left'),
        'corner_br': ('Corner', 'Bottom Right'),
        'side_left': ('Side', 'Left'),
        'side_right': ('Side', 'Right'),
        'side_top': ('Side', 'Top'),
        'side_bottom': ('Side', 'Bottom'),
        'center': ('Center', ''),
    }
    return mapping.get(board_part_str.lower(), ('Full Board', ''))
```

---

### Проблема 3: Игнорируется symmetry

**Где исправить:** `bigo_reader/diagrams/diagram_viewer.py`

**Текущий код (строка 232):**
```python
def _parse_sgf(self, sgf_text: str):
    parser = SGFParser(language=language)
    self.parsed_data = parser.parse(sgf_text)
    # ❌ Symmetry не применяется
```

**Исправленный код:**
```python
def _load_diagram_from_db(self):
    diagram_data = self.parent_window.db_manager.get_diagram(self.dia_id)
    sgf_text = diagram_data.get('SGF', '')
    symmetry = diagram_data.get('Symmetry')
    
    # ✅ Применяем симметрию ПЕРЕД парсингом
    if symmetry and symmetry != 0:
        sgf_text = self._apply_symmetry_to_sgf(sgf_text, symmetry)
    
    self._parse_sgf(sgf_text)

def _apply_symmetry_to_sgf(self, sgf_text: str, symmetry: int) -> str:
    """Apply symmetry transformation to SGF.
    
    Args:
        sgf_text: Original SGF
        symmetry: Symmetry code from DB
        
    Returns:
        Transformed SGF
    """
    from bigo_shared.utils import transform_sgf_coord
    import re
    
    # Определяем размер доски
    size_match = re.search(r'SZ\[(\d+):?(\d+)?\]', sgf_text)
    board_size = int(size_match.group(1)) if size_match else 19
    
    # Маппинг кодов БД на типы преобразований
    symmetry_map = {
        1: 'flip_h',    # Horizontal flip
        2: 'flip_v',    # Vertical flip
        3: 'rot90',     # Rotate 90°
        4: 'rot180',    # Rotate 180°
        5: 'rot270',    # Rotate 270°
        6: 'flip_d1',   # Diagonal \
        7: 'flip_d2',   # Diagonal /
    }
    
    symmetry_type = symmetry_map.get(symmetry)
    if not symmetry_type:
        return sgf_text
    
    # Преобразуем все координаты
    def replace_coord(match):
        coord = match.group(1)
        new_coord = transform_sgf_coord(coord, symmetry_type, board_size)
        return f'[{new_coord}]'
    
    # Применяем к координатам в SGF
    transformed = re.sub(r'\[([a-s][a-s])\]', replace_coord, sgf_text)
    
    return transformed
```

---

## 📊 Сравнение: bigo_reader vs bigo_editor

| Функция | bigo_editor | bigo_reader | bigo_shared |
|---------|-------------|-------------|-------------|
| **Renderer** | ✅ 660 строк | ⚠️ 201 строка | ✅ 660 строк |
| **Full Board** | ✅ | ✅ | ✅ |
| **Corner (4)** | ✅ | ❌ | ✅ |
| **Side (4)** | ✅ | ❌ | ✅ |
| **Center** | ✅ | ❌ | ✅ |
| **Symmetry** | ❌ | ❌ | ✅ (8 типов) |
| **БД хранит** | N/A | ✅ | N/A |
| **Использует** | N/A | ❌ | N/A |

---

## 🚀 План миграции

### Фаза 2B: Обновление bigo_reader (1.5 часа)

#### Шаг 1: Заменить renderer (30 минут)

**Файл:** `bigo_reader/rendering/__init__.py`

```python
# БЫЛО:
from .board_renderer import GoBoardRenderer

# СТАЛО:
from bigo_shared.rendering import GoBoardRenderer
```

**Удалить:** `bigo_reader/rendering/board_renderer.py` (201 строка - больше не нужен)

---

#### Шаг 2: Использовать board_part (30 минут)

**Файл:** `bigo_reader/diagrams/diagram_viewer.py`

**Изменения:**
1. Добавить `_parse_board_part()` метод (см. выше)
2. Обновить `_load_diagram_from_db()` для чтения board_part
3. Установить правильные значения в self.settings

**Тест:**
```python
# Создать диаграмму с board_part='corner_tl' в БД
# Открыть в diagram_viewer
# Должен показать только верхний левый угол, а не всю доску
```

---

#### Шаг 3: Использовать symmetry (30 минут)

**Файл:** `bigo_reader/diagrams/diagram_viewer.py`

**Изменения:**
1. Добавить импорт: `from bigo_shared.utils import transform_sgf_coord`
2. Добавить `_apply_symmetry_to_sgf()` метод (см. выше)
3. Обновить `_load_diagram_from_db()` для применения symmetry

**Тест:**
```python
# Создать диаграмму с symmetry=1 (flip_h) в БД
# Открыть в diagram_viewer
# Позиция должна быть зеркально отражена по горизонтали
```

---

## ✅ Ожидаемый результат

### После миграции:

```python
# bigo_reader/rendering/__init__.py (1 строка)
from bigo_shared.rendering import GoBoardRenderer

# bigo_reader/diagrams/diagram_viewer.py (+50 строк)
# + _parse_board_part()
# + _apply_symmetry_to_sgf()
# + Обновленный _load_diagram_from_db()
```

**Удалено:**
- `bigo_reader/rendering/board_renderer.py` (201 строка)

**Добавлено:**
- Поддержка всех типов досок (Corner, Side, Center)
- Поддержка 8 симметричных преобразований
- Использование данных из БД (board_part, symmetry)

**Выгоды:**
- ✅ Меньше кода (удалено 201, добавлено 50 = -151 строка)
- ✅ Больше функциональности (4 типа досок, 8 преобразований)
- ✅ Единый renderer для всех приложений
- ✅ Автоматические обновления и исправления

---

## 📈 Текущее состояние

### Что работает:
- ✅ Загрузка диаграмм из БД (SQLite/PostgreSQL/Flask API)
- ✅ Парсинг SGF
- ✅ Отображение полной доски (Full Board)
- ✅ Навигация по ходам
- ✅ Отображение комментариев

### Что НЕ работает:
- ❌ Части доски (Corner, Side, Center) - данные есть, но не используются
- ❌ Симметричные преобразования - данные есть, но не применяются

### Что будет после миграции:
- ✅ Все типы досок (из bigo_shared)
- ✅ Все симметричные преобразования (из bigo_shared)
- ✅ Автоматическое использование данных из БД

---

## 🎯 Рекомендации

### Приоритет 1 (Критично):
1. **Заменить renderer** - Использовать `bigo_shared.rendering.GoBoardRenderer`
2. **Использовать board_part** - Читать из БД и применять

### Приоритет 2 (Важно):
3. **Использовать symmetry** - Применять преобразования к SGF

### Приоритет 3 (Улучшение):
4. **UI для выбора** - Добавить dropdown для смены board_type
5. **Тестирование** - Проверить все комбинации board_part × symmetry

---

## 📚 Связанные файлы

### Текущие файлы bigo_reader:
1. `rendering/__init__.py` - Импорт renderer
2. `rendering/board_renderer.py` - Упрощенная версия (удалить)
3. `diagrams/diagram_viewer.py` - Окно просмотра (обновить)
4. `data/flask_db_manager.py` - Получение данных из API

### Файлы bigo_shared (использовать):
1. `rendering/board_renderer.py` - Полная версия (660 строк)
2. `utils/__init__.py` - Симметричные преобразования

### Документация:
1. `bigo_shared/BOARD_PARTS_AND_SYMMETRY_ANALYSIS.md` - Детальный анализ
2. `bigo_shared/VERIFICATION_REPORT_RU.md` - Общий отчет
3. `bigo_reader/ANALYSIS_REPORT.md` - Этот отчет

---

*Анализ выполнен: 21 октября 2025*  
*Приложение: bigo_reader*  
*Статус: Готов к миграции (Фаза 2B)*  
*Время: 1.5 часа*
