|
6 | 6 |
|
7 | 7 | ## 为什么要检测死锁
|
8 | 8 |
|
9 |
| -1. 优化求解器: 可以在搜索时进行可行性剪枝. |
| 9 | +1. **优化求解器**: 可以在搜索时进行可行性剪枝. |
10 | 10 |
|
11 | 11 | 若被死锁的箱子不在目标上, 那么该状态及其衍生状态一定无解.
|
12 | 12 | 部分死锁存在特定的模式, 可以通过较小的代价进行检测, 从而使求解器跳过无意义的搜索.
|
13 | 13 |
|
14 |
| -2. 提升玩家体验: 可以警告或防止玩家产生死锁状态. |
| 14 | +2. **提升玩家体验**: 可以警告或防止玩家产生死锁状态. |
15 | 15 |
|
16 | 16 | 比如在显示箱子可达位置时不显示会产生死锁的箱子位置.
|
17 | 17 |
|
18 | 18 | ## 静态死锁
|
19 | 19 |
|
| 20 | +**检测时机**: 因为该类型的死锁只与关卡的地形有关, 因此可以在**最开始进行计算**, 之后在**箱子被死锁时进行更新**. 被死锁的箱子可以被当成墙体, 进而导致关卡地形发生变化. |
| 21 | + |
20 | 22 | 
|
21 | 23 |
|
22 | 24 | 以上图为例, 暗色格子属于静态死锁区域. 若箱子被推动到这些区域则会导致该箱子永远无法再被推到目标上.
|
|
27 | 29 |
|
28 | 30 | 以上图为例, 箱子向右被推入死角, 导致冻结死锁. 此时该箱子无法再被移动, 可以视作墙体, 进而导致关卡地形发生变化, 需要重新计算静态死锁区域.
|
29 | 31 |
|
30 |
| -这类地形变化只会增加墙体, 导致静态死锁区域增加. 因此即使不在地形变化时重新计算也不会导致误报, 但可能导致静态死锁检测不全面. |
| 32 | +这类地形变化只会增加墙体, 导致静态死锁区域增加. 因此即使**不在地形变化时重新计算也不会导致误报**, 但可能导致静态死锁检测不全面. |
31 | 33 |
|
32 | 34 | ```rs
|
33 | 35 | pub fn is_static_deadlock(
|
@@ -81,9 +83,17 @@ pub fn is_static_deadlock(
|
81 | 83 |
|
82 | 84 | ## 冻结死锁(Freeze deadlocks)
|
83 | 85 |
|
84 |
| -若一个箱子在水平和垂直方向均不可能移动且不位于目标上, 则出现冻结死锁. |
| 86 | +**检测时机**: **箱子推动后**. |
| 87 | + |
| 88 | +若一个箱子在水平和垂直方向均不可能移动, 则出现冻结死锁. |
| 89 | + |
| 90 | +能遮挡箱子的元素有两个: |
| 91 | + |
| 92 | +1. 墙体. |
| 93 | +2. 其他箱子: 需**递归**的判断该箱子是否被死锁. |
| 94 | + |
| 95 | +在递归的检查其他箱子是否死锁时会产生循环检查, 即已检查过的节点会被重复检查, 从而形成死循环. |
85 | 96 |
|
86 |
| -判断指定箱子是否处于冻结死锁还需要**递归**的判断相邻箱子是否也处于死锁状态. |
87 | 97 | 为避免循环检查, 可以将已检查的箱子视为被死锁的, 原因如下:
|
88 | 98 |
|
89 | 99 | 如下 XSB 关卡所示, 有箱子 A, B, C. 其中 B 的左侧和下方是空地:
|
@@ -155,6 +165,8 @@ pub fn is_freeze_deadlock(
|
155 | 165 |
|
156 | 166 | ## 畜栏死锁(Corral deadlocks)
|
157 | 167 |
|
| 168 | +**检测时机**: **当玩家不可达区域面积减小时进行计算**, 因为此时才可能产生玩家永远不可达的区域, 区域周边的箱子只能被继续向内推动, 进而导致死锁. |
| 169 | + |
158 | 170 | 
|
159 | 171 |
|
160 | 172 | ## 闭对角死锁(Closed diagonal deadlocks)
|
|
0 commit comments