本系列前六篇已介紹專案架構、公用工具類、尋路演算法、基本格子定義。本文聚焦 Common/Step.cs,解析「走法步驟」結構如何支援移動記錄、撤銷/重做、通關錄影回放三大核心功能。
namespace Skyiv.Ben.PushBox.Common
{
// 方向枚舉:無、東、南、西、北
enum Direction { None, East, South, West, North }
// 設計模式動作:無、建立、編輯、刪除
public enum Action { None, Create, Edit, Delete }
/// 單一走法步驟
struct Step
{
Direction direct; // 前進方向
bool isBox; // 是否推著箱子
bool isStop; // 「撤銷」時是否停留在此步驟
public Direction Direct => direct;
public bool IsBox => isBox;
public bool IsStop => isStop;
public Step(Direction direct, bool isBox, bool isStop)
{
this.direct = direct;
this.isBox = isBox;
this.isStop = isStop;
}
// ── 隱式轉換:Step ⇄ char ──
// 編碼表:
// 0-4 : A B C D E (方向 None~North, 無箱子、非停留)
// 5-9 : F G H I J (同方向,有箱子)
// 10-14 : K L M N O (同方向,無箱子、停留)
// 15-19 : P Q R S T (同方向,有箱子、停留)
public static implicit operator char(Step step)
{
char c = "ABCDE"[step.direct - Direction.None];
if (step.isBox) c += 5;
if (step.isStop) c += 10;
return c;
}
public static implicit operator Step(char c)
{
int n = c - 'A';
return new Step(
(Direction)(n % 5),
(n % 10 >= 5),
(n >= 10)
);
}
}
}
| 欄位 | 含義 | 用途 |
|---|---|---|
Direct | 移動方向 | 重播/撤銷時決定位移向量 |
IsBox | 是否推箱 | 撤銷時箱子需跟隨退回 |
IsStop | 撤銷停靠點 | 「撤銷」鍵一次退回至最近的 true 步驟 |
假設工人從紅圈走到綠圈推箱子(圖示略),共產生 6 個 Step 實例壓入堆疊:
| 步驟 | Direct | IsBox | IsStop | Char |
|---|---|---|---|---|
| 1 | West | false | true | N |
| 2 | South | false | false | C |
| 3 | West | false | true | N |
| 4 | West | true | false | I |
| 5 | West | true | false | I |
| 6 | West | true | false | I |
IsStop=true 處(紅圈位置)。char (2 bytes) 完整承載三個布林值 + 5 向方向。*.bxs) 與設定檔 (PushBox.cfg) 直接存字串,無需序列化器,極適合行動裝置儲存空間有限的環境。Pub.ToString(Step[]) 將陣列轉字串並 反轉(因堆疊彈出順序為 LIFO),回放時再 ToCharArray() 逐字還原 Step。struct StepEx { Step base; uint tick; }。IsBox 改為 byte boxCount。