Back   Home Page

實 作 鬥 獸 棋 互 吃 規 則

在 鬥 獸 棋 中 的 動 物 互 吃 的 方 法 有 所 不 同. 譬 如 說, 貓 只 能 吃 敵 方 的 老 鼠 及 貓 而 已. 至 於 狗 的 話, 也 只 有 敵 方 的 三 種 動 物 可 以 吃, 即 是 老 鼠, 貓 及 狗 罷 了. 一 般 上, 體 型 大 的 動 物 可 以 吃 掉 體 型 小 的 動 物, 但 是 有 一項 例 外... 就 是 大 象 不 能 吃 小 老 鼠.
下 面 的 表 格 列 出 了 動 物 可 吃 的 對 象:
準 備 要 吃 的 動 物.... 被 吃 的 動 物 可 以 是....
這 是 鬥 獸 棋 互 吃 法 的 一 般 規 則...在 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 都 相 對 應 於 特 定 的 動 物. 我 們 可 以 用 圖 來 表 示:
1
0
0
0
0
0
0
1
再 用 淺 白 的 圖 表 達 的 話, 應 是 這 樣:
如 果 對 方 是...
可 以 吃
不 可 以 吃
不 可 以 吃
不 可 以 吃
不 可 以 吃
不 可 以 吃
不 可 以 吃
可 以 吃
在 上 例 的 表 格, 你 可 以 知 道 老 鼠 能 夠 吃 掉 的 動 物 只 有 兩 種: 大 象 及 老 鼠 同 類.
如 果 換 成 大 象 呢? 大 象 與 其 他 八 隻 動 物 的 關 係 如 下 圖 所 示:
1
1
1
1
1
1
1
0
只 有 老 鼠 不 能 吃 罷 了.
所 以 在 我 們 的 程 式 中, 我 們 定 義 了 八 項 不 同 的 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
        
       

Back   Home Page


Written by Junior programmers