本系列第三篇,詳細剖析 Common/Block.cs,定義遊戲八種基本單元格狀態、字元/位元組轉換、標記操作、狀態更新與查詢方法。
static class Block
{
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; // 工人在槽上
const string Mask = "-+#%xX()"; // 匯出文字檔對應字元
}
// 設計器畫筆名稱
public static string GetPenName(byte block) => "地槽牆磚箱箱人人"[block & 0x07].ToString();
// 匯出文字檔字元
public static char GetChar(ushort block) => Mask[block & 0x07];
// 匯入文字檔位元組
public static byte GetByte(char block) => (byte)Mask.IndexOf(block);
// 合法性檢查
public static bool IsOk(ushort block) => block <= Man1;
// 標記:value 存入 bit 3~ (優化後僅用 2 bits 存 1~3)
public static void Mark(ref ushort block, int value) => block |= (ushort)(value << 3);
// 取得標記值
public static int Value(ushort block) => block >> 3;
// 清除所有標記
public static void CleanAllMark(ushort[,] bb)
{
for (int i = 0; i < bb.GetLength(0); i++)
for (int j = 0; j < bb.GetLength(1); j++)
bb[i, j] &= 0x07; // 保留低 3 位狀態
}
// 設計器更新單元格
public static void Update(ref ushort block, byte pen)
{
if (IsSlot(block) && pen == Man0) pen = Man1;
if (IsSlot(block) && pen == Box0) pen = Box1;
block = pen;
}
// 工人進入/離開
public static void ManIn(ref ushort block) => block += (Man0 - Land);
public static void ManOut(ref ushort block) => block -= (Man0 - Land);
// 箱子進入/離開
public static void BoxIn(ref ushort block) => block += (Box0 - Land);
public static void BoxOut(ref ushort block) => block -= (Box0 - Land);
public static bool IsSlot(ushort block) => block == Slot || block == Box1 || block == Man1;
public static bool IsBlank(ushort block) => block == Land || block == Slot;
public static bool IsBox(ushort block) => block == Box0 || block == Box1;
public static bool IsMan(ushort block) => block == Man0 || block == Man1;
ushort → byte。Mark 僅用 2 位元存 1~3,Value 對應調整。Block.cs 以位元操作高效編碼八種狀態,提供完整的轉換、標記、更新與查詢 API,是遊戲核心邏輯的基石。