0%

js 2048

 

See the Pen 2048 by 喇賽人 (@weber87na) on CodePen.

剛開工整個很沉悶 , 剛好看到 2048 這個遊戲 , 刷了一陣子覺得滿有趣的 , 就自己寫看看 , 想了半天也是挺燒腦的

其實最主要就一個規則 , 做出來後上下左右滑都可以套用 , 我是由往右滑開始思考

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
32
33
function right() {
for (let x = 4 - 1; x >= 0; x--) {
if (x === 3) {
rightX3(0, x)
rightX3(1, x)
rightX3(2, x)
rightX3(3, x)
}

if (x === 2) {
rightX2(0, x)
rightX2(1, x)
rightX2(2, x)
rightX2(3, x)

}

if (x === 1) {
rightX1(0, x)
rightX1(1, x)
rightX1(2, x)
rightX1(3, x)

}

if (x === 0) {
rightX0(0, x)
rightX0(1, x)
rightX0(2, x)
rightX0(3, x)
}
}
}

第一格邏輯

首先當 x === 3 的狀況就單純移動方塊 , 關鍵就是套個 while 迴圈 , 當目前元素為 0 時就開始不斷移動元素
另外要防止這條橫線全為 0 的狀況 , 所以用 every 判斷如果全為 0 就直接 return

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function rightX3(y, x) {
if (board[y].every(c => c === 0)) return



let current = board[y][x]
while (current === 0) {
board[y][x] = board[y][x - 1]
board[y][x - 1] = board[y][x - 2]
board[y][x - 2] = board[y][x - 3]
board[y][x - 3] = 0

//重新設定值
current = board[y][x]
}
}

第二格邏輯

接著 第二格邏輯 寫出來了就基本全寫出來 , 後面的格子就是看有幾格跑幾次進行微調 , code 應該可以更精簡不過太晚了 -. -
首先也是要防止全部為 0 的狀況
接著跑 3 次 迴圈動態的把元素也給往右邊移動
當目前元素為 0 的話單純的把元素往右推 , 當推到最後一個則設定為 0 , 如果你是最後一格這個動作就可以直接省略
然後當目前元素與右邊的元素相等時則需要把兩數加起來更新分數 , 因為加起來這個動作只會有一次 , 所以外圍設定 flag 來控制 , 如果已經加過了就不給加第二次

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
32
function rightX2(y, x) {
if (board[y].every(c => c === 0)) return

let flag = false
for (let counter = 0; counter < 3; counter++) {
let current = board[y][x]

//如果為 0 的情況
//則移動左邊兩個
if (current === 0) {
board[y][x] = board[y][x - 1]
board[y][x - 1] = board[y][x - 2]
board[y][x - 2] = 0
}

//如果目前這個跟最右邊那個數值相等的話
//則兩數相乘
//接著移動左邊兩個
if (flag === false) {
let prev = board[y][x + 1]
if (current === prev) {
updateScore(current)
board[y][x + 1] = current * 2
board[y][x] = board[y][x - 1]
board[y][x - 1] = board[y][x - 2]
board[y][x - 2] = 0

flag = true
}
}
}
}

gg 判斷

最後是判斷 gg 的規則 , 這個還挺簡單的 , 就是先看棋盤滿了沒
board[y] 表示取得那一條 row 橫條 接著搭配 some 是否有任意元素為 0 有的話表示沒滿 , 反之就是滿了
接著以兩個元素為一組橫向掃瞄 , 接著直向掃描 , 當目前元素與後面那個元素相等時 , 表示還可以繼續玩 , 如果全掃描完了則表示已經結束了

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
32
33
34
35
36
37
38
39
//是否棋盤全滿
function isFull() {
let result = false
for (let y = 0; y < 4; y++) {
if (board[y].some(c => c === 0)) {
return false
}
}

return true
}

function isGoodGame() {
if (isFull() === true) {
for (let y = 0; y < 4; y++) {
for (let x = 0; x < 4 - 1; x++) {
let current = board[y][x]
let next = board[y][x + 1]
if (current === next)
return false

}
}

for (let x = 0; x < 4; x++) {
for (let y = 0; y < 4 - 1; y++) {
let current = board[y][x]
let next = board[y + 1][x]
if (current === next)
return false
}
}

return true
} else {
return false
}

}
關閉