# Board API 接口说明

---

## 1. 概览

Board API 由两个核心抽象类组成：

* `Position`：表示题板上的单个格子位置，包含坐标及题板标识，提供位置移动、偏移、邻域查询和边界判断功能。
* `Board`：表示整个题板，管理位置对象、内容、变量、配置及渲染相关功能，支持多子题板（board\_key区分）。

该接口设计用于支持多题板、多位置、多变量的复杂谜题状态管理，确保位置和内容操作的统一和高效。

---

## 2. 结构划分

| 小节         | 内容说明                          |
|------------|-------------------------------|
| `Position` | 单个位置抽象，坐标及操作接口                |
| `Board`    | 题板整体抽象，数据管理、变量接口、配置管理及特殊遍历等功能 |

---

## 3. `Position` 接口概览

| 名称                       | 类型    | 说明                    |
|--------------------------|-------|-----------------------|
| [x](#x)                  | `int` | 纵坐标                   |
| [y](#y)                  | `int` | 横坐标                   |
| [board_key](#board_key)  | `str` | 位置所属题板标识              |
| [clone](#clone)          | 方法    | 复制返回当前对象的副本           |
| [up](#up)                | 方法    | 返回向上移动 n 格的新位置，不修改自身  |
| [down](#down)            | 方法    | 返回向下移动 n 格的新位置，不修改自身  |
| [left](#left)            | 方法    | 返回向左移动 n 格的新位置，不修改自身  |
| [right](#right)          | 方法    | 返回向右移动 n 格的新位置，不修改自身  |
| [deviation](#deviation)  | 方法    | 返回对输入位置偏移后的新位置，不修改自身  |
| [in\_bounds](#in_bounds) | 方法    | 判断自身是否在边界位置范围内        |
| [neighbors](#neighbors)  | 方法    | 返回按距离排序的邻近位置列表，支持分层扩散 |

---

## 4. `Board` 接口概览

| 名称                                             | 类型          | 说明                                                                              |
|------------------------------------------------|-------------|---------------------------------------------------------------------------------|
| [CONFIG_FLAGS](#CONFIG_FLAGS)                  | `list[str]` | 题板配置标志列表，包含：<br> - `by_mini`（类角标）<br> - `pos_label`（X=N标志）<br> - `row_col`（行列号） |
| [\__call\__](#__call__)                        | 方法          | 遍历返回指定目标内容，支持多题板                                                                |
| [batch](#batch)                                | 方法          | 批量获取指定位置内容，支持多种模式                                                               |
| [clone](#clone)                                | 方法          | 克隆当前题板，返回全新对象                                                                   |
| [get\_board\_keys](#get_board_keys)            | 方法          | 返回当前所有题板名称索引列表(不推荐使用请使用下方这个)                                                    |
| [get_interactive_board](#get_interactive_keys) | 方法          | 返回当前所有可交互的题板名称索引列表                                                              |
| [generate\_board](#generate_board)             | 方法          | 新建副板，指定名称和尺寸                                                                    |
| [encode](#encode)                              | 方法          | 将题板编码成字节串                                                                       |
| [boundary](#boundary)                          | 方法          | 返回题板边界极限位置对象                                                                    |
| [in\_bounds](#in_bounds)                       | 方法          | 判断位置是否在当前题板范围内                                                                  |
| [type\_value](#type_value)                     | 方法          | 根据值判断类型：雷(F)、线索(C)、未赋值(N)                                                       |
| [get\_type](#get_type)                         | 方法          | 获取指定位置的类型字符串                                                                    |
| [get\_value](#get_value)                       | 方法          | 获取指定位置的对象值，超出返回 None                                                            |
| [set\_value](#set_value)                       | 方法          | 设置指定位置的对象值                                                                      |
| [clear\_board](#clear_board)                   | 方法          | 清空整个题板的数据                                                                       |
| [set\_dyed](#set_dyed)                         | 方法          | 设置指定位置的染色状态                                                                     |
| [get\_dyed](#get_dyed)                         | 方法          | 获取指定位置的染色状态                                                                     |
| [get\_config](#get_config)                     | 方法          | 获取指定题板配置项                                                                       |
| [set\_config](#set_config)                     | 方法          | 设置指定题板配置项                                                                       |
| [get\_variable](#get_variable)                 | 方法          | 获取指定位置对应的 CP-SAT 变量                                                             |
| [get\_row\_pos](#get_row_pos)                  | 方法          | 获取同一行所有位置对象列表                                                                   |
| [get\_col\_pos](#get_col_pos)                  | 方法          | 获取同一列所有位置对象列表                                                                   |
| [get\_pos](#get_pos)                           | 方法          | 根据坐标和题板名返回位置对象                                                                  |
| [get\_model](#get_model)                       | 方法          | 返回该题板的model对象                                                                   |
| [\__getitem\__](#__getitem__)                  | 方法          | 等价于 `get_value`                                                                 |
| [\__setitem\__](#__setitem__)                  | 方法          | 等价于 `set_value`                                                                 |
| [\__contains\__](#__contains__)                | 方法          | 判断类型是否包含在题板内                                                                    |
| [has](#has)                                    | 方法          | 同 `__contains__`，判断包含关系                                                         |
| [show\_board](#show_board)                     | 方法          | 显示题板界面，可选择显示标签                                                                  |

---

# 3. AbstractPosition 接口详解

---

### x

**类型**：`int`

**说明**：当前坐标的纵向索引（行号）。

---

### y

**类型**：`int`

**说明**：当前坐标的横向索引（列号）。

---

### board\_key

**类型**：`str`

**说明**：所属题板名称，用于区分多题板。

---

### clone()

**返回**：另一个位置对象

**说明**：复制当前对象，返回同坐标同题板的新位置对象。

---

### up(...)

**返回**：另一个位置对象

**说明**：返回向上移动 n 格的新位置，不修改当前对象。

| 参数名 | 类型    | 说明        |
|-----|-------|-----------|
| n   | `int` | 移动格数（默认1） |

---

### down(...)

**返回**：另一个位置对象

**说明**：返回向下移动 n 格的新位置，不修改当前对象。

| 参数名 | 类型    | 说明        |
|-----|-------|-----------|
| n   | `int` | 移动格数（默认1） |

---

### left(...)

**返回**：另一个位置对象

**说明**：返回向左移动 n 格的新位置，不修改当前对象。

| 参数名 | 类型    | 说明        |
|-----|-------|-----------|
| n   | `int` | 移动格数（默认1） |

---

### right(...)

**返回**：另一个位置对象

**说明**：返回向右移动 n 格的新位置，不修改当前对象。

| 参数名 | 类型    | 说明        |
|-----|-------|-----------|
| n   | `int` | 移动格数（默认1） |

---

### deviation(...)

**返回**：另一个位置对象

**说明**：返回对输入位置偏移后的新位置，不修改当前对象。

| 参数名 | 类型                 | 说明      |
|-----|--------------------|---------|
| pos | `AbstractPosition` | 偏移量位置对象 |

---

### `neighbors(...)`

**返回**：所有的对应位置对象的列表

**说明**：
返回当前位置周围邻近位置，依据**欧几里得距离的平方值**进行筛选。结果不包含当前位置自身，按距离从近到远排序。

| 参数名  | 类型       | 说明                                                                                                              |
|------|----------|-----------------------------------------------------------------------------------------------------------------|
| args | `int...` | 可传入一个或两个整数：<br>- `neighbors(n)`：返回欧几里得距离 ≤ √n 的所有位置<br>- `neighbors(low, high)`：返回欧几里得距离 ∈ \[√low, √high] 的所有位置 |

---

### 距离说明

使用欧几里得距离公式进行判断，即：

```
sqrt(dx^2 + dy^2) ∈ [√low, √high]
```

判断时使用平方值，无需实际开根。

---

### 示例

| 调用方式              | 说明                           |
|-------------------|------------------------------|
| `neighbors(1)`    | 返回距离为 √1 的位置（上下左右）           |
| `neighbors(2)`    | 返回距离 ≤ √2 的位置（上下左右 + 对角线）    |
| `neighbors(4)`    | 返回距离 ≤ √4 的位置（包含“马步”方向）      |
| `neighbors(2, 2)` | 返回距离 = √2 的位置（仅对角线）          |
| `neighbors(3, 5)` | 返回距离 ∈ \[√3, √5] 的位置（构成环状区域） |
| `neighbors(0, 1)` | 返回距离为 ≤ √1 的位置（上下左右 + 本格）    |

---

### in\_bounds(...)

**返回**：`True`在边界内 `False`不在边界内

**说明**：判断自身是否在边界位置范围内。

| 参数名        | 类型                 | 说明     |
|------------|--------------------|--------|
| bound\_pos | `AbstractPosition` | 边界位置对象 |

---

# 4. Board 接口详解

---

### CONFIG_FLAGS

**类型**：`list[str]`

**说明**：题板配置项名称列表，固定不变，供 `get_config` 和 `set_config` 调用以控制题板渲染和规则行为。

**内容**：

| 名称            | 说明                           |
|---------------|------------------------------|
| `by_mini`     | 是否启用类型角标                     |
| `pos_label`   | 该副板是否启用X=N标签（如 `x=2`）        |
| `row_col`     | 是否在题板渲染时显示行列号                |
| `interactive` | 是否可被求解器主动设置值 设为True后视为与主板同等级 |

## **详解**:

### `interactive: bool`
  * 控制该副板是否允许被求解器主动交互。若为 `True`，该副板将：
    * 与主板一样被纳入规则系统；
    * 允许求解器直接在其上设定变量值；
    * 允许规则读取、修改、约束其变量；
    * 参与完整的建模与推理过程。
  * 若为 `False`，该副板仅作为静态参照，不参与解空间构造或变量赋值。

------

### `__call__(...)`

**说明**：遍历题板中符合条件的位置，返回对应坐标和内容。

| 参数名    | 类型              | 说明     |
|--------|-----------------|--------|
| target | `str` \| `None` | 遍历对象类型 |
| mode   | `str`           | 返回内容类型 |
| key    | `str` \| `None` | 题板名称   |

**返回**：生成器，依次返回 `(AbstractPosition, 内容)`。

**详细说明**

  * `target` 参数用于指定遍历的对象类型，常用值包括：
  
    * `"C"`：仅遍历线索格子。
  
    * `"F"`：仅遍历雷格子。
  
    * `"N"`：仅遍历空白（未赋值或未翻开）格子。
  
    * `"always"`（默认）：遍历所有格子。
  
  * `mode` 参数定义返回内容的类型：
  
    * `"object"`（默认）：返回格子所包含的对象实例。
  
    * `"type"`：返回格子内容的类型标识符（例如 `'F'`、`'C'`、`'N'`）。
  
    * `"variable"`：返回与格子绑定的 CP-SAT 变量（若有）。
  
    * `"dye"`：返回格子的染色状态（布尔值）。
  
  * `key` 参数用于指定题板名称：
  
    * 默认值为 `"None"`，即遍历所有存在的可交互题板。

    * 传入的值需要在get_board_keys()中
  
  * 该方法返回一个生成器，可逐步迭代遍历满足条件的格子及其对应内容。

**示例**：

```
for pos, type_str in board(target="F", mode="type"):
    # 处理雷对象

for pos, var in board(target="C", mode="variable", key=None):
    # 处理所有题板的线索变量
```

---

### `__getitem__`(...)

**说明**：语法糖。支持使用 `board[pos]` 的形式获取指定位置的对象。

| **参数名** | **类型**             | **说明** |
|---------|--------------------|--------|
| **pos** | `AbstractPosition` | 目标位置对象 |

**返回**：该位置的对象（线索、雷或空）

---

### `__setitem__`(...)

**说明**：语法糖。支持使用 `board[pos] = value` 的形式设置指定位置的对象。

| **参数名**   | **类型**             | **说明** |
|-----------|--------------------|--------|
| **pos**   | `AbstractPosition` | 目标位置对象 |
| **value** | 任意类型               | 要设置的对象 |

**返回**：无

---

---

### `__contains\__`(...)

**说明**：判断 `target` 字符串是否包含在题板中，
即判断题板中是否存在符合该目标类型的元素。
常用于判断如 `"N"`（未定义）、`"F"`（雷）、`"C"`（线索）等类型是否存在于题板。

该方法通常支持表达式如：

```
if "N" in board:
    # 题板中存在未翻开的格子
```

| **参数名** | **类型** | **说明**                        |
|---------|--------|-------------------------------|
| target  | `str`  | 目标类型字符串，如 `"N"`、`"F"`、`"C"` 等 |

**返回**：
布尔值，若题板中存在符合目标的元素则返回 `True`，否则返回 `False`。

---

### has(...)

**说明**：-判断指定题板中是否包含目标字符串对应的元素。功能与 `__contains__` 类似，但可指定搜索的题板 `key`。

| **参数名** | **类型**         | **说明**                        |
|---------|----------------|-------------------------------|
| target  | `str`          | 目标类型字符串，如 `"N"`、`"F"`、`"C"` 等 |
| key     | `str` 或 `None` | 题板标识，指定在哪个题板内搜索；默认搜索所有        |

**返回**：
布尔值，表示指定题板中是否存在目标类型的元素。`True` 表示存在，`False` 表示不存在。

---

### `clone()`

**说明**：克隆当前题板对象，内容完全复制。

**返回**：新的题板实例，与当前题板等价但独立。

---

### `get_board_keys()`

**说明**：获取当前题板对象管理的所有题板名称列表。

**返回**：字符串列表，包含所有存在的题板索引。

---

### `get_interactive_keys()`

**说明**：返回所有配置项中 `interactive=True` 的题板 key 列表。

| **参数名** | **类型** | **说明** |
|---------|--------|--------|
| —       | —      | 无参数    |

**返回**：`list[str]` —— 所有允许被求解器主动交互的题板字符串索引。

> 可用于遍历所有具有主板等价交互权限的子题板。

---

### `generate_board(...)`

**说明**：创建一块副板。

| **参数名**    | **类型**            | **说明**  |
|------------|-------------------|---------|
| board\_key | `str`             | 副板名称索引  |
| size       | `tuple`           | 副板尺寸    |
| code       | `bytes` \| `None` | 副板编码，可选 |

**返回**：
无

**备注**:
可通过set_config调整渲染设置

---

### `encode(...)`

**说明**：将题板编码成字节格式，方便存储与传输。

**返回**：`bytes`，题板的编码数据。

---

### `boundary(...)`

**说明**：获取指定题板的边界极限位置。

| **参数名** | **类型** | **说明**     |
|---------|--------|------------|
| key     | `str`  | 题板名称，默认主题板 |

**返回**：`AbstractPosition`，表示边界最大坐标。

---

### `in_bounds(...)`

**说明**：判断某个位置是否在当前题板范围内。

| **参数名** | **类型**             | **说明**  |
|---------|--------------------|---------|
| pos     | `AbstractPosition` | 待检测位置对象 |

**返回**：布尔值，`True` 表示在范围内。

---

### `type_value(...)`

**说明**：静态方法，判断对象值的类型，返回表示类别的字符串。

| **参数名** | **类型** | **说明**  |
|---------|--------|---------|
| value   | 任意类型   | 待检测对象的值 |

**返回**：字符串，`"F"` 表示雷，`"C"` 表示线索，`"N"` 表示未赋值。

---

### `get_type(...)`

**说明**：获取某位置的类型。

| **参数名** | **类型**             | **说明** |
|---------|--------------------|--------|
| pos     | `AbstractPosition` | 目标位置对象 |

**返回**：字符串，`"F"`（雷）、`"C"`（线索）、`"N"`（未赋值）、空字符串表示题板外。

---

### `get_value(...)`

**说明**：获取指定位置的对象。

| **参数名** | **类型**             | **说明** |
|---------|--------------------|--------|
| pos     | `AbstractPosition` | 目标位置对象 |

**返回**：位置上的对象实例，题板外也返回 `None`。

---

### `set_value(...)`

**说明**：设置指定位置的对象。

| **参数名** | **类型**             | **说明** |
|---------|--------------------|--------|
| pos     | `AbstractPosition` | 目标位置对象 |
| value   | 任意类型               | 赋值对象   |

**返回**：无

**备注**: 放置的值需要继承于AbstractValue或None

---

### `clear_board(...)`

**说明**：清空所有题板数据，恢复初始状态。

---

### `set_dyed(...)`

**说明**：设置某位置的染色状态。

| **参数名** | **类型**             | **说明** |
|---------|--------------------|--------|
| pos     | `AbstractPosition` | 目标位置对象 |
| dyed    | `bool`             | 是否染色   |

---

### `get_dyed(...)`

**说明**：获取某位置的染色状态。

| **参数名** | **类型**             | **说明** |
|---------|--------------------|--------|
| pos     | `AbstractPosition` | 目标位置对象 |

**返回**：布尔值，`True` 表示染色。

---

### `get_config(...)`

**说明**：获取题板设置项。

| **参数名**      | **类型** | **说明**                        |
|--------------|--------|-------------------------------|
| board\_key   | `str`  | 题板名称                          |
| config\_name | `str`  | 设置名称，通常为 `CONFIG_FLAGS` 中定义的项 |

**返回**：对应设置的值。

---

### `set_config(...)`

**说明**：设置题板配置。

| **参数名**      | **类型** | **说明** |
|--------------|--------|--------|
| board\_key   | `str`  | 题板名称   |
| config\_name | `str`  | 配置项名称  |
| value        | `bool` | 设置值    |

---

### `get_variable(...)`

**说明**：获取指定位置对应的 OR-Tools 变量。

| **参数名** | **类型**             | **说明** |
|---------|--------------------|--------|
| pos     | `AbstractPosition` | 目标位置对象 |

**返回**：`IntVar` 类型变量。

---

### `get_row_pos(...)`

**说明**：返回指定位置所在行从左到右的所有坐标。

| **参数名** | **类型**             | **说明** |
|---------|--------------------|--------|
| pos     | `AbstractPosition` | 目标位置对象 |

**返回**：包含该行所有位置的 `AbstractPosition` 列表。

---

### `get_col_pos(...)`

**说明**：返回指定位置所在列从上到下的所有坐标。

| **参数名** | **类型**             | **说明** |
|---------|--------------------|--------|
| pos     | `AbstractPosition` | 目标位置对象 |

**返回**：包含该列所有位置的 `AbstractPosition` 列表。

---

### `get_pos(...)`

**说明**：根据坐标和题板名返回对应位置对象。

| **参数名** | **类型** | **说明**     |
|---------|--------|------------|
| x       | `int`  | 横坐标        |
| y       | `int`  | 纵坐标        |
| key     | `str`  | 题板名称，默认主题板 |

**返回**：对应的 `AbstractPosition` 对象。

---

### `get_pos_box(...)`

**说明**: 使这两个对角点形成一个矩形并返回所有在内的坐标

| **参数名** | **类型**             | **说明** |
|---------|--------------------|--------|
| pos1    | `AbstractPosition` | 对角点1   |
| pos2    | `AbstractPosition` | 对角点2   |

**返回**：返回在矩形内的所有坐标对象列表

---

### `get_model()`

**返回**：返回该题板的ortools的CpModel实体对象

---

### `batch(...)`

**说明**：批量获取多个位置对应的数据。

| **参数名**    | **类型**                   | **说明**                                           |
|------------|--------------------------|--------------------------------------------------|
| positions  | `List[AbstractPosition]` | 位置列表                                             |
| mode       | `str`                    | 获取类型，支持 `"object"`、`"type"`、`"variable"`、`"dye"` |
| drop\_none | `bool`                   | 是否自动丢弃所有不在题板范围内的坐标                               |

**返回**：对应位置的数据列表。

---

### `show_board(...)`

**说明**：打印或渲染当前题板状态，方便调试。

---

## 其他文档

### [README.md](../README.md) << 入口文档

### [rule_mines.md](./rule_mines.md) << 左线规则接口

### [rule_clue_mines.md](./rule_clue_mines.md) << 中线规则接口

### [rule_clue.md](./rule_clue.md)：<< 右线规则接口

### [utils.md](./utils.md) << 工具模块说明
