投 稿 類 別 : 資 訊 類 篇 名 : 小 心 翼 翼 的 二 十 一 點 作 者 : 陳 鈺 文 國 立 瑞 芳 高 級 工 業 職 業 學 校 資 訊 二 李 伯 謙 國 立 瑞 芳 高 級 工 業 職 業 學 校 資 訊 二 胡 家 媛 國 立 瑞 芳 高 級 工 業 職 業 學 校 資 訊 二 指 導 老 師 : 周 曉 玲 老 師 陳 思 亮 主 任
壹 前 言 一 研 究 動 機 平 時 我 們 於 電 腦 上 玩 遊 戲 21 點, 總 是 輕 輕 鬆 鬆 的 移 動 滑 鼠, 一 場 全 新 的 牌 局 隨 即 開 始 看 著 螢 幕 上 秀 出 你 贏 了! 的 字 樣 時, 心 中 滿 佈 欣 喜, 但 大 多 數 人 都 不 明 白 : 為 何 僅 僅 一 個 簡 單 的 動 作 就 能 使 電 腦 乖 乖 聽 話? 一 臺 只 會 分 辨 0 與 1 的 計 算 機 如 何 靠 著 程 式 完 成 這 麼 複 雜 的 遊 戲 呢? 我 們 將 運 用 高 二 初 學 的 Visual Basic 6.0 軟 體 來 簡 單 呈 現 21 點 這 個 耳 熟 能 詳 的 撲 克 牌 遊 戲 二 研 究 目 的 本 研 究 目 的 大 致 分 為 二 項 : ( 一 ) 驗 證 所 學 : 自 從 升 上 高 二 到 現 在, 撰 寫 程 式 已 有 半 年 的 時 間, 我 們 想 藉 由 這 次 的 專 題 製 作 來 測 試 程 式 撰 寫 的 程 度, 並 加 以 精 進 我 們 的 撰 寫 技 巧 ( 二 ) 培 養 團 隊 精 神 : 藉 由 這 次 的 專 題 製 作, 由 搜 集 資 料 到 分 工, 從 撰 寫 程 式 到 編 寫 報 告, 小 組 成 員 同 心 協 力, 相 互 彌 補 彼 此 的 不 足 之 處, 有 了 這 次 的 經 驗, 以 便 往 後 的 分 工 合 作 更 有 效 率, 也 能 達 到 事 半 功 倍 的 效 果 三 研 究 步 驟 經 過 組 員 共 同 討 論 後, 我 們 的 專 題 製 作 計 畫 如 下 圖 一 所 示 : 時 間 工 作 蒐 集 相 關 資 料 尋 求 師 長 協 助 構 思 程 式 撰 寫 程 式 程 式 除 錯 編 寫 論 文 貳 正 文 12 月 1 月 2 月 3 月 圖 一 專 題 研 究 甘 特 圖 一 遊 戲 介 紹 1
遊 戲 目 的 就 是 要 取 得 最 接 近 二 十 一 點 的 點 數, 而 又 不 能 超 過 二 十 一 點 ( 一 般 術 語 稱 之 為 爆 掉 ) 玩 家 需 要 在 投 注 圈 中 央 押 放 注 碼 接 著, 莊 家 ( 電 腦 ) 會 給 玩 家 及 自 己 派 發 兩 張 牌, 一 張 面 朝 上, 一 張 朝 下 這 時 玩 家 可 視 自 己 的 牌 面 點 數 來 決 定 是 否 再 要 一 張 牌 或 多 張 牌, 以 更 接 近 二 十 一 點 點 數, 當 然 也 可 以 見 好 就 收, 等 待 與 莊 家 比 牌 而 莊 家 等 待 玩 家 補 完 牌 後 須 將 蓋 牌 翻 開, 並 視 牌 面 點 數 來 決 定 是 否 補 牌, 但 莊 家 牌 面 點 數 低 於 十 六 時 一 定 得 補 牌 當 玩 家 與 莊 家 都 補 完 牌 後, 就 進 行 勝 負 判 定, 越 接 近 二 十 一 點 者 獲 勝, 當 點 數 相 同 時, 判 定 莊 家 勝 利 ( 一 ) 牌 的 面 值 國 王 (K) 皇 后 (Q) 傑 克 (J) 及 10 點 牌 各 算 作 十 點,Ace(A) 牌 可 算 作 1 或 11 點, 視 乎 玩 家 的 意 願 而 定 ; 其 它 的 牌, 即 2 點 至 9 點, 則 依 其 面 值 計 算 ( 二 ) 點 數 計 算 如 果 玩 家 得 到 的 首 兩 張 牌, 分 別 為 一 張 Ace(A) 牌 和 一 張 價 值 十 點 的 牌, 那 玩 家 就 算 取 得 Blackjack( 黑 傑 克 ) 並 且 獲 勝 ; 除 非 莊 家 同 時 取 得 Blackjack, 那 就 算 平 局 Blackjack( 黑 傑 克 ) 可 擊 敗 對 手 合 計 為 21 點 的 牌, 如 : 一 張 Ace(A) 牌 和 一 張 價 值 十 點 ( 如 : 國 王 (k) 皇 后 (Q) 傑 克 (J) 及 牌 面 10 點 的 牌 ); 也 能 擊 敗 對 手 擁 有 10 點 5 點 6 點 的 牌 雖 然 雙 方 都 同 時 擁 有 二 十 一 點, 但 判 定 Blackjack( 黑 傑 克 ) 為 勝 出 如 果 玩 家 沒 有 取 得 Blackjack( 黑 傑 克 ), 也 可 以 自 行 決 定 是 否 繼 續 補 牌 以 期 達 到 能 更 接 近 二 十 一 點, 又 不 超 過 二 十 一 點 的 點 數 如 玩 家 不 幸 取 得 多 於 二 十 一 點 的 點 數, 那 麼 就 算 作 爆 掉, 並 會 立 即 失 去 籌 碼 若 莊 家 手 持 的 總 點 數 為 16 點 或 16 點 以 下, 則 莊 家 必 須 再 補 牌 ( 三 ) 程 式 中 的 按 鍵 說 明 ( 由 上 而 下 ), 按 表 一 所 示 : 表 一 按 鍵 功 能 說 明 按 鍵 順 序 按 鍵 名 稱 功 能 說 明 第 一 顆 新 局 籌 碼 重 新 回 復 為 一 萬 第 二 顆 遊 戲 說 明 按 下 此 鍵 顯 示 遊 戲 說 明 第 三 顆 音 樂 開 關 按 下 此 鍵 背 景 音 樂 開 始 播 放 第 四 顆 加 注 將 籌 碼 增 加 ( 程 式 以 一 次 增 加 500 為 限 ) 第 五 顆 減 注 將 籌 碼 減 少 ( 程 式 以 一 次 減 少 500 為 限, 最 少 押 注 500) 第 六 顆 要 牌 程 式 即 分 配 給 玩 家 一 張 牌 2
第 七 顆 分 牌 首 兩 張 牌 必 須 點 數 相 符 才 能 分 拆 第 八 顆 比 牌 比 較 玩 家 和 莊 家 ( 電 腦 ) 的 點 數 相 加 大 小 判 定 輸 贏 二 研 究 設 備, 按 表 二 所 示 表 二 研 究 設 備 規 格 表 名 稱 規 格 電 腦 型 號 ACPI Multiprocessor PC 中 央 處 理 器 Intel(R)Core(TM) Quad CPU Q8300 @ 2.50GHz 螢 幕 解 析 度 1280 x 1024 作 業 系 統 Microsoft Windows XP Professional 版 程 式 語 言 Microsoft Visual Basic 6.0 顯 示 卡 Intel(R) G33/G31 Express Chipset Family 滑 鼠 Microsoft HID-compliant mouse 鍵 盤 HID Keyboard Device 硬 碟 255 GB 三 研 究 理 論 此 次 專 題 本 組 運 用 了 陣 列 撲 克 牌 物 件 OLE 控 制 項, 分 述 如 下 : ( 一 ) 陣 列 : 陣 列 源 自 於 數 學 中 的 矩 陣 陣 列 是 一 批 資 料 型 態 相 同 的 變 數, 在 主 記 憶 體 連 續 存 放 的 集 合, 程 式 設 計 者 可 以 此 資 料 結 構, 減 少 大 量 變 數 命 名 的 困 擾, 使 程 式 的 設 計 更 為 靈 活 快 速 使 用 前 必 須 宣 告 一 個 陣 列 型 態, 並 依 處 理 資 料 的 筆 數 大 小, 宣 告 合 適 的 陣 列 型 態 資 料 筆 數, 以 避 免 占 用 過 多 主 記 憶 體 空 間 Visual Basic 6.0 提 供 Dim 敘 述 來 宣 告 一 個 陣 列, 宣 告 後 如 未 給 予 初 值, 則 陣 列 中 所 有 的 元 件 預 設 值 為 零 如 為 字 串 陣 列, 則 陣 列 中 所 有 元 件 預 設 值 為 空 字 串 如 為 自 由 資 料 型 態 陣 列, 則 所 有 的 元 件 預 設 值 為 空 值 (Empty) 陣 列 中 的 變 數 可 以 和 變 數 做 各 種 運 算 如 :score(3)= b + score(2) 本 程 式 有 用 到 陣 列 中 的 AS 資 料 型 態 中 的 AS Integer 方 式,AS 型 態 資 料 介 紹 如 表 三 所 示 表 三 AS 資 料 型 態 方 式 之 介 紹 名 稱 型 態 用 意 AS Integre 宣 告 一 整 數 數 列, 若 資 料 介 於 -32768 至 32767 之 間 時 可 用 此 方 式 AS Long 宣 告 一 個 常 整 數 數 列, 若 資 料 大 於 32767 或 小 於 -32768 可 用 此 方 式 AS Single 宣 告 一 個 單 精 確 度 列, 可 處 理 含 有 小 數 的 資 料 3
AS Double 宣 告 一 個 倍 精 確 度 陣 列, 可 處 理 含 有 小 數 的 資 料 AS String 宣 告 一 個 字 串 陣 列, 可 處 理 含 有 字 串 的 資 料 AS Variant 宣 告 一 個 自 由 型 態 陣 列, 陣 列 中 的 每 個 元 件 都 可 以 接 受 任 任 何 型 態 的 資 料, 但 每 個 元 件 不 管 放 任 何 資 料 至 少 占 8 位 元 ( 二 ) 撲 克 牌 物 件, 按 表 三 所 示 表 四 元 件 項 目 功 能 說 明 項 目 內 容 項 目 內 容 項 目 內 容 JTechCard 物 件 名 稱 Suit 四 種 花 色 Visible 可 視 設 定 CardBackStyle 牌 背 的 花 樣 Value 牌 面 點 數 ( 三 )OLE 控 制 項 : 如 何 建 立 OLE 控 制 項 ; 1 步 驟 一 : 在 工 具 箱 中 選 擇 OLE 控 制 項 2 於 工 作 區 拉 出 OLE 控 制 項 3 拉 出 物 件 後 即 出 現 插 入 物 件 的 視 窗, 可 選 擇 你 將 要 置 入 的 物 件 類 型 4 選 擇 從 檔 案 建 立 後, 會 出 現 對 話 方 塊, 供 選 擇 插 入 OLE 控 制 項 的 檔 案 本 程 式 使 用 MIC 指 令 對 所 要 放 的 音 樂 下 達 命 令 MIC 指 令 是 一 個 字 串, 指 令 分 述 如 下 : 1 open 指 令 : 開 啟 設 備 2 close 指 令 : 關 閉 設 備 3 play 指 令 : 播 放 4 pause 指 令 : 恢 復 播 放 5 resume 指 令 : 開 啟 設 備 6 seek 指 令 : 移 到 音 樂 中 程 式 指 定 的 時 間 7 stop 指 令 : 停 止 本 程 式 使 用 講 mcisendstring 函 式 撰 寫 於 模 組 之 內, 說 明 如 下 1 步 驟 一 : 宣 告 API 函 數, 在 表 單 或 模 組 的 General 中 做 如 下 的 宣 告 : Private Declare Function mcisendstring Lib winmm.dll Alias mcisendstring (ByVal Command As String, ByVal ReturnString As String,ByVal ReturnLength As Long,ByVal Callback AS long) AS Long 4
2 步 驟 二 : 在 程 式 中 呼 叫 mcisendstring 函 數 來 播 放 多 媒 體 檔 案 檔 本 程 式 模 組 中 的 API 函 數 如 下 : Public Declare Function mcisendstring Lib "winmm.dll" Alias "mcisendstringa" (ByVal lpstrcommand As String, ByVal lpstrreturnstring As String, ByVal ureturnlength As Long, ByVal hwndcallback As Long) As Long 四 程 式 設 計 ( 一 ) 程 式 流 程 圖 下 圖 為 本 專 題 研 究 的 程 式 流 程 圖 : START 是 是 否 再 玩 否 END 初 值 設 定 按 下 要 牌 是 否 比 牌 是 勝 負 判 斷 玩 家 輸 玩 家 贏 顯 示 你 贏 了 否 下 注 否 是 加 加 減 注 加 五 百 顯 示 你 輸 了 籌 碼 減 去 下 注 金 額 籌 碼 加 上 下 注 金 額 減 減 五 百 重 啟 新 局 圖 二 程 式 流 程 圖 ( 二 ) 程 式 演 算 法 : Step1: 初 值 設 定 及 洗 牌 Step2: 判 斷 是 否 壓 下 要 牌 鈕 是 跳 至 Step3, 否 跳 至 Step4 Step3: 判 斷 是 否 要 比 牌, 是 跳 至 Step6, 否 跳 至 Step1 Step4: 判 斷 是 否 下 注 否 跳 至 Strp1 Step5: 判 斷 是 否 加 減 注, 是 的 話 籌 碼 加 500 跳 至 Step2, 否 籌 碼 減 500, 跳 至 Step2 Step6: 判 斷 電 腦 之 點 數 否 大 於 玩 家 是 跳 至 Step7, 否 跳 至 Step8 5
Step7: 視 窗 跳 出 顯 示 你 贏 了, 籌 碼 加 上 注 金 額 跳 至 Step9 Step8: 視 窗 跳 出 顯 示 你 輸 了, 籌 碼 值 減 去 注 金 額 跳 至 Step9 Step9: 判 斷 是 否 需 要 重 新 啟 動 新 的 一 局, 若 為 否 則 離 開 視 窗 五 程 式 說 明 ( 一 ) 補 牌 程 式 碼 usum1 = usum1 + ccc(m(nt).number, 1) ' 發 一 張 新 牌 並 算 出 總 數 值 Label8 = usum1 If usum1 > 21 Then ' 如 果 總 數 值 大 於 21 If uflag1 > 0 Then ' 則 判 斷 是 否 有 A, 有 則 將 A 換 成 1 繼 續 遊 戲 uflag1 = uflag1 1 : usum1 = usum1 10 Label8 = usum1: Exit Sub MsgBox " 你 輸 了 ": money = money - bet: Label5 = money: q1 = 0: Command6.Enabled = False ' 如 果 還 是 大 於 21 則 視 窗 顯 示 " 你 輸 了 ", 總 籌 碼 減 掉 下 注 值 If flag2 = False Then For i = 1 To nt ' 刪 除 全 部 數 值 JTechCard1(i).Visible = False Unload JTechCard1(i) Next If money <= 0 Then ' 如 果 總 數 值 <=0, 由 視 窗 問 你 是 否 在 玩 ans = MsgBox(" 是 否 再 玩 ", vbyesno) If ans = 6 Then ' 回 傳 為 6 則 呼 叫 form_load Call Form_Load Exit Sub Else End ' 反 之 結 束 Call play Else flag2 = False Else If usum1 = 21 Then 6
MsgBox " 你 贏 了 ": q1 = 0: Command6.Enabled = False ' 如 果 你 的 總 數 值 等 於 21 則 獲 勝 money = money + bet: Label5 = money ' 總 籌 碼 加 掉 下 注 值 If flag2 = False Then For i = 1 To nt JTechCard1(i).Visible = False ' 刪 除 全 部 數 值 Unload JTechCard1(i) Next Call play Else flag2 = False End Sub ( 二 ) 比 牌 程 式 碼 Do While csum < 16 ' 如 果 莊 家 總 數 值 小 於 16, 再 補 發 一 張 csum = csum + ccc(m(nt).number, 0) ' 計 算 莊 家 總 數 值 Label7 = csum Loop If cflag > 1 And csum > 21 Then cflag = cflag - 1: csum = csum - 10: Label7 = csum: GoTo www ' 則 判 斷 是 否 有 A, 有 則 將 A 換 成 1 繼 續 遊 戲 If q1 <> 0 Then If csum > 21 Or usum1 > csum Then ' 勝 負 判 斷 MsgBox " 你 贏 了 ": q1 = 0 money = money + bet: Label5 = money Else MsgBox " 你 輸 了 ": money = money - bet: Label5 = money: q1 = 0 If q2 = 0 Then If money <= 0 Then ' 如 過 錢 扣 到 <=0 則 由 視 窗 問 你 是 否 再 玩 ans = MsgBox(" 是 否 再 玩 ", vbyesno) Call play: Exit Sub ' 回 傳 為 6 則 再 玩 一 次 7
六 研 究 成 果 未 壓 下 比 牌 鍵 前 對 方 第 一 張 蓋 著 壓 下 此 鍵 可 換 一 手 新 的 牌, 籌 碼 則 扣 500 壓 下 此 鍵 可 得 知 21 點 遊 戲 規 則 壓 下 此 鍵 可 撥 放 內 建 音 樂 加 減 注 一 次 以 500 為 限 圖 三 程 式 開 始 時 的 畫 面 壓 下 要 牌 鈕, 程 式 將 發 配 一 張 牌 給 玩 家 兩 張 牌 點 數 相 同 時, 得 以 壓 下 分 牌 鍵 使 手 白 由 一 手 變 為 兩 手 壓 下 此 鍵 由 程 式 計 算 點 數 分 判 定 輸 贏 上 圖 三 為 本 專 題 製 作 遊 戲 的 起 始 畫 面, 玩 家 可 運 用 視 窗 右 方 的 八 個 功 能 按 鍵 進 行 遊 戲, 每 個 按 鍵 的 功 能 說 明 如 上 圖 三 所 示 對 方 牌 面 點 數, 翻 開 覆 蓋 的 牌 當 按 下 比 牌 鍵, 程 式 就 會 進 行 勝 負 判 當 定 壓 下 比 我 方 牌 面 的 點 數 當 壓 下 比 牌 鍵 後 Msgbox 跳 出 視 窗 顯 示 你 輸 / 贏 了 圖 四 按 下 比 牌 鍵 後 的 畫 面 8
上 圖 四 為 勝 負 判 斷 展 示 圖, 下 圖 五 為 重 新 計 算 籌 碼 後 的 新 局 展 示 圖 自 動 發 牌 下 新 牌 給 莊 家 ( 電 腦 ) 壓 下 確 定 後, 依 據 輸 贏 籌 碼 加 減 500 自 動 發 下 新 牌 給 玩 家 圖 五 按 下 確 定 後 顯 示 新 局 示 意 圖 當 起 始 牌 型 點 數 項 同 時 可 進 行 分 牌 分 牌 後 可 進 行 上 下 兩 組 牌 組 補 牌 補 牌 完 畢 後 會 進 行 兩 組 比 牌 勝 負 顯 示 圖 六 按 下 分 牌 按 鍵 後 程 式 運 作 示 意 圖 圖 六 為 啟 動 分 牌 特 殊 指 令 的 程 式 運 作 過 程, 玩 家 將 同 時 擁 有 兩 副 牌 一 同 進 行 9
遊 戲, 而 輸 贏 的 結 果 計 算 也 都 變 為 兩 份 参 結 論 一 未 來 展 望 經 過 本 組 成 員 的 努 力 與 不 斷 改 進, 我 們 的 博 弈 小 遊 戲 21 點 終 於 大 功 告 成, 我 們 也 覺 得 全 體 組 員 在 程 式 的 撰 寫 能 力 上 進 步 不 少 但 我 們 這 次 僅 寫 出 了 最 基 本 的 功 能, 也 就 是 21 點 的 單 機 版 ; 期 許 未 來 能 把 程 式 優 化 的 更 加 完 整, 例 如 : 增 加 電 腦 對 戰 功 能 多 人 連 線 對 戰 多 副 牌 洗 亂 加 設 紀 錄 比 賽 成 績 功 能 等 等 如 果 可 能, 我 們 還 可 以 再 加 入 一 些 小 巧 思, 讓 我 們 的 21 點 不 再 只 是 平 凡 的 博 奕 遊 戲, 而 是 新 興 撲 克 牌 玩 法 不 過, 這 些 構 思 離 我 們 還 有 段 差 距, 有 待 我 們 精 進 實 力 後 再 去 設 計 製 作, 但 至 少 我 們 已 踏 出 了 關 鍵 的 第 一 步! 相 信 未 來, 我 們 撰 寫 程 式 的 能 力 更 熟 稔 後, 這 些 構 思 都 不 再 只 是 紙 上 談 兵, 而 是 可 以 一 一 去 實 現 的 夢 想 二 研 究 心 得 經 過 幾 個 月 的 努 力, 專 題 總 算 如 期 完 成, 過 程 中 我 們 時 常 反 覆 思 索 程 式 要 如 何 撰 寫 如 何 精 簡 ; 如 何 讓 使 用 者 更 方 便 明 瞭 完 成 的 同 時, 心 中 充 滿 習 得 新 事 物 的 感 動 和 欣 喜! 我 們 運 用 以 前 老 師 教 授 的 程 式, 加 上 自 己 的 思 考 方 式, 不 但 熟 悉 程 式 的 操 作, 更 學 到 了 不 同 的 用 法, 這 些 是 理 論 課 程 中 所 無 法 習 得 的 東 西, 在 親 身 參 與 實 踐 的 過 程 中, 我 們 獲 益 良 多 因 為 這 次 的 分 工 合 作, 加 深 了 組 員 間 的 默 契 與 情 感, 更 要 感 謝 老 師 的 協 助, 讓 我 們 匯 集 組 員 們 的 心 血, 成 就 了 這 個 21 點 肆 引 註 資 料 : [1] 黃 世 陽 吳 明 哲 何 嘉 益 張 志 成 吳 志 忠 曹 祖 聖 編 著 (1998) Visual Basic6.0 中 文 版 學 習 範 本 臺 北 市 : 松 崗 出 版 社 [2] 洪 國 勝 編 著 (2010) Visual Basic 程 式 設 計 與 專 題 製 作 臺 北 市 : 松 崗 出 版 社 [3] 李 啟 龍 俞 冠 廷 編 著 (2007) Visual Basic 2005 Express 程 式 設 計 臺 北 市 : 松 崗 出 版 社 [4] 李 啟 龍 尤 信 翰 編 著 (2009) 資 料 結 構 與 程 式 設 計 臺 北 市 : 文 魁 資 訊 股 份 有 限 公 司 [5] 位 元 文 化 編 著 (2001) Visual Basic 遊 戲 設 計 實 務 臺 北 市 : 文 魁 資 訊 10