iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 29
0

今天圈圈叉叉遊戲完成
寫了判斷連線的函式
也加了條件檢查是否點了重複的位置
如果原本的位置已經有圈或叉
或者是遊戲已經連線結束
便不會再讓使用者填寫

// reducer.js
if(OX[action.x][action.y] == "O" || OX[action.x][action.y] == "X"){
    window.alert("不可以作弊ㄛ~~~~");
    return state;
}

之所以寫的是「不為圈或叉」而不是「不為空」
是因為出現了一個很神奇的問題
當我將初始狀態設置為空的時候
會有一個不知來自何處的 padding
把表格空間的高完全吃光
檢查了上層、上上層
皆沒辦法除去這段神奇的 padding
所以我只好先填入 1 ~ 9 的編號
以撐起這個遊戲的框框

回到圈圈叉叉
如果已經有連線狀況
判斷遊戲是否結束會同時記錄連線的符號並且顯示出來
新開遊戲的行為則是把遊戲狀態清除
包括記錄遊戲的畫面狀態、勝利者等等
也就是初始化資料
如此一來便可以重新開始玩
透過按鈕觸發
可以隨時重新開始這樣

進到本日重點 - 猜數字遊戲
今日進度大概是
完成了顯示歷史猜題紀錄
能夠接收輸入的四位數字
並且判斷結果是幾個 A 幾個 B
但是!!!!!!
就是這個但是
遭遇了神奇的問題
狀態更新了

組件居然沒有跟著刷新
然後沒有任何的徵兆
任何的錯誤訊息提示
都沒有!!!!!!!
所以我只能繼續想像到底是哪裡出現了問題(哭哭)

不過還是紀錄一下今天所做的吧
首先
定義了猜數字遊戲的行為
分別是 猜數字、存放輸入的數字 和 重新開始

export function guessNum(){
    return{
        type : AB_GUESS
    }
}

export function saveInput(num){
    return{
        type : SAVE_NUM,
        num : num       
    }
}

export function playAgainAABB(){
    return{
        type : AB_AGAIN
    }
}

存放數字會把數字存進狀態值
透過一個 onChange 和一個 onClick 合作處理
onChange 會更新狀態內部存的輸入數值
onClick 則觸發判斷結果的行為

// AB.jsx
<input type="text" placeholder="請輸入4位不重複數字" 
       onChange={(event) => saveInput(event)} maxLength="4"/>
<input type="submit" value="確認" onClick={() => guessNum()}/>

一樣是傳遞整個事件
再透過 Reducer 去取出數值資料

// reducer.js
function ABGame(state = abData, action){
    switch(action.type){
        case AB_GUESS:
            if(!state.is4A){

                var userInput = state.lastNum;
                var ans = state.answer;
                var n = [];
                var i, j, a = 0, b = 0;

                for(i = 0; i < 4; i++){
                    n[i] = userInput.charAt(i);
                }
                for(i=0; i<4; i++){
                    for(j=0; j<4; j++){
                        if(ans[i] == n[j]){
                            if(i == j)
                                a++;
                            else
                                b++;
                        }
                    }
                }
                var H = state.History;
                H.push({
                    number:n,
                    A:a,
                    B:b
                })

                if(a == 4){
                    return Object.assign({},state,{
                        History:H,
                        is4A:true
                    });
                }else{
                    return Object.assign({},state,{
                        History: H,
                    });
                }
            }else{
                window.alert(遊戲已結束);
                return state;
            }
        case SAVE_NUM:
            return Object.assign({}, state, {
                lastNum: action.num.target.value
            });
        case AB_AGAIN:
            ...
        default:
            return state;
    }
}

猜數字的過程比較繁瑣
透過與狀態中記錄答案的 answer 陣列比較
產生出 A 和 B 的數目後
透過 push 以物件型式紀錄 四位數字與結果
並加入到存取歷史紀錄的 History 陣列資料中
其實原理和圈圈叉叉是很相近的
也透過console.log 檢查了
可惜還沒找到問題的根源
只能繼續追查下去啦!

參考資料

  1. tutorialspoint-ReactJS Tutorial
  2. React 官方文件

>>> 隊友任意門 <<<


Day29 end
by 瑞Ray ( ´•̥̥̥ω•̥̥̥` )


上一篇
【Day28】發現突破口!乘勝追擊 R
下一篇
【Day30】 30天 一步一腳印
系列文
激戰 ReactJS 30天31

尚未有邦友留言

立即登入留言