0%

JS地下城8F-井字遊戲

作品

作品

井字遊戲

規則

  1. 【特定技術】先手為 O,後手為 X,某方獲勝時,上方會紀錄各方的獲勝戰績
  2. 【特定技術】每回合結束後,會判定結果頁(平手、O 獲勝、X 獲勝)
  3. 【特定技術】需符合 RWD,能在低螢幕解析度也能遊玩,介面不能超出 x 軸,至少在以下解析度能夠遊玩。
    • iPhone SE 320px
    • iPhone 8 375px
    • iPhone PLUS 414px
  4. 【特定技術】請使用瀏覽器離線儲存技術,將戰績保留起來,重新打開遊戲也仍可觀看到歷史戰績。技術請任選以下幾種
    • Cookie
    • localStorage
  5. 【書寫能力】請寫 BLOG,描述你在開發「滿足獲勝條件」解題思維來進行加強描述
    • 上面三個 O 符合獲勝條件
    • 斜線三個 X 符合獲勝條件

規劃

  • html + CSS
    • row rol-cols-3
    • CSS 圓圈
    • CSS 交叉
    • CSS 空心圓圈
  • JavaScript
    • 點擊 start 時轉換遊戲畫面
    • 點籍 restart 時重置遊戲
  • 遊戲畫面 html + CSS
    • 戰績區塊
    • 井字區塊
    • 結果區塊
      • CSS ::after{文字}
      • 勝者顯示
      • 平手顯示
  • 螢幕解析度 RWD
    • 320px、375px、414px (題目要求)
    • sm、md、lg、xl (依據 Bootstarp 5)
  • 離線紀錄
    • localstorage.setItem('索引名稱', JSON.string())
    • localstorage.getItem('索引名稱')
  • 連線規則
    • 連線後加總有八種情況
    • 上、中橫、下
    • 右、中直、左
    • 正斜、反斜

連線規則

第一種想法 - 按鈕對應加總

  • 將按鈕給予對應值,9 個按鈕給 1~9 的值
    • 6 上、12 左、18 右、24 下
    • 15 中橫中直
  • 問題一
    • 玩家點不同行列的數字,加總會一樣
    • 分別是 4 與 6 會有各三種
    • 3+6+9、4+6+8、5+6+7,第一種才是正確
    • 1+4+7、2+4+6、3+4+5,第一種才是正確
  • 問題二
    • 暫存陣列存放了超過四個數字,則無法加總

第二種想法 - 多個暫存陣列

  • 建立 8 個陣列,根據規則 top、center`、bottom等等
  • 根據按鈕所帶的值分類,將按鈕分類到 8 個陣列中
    • 例如按鈕一會有三個連線規則 top、rignt、backslash
  • 再從該陣列中,利用 every() 對比該陣列中的值是否相同,若否,則無連線
  • 若比對值均相同,代表連線成功,下一步則顯示贏家或平手
  • 缺點是 code 很長
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const top = []
const slash = []
const left = []
// ... 以此類堆

// 每次按鈕點擊後就將該鈕對應號碼加入此陣列
let recordStorage []
// 紀錄的預設值為
let record = {
gamer : 1,
value : 1
}
// 點擊時,假設玩家一點了按鈕一
record.gamer = 1
record.value = 1

// 根據規則將資料放入對應的暫存陣列
recordStorage.forEach( item => {
switch(item.value){
case '1':
top.push(item)
slash.push(item)
left.push(item)
}
})

// 利用 every 檢查陣列資料是否相同,依據判斷回報 true or false
// 若回報 true ,則為已連線
top.every( item => {
return item.value === 1
})

第三種想法(參考攻略文)

  • 根據按鈕所帶的內容,O 為 1,X 為 -1
  • 連線規則可以拆解為
    • for 迴圈 n=1n<3
    • 橫向按鈕,3n、3n+1、3n+2
    • 直向按鈕,n、n+3、n+6
    • 正斜按鈕 0、4、8
    • 反斜按鈕 2、4、6
  • 將規則之三個數字相加取絕對值,若為3,則取得內容值即為贏家
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // 可以選擇 O 點擊時 value 賦予 1,X 賦予 -1
    // 或者取得 textContent 的內容再寫判斷,因為還要判斷是否已點擊,所以選擇判斷內容再轉成 1 或 -1
    let btnAll = document.querySelectorAll('.btn')
    let winer = null

    let slash = Math.abs( btnAll[0].value + btnAll[4].value + btnAll[8].value )
    let backSlash = Math.abs( btnAll[2].value + btnAll[4].value + btnAll[6].value )
    for (n = 0 ; n < 3 ; n++ ) {
    let row = Math.abs( btnAll[3n].value + btnAll[3n+1].value + btnAll[3n+2].value )
    let col = Math.abs( btnAll[n].value + btnAll[n+3].value + btnAll[n+6].value )
    if (row === 3) return winer = btnAll[3n].textContent
    if (col === 3) return winer = btnAll[n].textContent
    }
    if (slash === 3) return winer = btnAll[0].textContent
    if (backSlash === 3) return winer = btnAll[2].textContent
    // 接著就是控制 CSS

戰績紀錄

localstorage

  • 設定 localstorage
    • localstorage.setItem('test', JSON.string(物件))
  • 取得 localstorage
    • 建立變數存放 JSON.parse(localstorage.getItem('test'))

參考來源

  1. MaxLee - JS地下城[8F] - 井字遊戲