在 鬥 獸 棋 中 的 動 物 互 吃 的 方 法 有 所 不 同. 譬 如 說, 貓 只 能 吃 敵 方 的 老 鼠 及 貓 而 已. 至 於 狗 的 話, 也 只 有 敵 方 的 三 種 動 物 可 以 吃, 即 是 老 鼠, 貓 及 狗 罷 了. 一 般 上, 體 型 大 的 動 物 可 以 吃 掉 體 型 小 的 動 物, 但 是 有 一項 例 外... 就 是 大 象 不 能 吃 小 老 鼠.
下 面 的 表 格 列 出 了 動 物 可 吃 的 對 象:
準 備 要 吃 的 動 物.... | 被 吃 的 動 物 可 以 是.... |
![]() |
![]() ![]() |
![]() |
![]() ![]() |
![]() |
![]() ![]() ![]() |
![]() |
![]() ![]() ![]() ![]() |
![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
![]() ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() |
這 是 鬥 獸 棋 互 吃 法 的 一 般 規 則...在 ABC 中, 在 特 殊 的 情 況 下 還 有 一 些 特 殊 的 吃 法, 譬 如, 敵 方 的 動 物 跌 入 我 們 的 陷 阱 後, 我 方 任 何 一 隻 動 物 都 可 以 吃 掉 牠, 即 使 是 對 方 的 是 獅 子, 盡 管 我 方 的 只 是 老 鼠.
這 一 頁 主 要 是 討 論 如 何 在 程 式 做 到 這 些 規 則. 一 般 上, 已 有 程 式 設 計 經 驗 的 朋 友 們 知 道 可 以 用 IF-THEN 來 做 到. 如 下 面 的 例 子:
Enum animalEnum Rat = 0 cat = 1 dog = 2 wolf = 3 leopard = 4 tiger = 5 lion = 6 elephant = 7 End Enum Dim killer As animalEnum Dim killee As animalEnum Dim canKill As Boolean Sub Main() Let Killer = Rat Let Killee = elephant If (killer >= killee) Then If killer = Elephant And killee = Rat Then Let canKill = False Else Let canKill = True End If Else If killer = Rat And killee = Elephant Then Let canKill = True Else Let canKill = False End If End If If canKill Then MsgBox "can eat" Else MsgBox "cannot eat" End If End Sub
但 是 我 們 利 用 的 是 另 一 套 方 法, 喚 著 bitwise operation . 因 為 鬥 獸 棋 中 只 有 八 隻 不 同 的 動 物. 在 棋 盤 上, 每 隻 動 物 都 有 很 可 能 面 對 敵 方 的 其 中 一 隻 動 物, 因 此 我 們 設 計 了 一 個 機 制 (mechanism) 儲 存 了 那 隻 動 物 與 敵 方 每 一 隻 動 物 的 關 係. 我 們 的 目 的 非 常 簡 單, 只 要 有 記 錄 兩 種 互 斥 (exclusive) 的 關 係 罷 了, 那 就 是 "可 以 吃 對 方" 或 是 "不 可 以 吃 對 方". 當 雙 方 對 壘 時, 我 們 再 透 過 一 項 計 算 公 式 取 得 兩 者 (要 吃 與 被 吃) 的 關 係 後 才 決 定 能 不 能 吃.
好 了, 接 下 來 討 論 這 個 機 制 是 如 何 運 作 的. 因 為 只 有 兩 種 關 係 (可 以 吃 或 是 不 可 以 吃)要 儲 存. 所 以 我 們 正 好 可 以 利 用 0 和 1 代 表. 因 為 只 需 要 儲 存 八 隻 動 物 的 關 係, 所 以 我 們 用 掉 了 8 bits 的 空 間.
譬 如 老 鼠 與 其 他 八 隻 動 物 的 關 係 在 用 bits 的 互 吃 表 達 方 式 應 該 是 這 樣 的:
10000001
每 個 位 置 的 bit 都 相 對 應 於 特 定 的 動 物. 我 們 可 以 用 圖 來 表 示:
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
再 用 淺 白 的 圖 表 達 的 話, 應 是 這 樣:
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
在 上 例 的 表 格, 你 可 以 知 道 老 鼠 能 夠 吃 掉 的 動 物 只 有 兩 種: 大 象 及 老 鼠 同 類.
如 果 換 成 大 象 呢? 大 象 與 其 他 八 隻 動 物 的 關 係 如 下 圖 所 示:
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
只 有 老 鼠 不 能 吃 罷 了.
所 以 在 我 們 的 程 式 中, 我 們 定 義 了 八 項 不 同 的 data structure... 由 於 Visual Basic 不 支 援 二 進 位 數, 所 以 我 們 用 了 十 六 進 位 來 表 達... Dim rat As Integer, cat As Integer, dog As Integer, wolf As Integer Dim leopard As Integer, tiger As Integer, lion As Integer Dim elephant As Integer Let rat = &H81 ' 10000001 Let cat = &H3 ' 00000011 Let dog = &H7 ' 00000111 Let wolf = &HF ' 00001111 Let leopard = &H1F ' 00011111 Let tiger = &H3F ' 00111111 Let lion = &H7F ' 01111111 Let elephant = &HFE ' 11111110
接 下 來 那 麼 要 如 何 從 這 些 資 料 結 構 中 取 得 可 以 吃 或 不 可 以 吃 的 資 訊 呢?
譬 如, 大 象 可 不 可 以 吃 老 鼠 呢? 或 是 老 鼠 可 不 可 以 吃 大 象 呢?
我 們 已 得 知 大 象 的 吃 法 權 限 是:
11111110
我 們 也 知 道 了 老 鼠 的 吃 法 權 限 是:
10000001
我 們 已 知 在 大 象 的 8 bits 吃 法 權 限 資 料 結 構 (data structure) 中, 老 鼠 佔 第 八 個 位 置. 恰 好 第 八 個 位 置 是 零, 表 示 牠 不 能 把 老 鼠 吃 掉.
我 們 也 然 知 道 老 鼠 能 吃 掉 大 象, 因 為 老 鼠 的 吃 法 權 限 的 資 料 結 構 的 第 一 個 位 置 是 1.
可 是 要 電 腦 如 何 從
11111110
和
10000001
拿 到 答 案 呢?
啊! 就 是 bitwise operation 啦.
我 們 先 談 談 大 象 吃 老 鼠 的 bitwise operation.
假 設 大 象 是 killer, 以 及 老 鼠 是 killee...當 電 腦 要 做 bitwise operation 時, 電 腦 應 該 從 killer 的 bits 中 拿 killee 所 佔 位 置 的 bit. 看 看 它 的 價 值, 這 個 可 利 用 AND 來 做 到:
11111110 | |
AND | 00000001 |
===> | 00000000 |
結 果 電 腦 會 得 到 0 的 價 值. 表 示 大 象 不 能 吃 老 鼠.
我 們 再 反 過 來 看 老 鼠 能 否 吃 掉 大 象?
11111110 | |
AND | 10000000 |
===> | 10000000 |
結 果 你 會 得 到 10000000. 任 何 的 結 果 如 果有 1 的 話 我 們 可 以 說 它 大 於 零! 下 面 是 一 個 簡 單 的 測 試 程 式:
Option Explicit Private Type animalType rights As Byte End Type Enum animalEnum Rat = 0 cat = 1 dog = 2 wolf = 3 leopard = 4 tiger = 5 lion = 6 elephant = 7 End Enum Dim animal(0 To 7) As animalType Dim killer As animalEnum, killee As animalEnum Let animal(Rat).rights = &H81 ' 10000001 Let animal(cat).rights = &H3 ' 00000011 Let animal(dog).rights = &H7 ' 00000111 Let animal(wolf).rights = &HF ' 00001111 Let animal(leopard).rights = &H1F ' 00011111 Let animal(tiger).rights = &H3F ' 00111111 Let animal(lion).rights = &H7F ' 01111111 Let animal(elephant).rights = &HFE ' 11111110 Let killer = Rat Let Killee = Cat If (animal( killer ).rights And 2 ^ Killee) > 0 Then ' can eat Else ' cannot eat End If
Written by Junior programmers