定義遊戲最小單位——「格子」的 8 種狀態,並封裝位元級操作,供地圖儲存、尋路標記、關卡編輯、遊戲邏輯共用。
static class Block
{
// ── 8 種基礎狀態 (低 3 bits) ──
public const byte Land = 0; // 空地
public const byte Slot = 1; // 槽(目標點)
public const byte Wall = 2; // 牆
public const byte Brick = 3; // 磚(視覺裝飾,等同牆)
public const byte Box0 = 4; // 箱子在空地
public const byte Box1 = 5; // 箱子在槽
public const byte Man0 = 6; // 工人在空地
public const byte Man1 = 7; // 工人在槽
// 文字關卡對應字元:- + # % x X ( )
const string Mask = "-+#%xX()";
// ── 型別轉換 ──
public static string GetPenName(byte b) => "地槽牆磚箱箱人人"[b & 7].ToString(); // 編輯器筆刷名稱
public static char GetChar(ushort b) => Mask[b & 7]; // *.bxa 匯出
public static byte GetByte(char c) => (byte)Mask.IndexOf(c); // *.bxa 匯入
public static bool IsOk(ushort b) => b <= Man1; // 合法性檢查
// ── 尋路標記操作 (高 bits) ──
public static void CleanAllMark(ushort[,] map)
{
for (int y = 0; y < map.GetLength(0); y++)
for (int x = 0; x < map.GetLength(1); x++)
map[y, x] &= 0x07; // 只保留低 3 bits
}
public static void Mark(ref ushort cell, int value) => cell |= (ushort)(value << 3);
public static int Value(ushort cell) => cell >> 3;
// ── 遊戲邏輯狀態更新 ──
public static void Update(ref ushort cell, byte pen)
{
if (IsSlot(cell) && pen == Man0) pen = Man1;
if (IsSlot(cell) && pen == Box0) pen = Box1;
cell = pen;
}
public static void ManIn(ref ushort cell) => cell += (Man0 - Land);
public static void ManOut(ref ushort cell) => cell -= (Man0 - Land);
public static void BoxIn(ref ushort cell) => cell += (Box0 - Land);
public static void BoxOut(ref ushort cell) => cell -= (Box0 - Land);
// ── 型別判斷 ──
public static bool IsSlot(ushort c) => c == Slot || c == Box1 || c == Man1;
public static bool IsBlank(ushort c) => c == Land || c == Slot;
public static bool IsBox(ushort c) => c == Box0 || c == Box1;
public static bool IsMan(ushort c) => c == Man0 || c == Man1;
}
ushort (16 bits) / byte (8 bits) ┌─────────────┬─────────────┐ │ 高位 (標記) │ 低 3 bits │ │ 距離/步數 │ 型別 0~7 │ └─────────────┴─────────────┘
byte 即可容納。ushort 提供 13 bits (8191);優化版改用 byte + 三態循環,高 5 bits 足矣。(Man0 - Land) 實現「工人/箱子進出格子」的狀態切換,避免大量 if-else。Man1/Box1,確保邏輯一致。*.bxa) 與二進位關卡 (*.bxb) 雙向轉換,便於人工編輯與版本控制。第 5 篇優化後,全專案地圖改為 byte[,],本類所有 ushort 參數/回傳值同步改為 byte,位元操作邏輯不變,僅移位位數調整(高 5 bits 仍足夠存三態標記 1~3)。