JavaScript Blackjack 遊戲

HTMLCSSJavaScriptGame Logic
JavaScript Blackjack 遊戲 preview image

專案背景

這是我在大學「動態網頁程式設計」課程中的期中作業。目標是使用原生 JavaScript、HTML 和 CSS,不依賴任何前端框架,來實作一個功能完整的 Blackjack (21點) 遊戲。

一個有趣的要求是,老師希望我們加上「作弊模式」作為警惕,告訴我們網路賭博都不可信。當你勾選左下角的 "cheat" 後,遊戲的隨機抽牌演算法會被調整,讓莊家擁有極高的勝率。

技術實現與挑戰

對於當時的我來說,這個專案最大的挑戰在於完全使用原生 JavaScript 來處理所有遊戲狀態和互動邏輯。那個時候還沒有 ChatGPT 哈哈哈,所以全部都是一個個 console.log 慢慢刻出來的,但也因此學到很多:

  • 複雜的遊戲狀態管理:我使用了一系列全域變數來追蹤玩家與莊家的手牌、點數、金錢、當前回合等多個狀態。那時候對狀態管理還很不熟,現在回頭看,才發現自己當時手動實現了一個多麼脆弱的狀態機。

  • 非同步動畫流程:為了模擬真實賭場的發牌節奏,我使用了 async/await 搭配自訂的 sleep 函式。在每一次發牌的 DOM 操作之間創造出延遲,讓視覺動畫與遊戲邏輯能同步進行,這讓我對 JavaScript 的非同步有了更具體的認識。

  • Blackjack 核心規則實現

    • A 的彈性計分:在計分函式 countPoint 中,透過 if/else 判斷式,處理了 Ace (A) 應被計算為 1 點或 11 點的關鍵邏輯。
    • 分牌 (Split) 邏輯:當玩家拿到對子時,split() 函式會動態地將單一玩家區域 (playerArea) 分割成兩個獨立的手牌區域 (playerArea1, playerArea2),並分別追蹤它們的點數與爆牌狀態,這應該是整個專案中最複雜的狀態管理挑戰之一。
    • 莊家 AI:在玩家 stand() 後,莊家會根據「點數小於 17 必須加牌」的規則自動行動,直到滿足條件為止。
  • 原生 DOM 操作:遊戲中所有的視覺更新,例如動態生成卡牌 <img> 元素、更新計分板、顯示遊戲結果等,都是透過 document.getElementByIdcreateElement 等原生 DOM API 來完成的。

學習與反思

透過這個專案,我對 JavaScript 的事件驅動編程、非同步處理和狀態管理有了非常深刻的實戰經驗。它讓我體會到,雖然現代框架很強大,但理解其底層的原生 JavaScript 運作原理,才是建立穩固基礎的關鍵。

如果現在要重做這個專案,我會選擇使用 React (Next.js) 來進行元件化管理,並用 useStateuseReducer Hook 來處理複雜的遊戲狀態,取代直接操作 DOM。這樣不僅能讓程式碼的結構更清晰、更容易維護,也能更好地將 UI 表現與遊戲邏輯分離。


註:本文案使用 Gemini 2.5 Pro 進行最終的文字潤飾。