來自 LIOJ 上的題目。這題在考二維陣列的應用,覺得還真的蠻容易搞混的,所以想記錄下來。
解題方向
最簡單的方式就是窮舉所有會贏的可能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| O O O ------- O O O ------- O O O ------- O O O ------- O O O
|
關於二維陣列
由於拿到的資料會是 ['ooo', 'xxo', 'xxo']
,所以如果要取出每一行的字串的話:
如果要取出每行的一個字元的話:
1 2 3 4 5 6 7 8 9 10 11 12
| ooo 'o' 'o' 'o' xxo 'x' 'x' 'o' xxo 'x' 'x' 'o'
|
(上下一起對照著看,比較不會搞混)
如果現在我們想要看「橫排」的每一個字元有沒有相同?會發現可以利用迴圈來做:
1 2 3 4 5
| for(let i=0; i<3; i++) { if(lines[i][0] === lines[i][1] && lines[i][1] === lines[i][2]) { return lines[i][0] } }
|
每一行要檢查的字元都固定為 [0][1][2]
,需要改變的只有前面代表「行數」的索引值。
反過來,如果要看「直排」的每一個字元有沒有相同?也可以用迴圈來做:
1 2 3 4 5 6 7 8 9 10 11
| 'o' 'x' 'x'
'o' 'x' 'x'
'o' 'o' 'o'
|
1 2 3 4 5
| for(let i=0; i<3; i++) { if(lines[0][i] === lines[1][i] && lines[1][i] === lines[2][i]) { return lines[0][i] } }
|
每一個字元要檢查的固定行數為 [0][1][2]
,需要改變的只有後面代表「字元」的索引值。
所以這樣就處理完「橫排」跟「直排」的部分了,接下來只要把「斜排」的部分也做完就搞定:
1 2 3 4 5 6 7
| 'o' 'x' 'o'
'o' 'x' 'x'
|
這裡沒有辦法寫成迴圈,所以直接判斷就好:
1 2 3 4 5 6
| if(lines[0][0] === lines[1][1] && lines[1][1] === lines[2][2]) { return lines[0][0] } if(lines[0][2] === lines[1][1] && lines[1][1] === lines[2][0]) { return lines[0][2] }
|
工具都備好了,最後只要集合起來就完成囉:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| function whoWin(lines) { for(let i=0; i<3; i++) { if(lines[i][0] === lines[i][1] && lines[i][1] === lines[i][2]) { return lines[i][0] } } for(let i=0; i<3; i++) { if(lines[0][i] === lines[1][i] && lines[1][i] === lines[2][i]) { return lines[0][i] } } if(lines[0][0] === lines[1][1] && lines[1][1] === lines[2][2]) { return lines[0][0] } if(lines[0][2] === lines[1][1] && lines[1][1] === lines[2][0]) { return lines[0][2] } return 'DRAW' }
|
另一種選擇
如果二維陣列不好理解的話,你也可以把資料轉換成一行字串,例如說 'oooxxoxxo'
,接著在照著上面的做法也是 ok。
先用數字表示位置:
1 2 3 4 5 6 7
| o o o x x o x x o
0 1 2 3 4 5 6 7 8
|
橫排的情況:
1 2 3 4 5 6 7 8 9 10
| let str = 'oooxxoxxo' for(let i=0; i<3; i++) { let n = i*3 if(str[n] === str[n+1] && str[n+1] === str[n+2]) { return str[n] } }
|
直排的情況:
1 2 3 4 5 6 7 8 9
| let str = 'oooxxoxxo' for(let i=0; i<3; i++) { if(str[i] === str[i+3] && str[i+3] === str[i+6]) { return str[i] } }
|
斜排的情況:
1 2 3
| let str = 'oooxxoxxo' if(str[0] === str[4] && str[4] === str[8]) return str[0] if(str[2] === str[4] && str[4] === str[6]) return str[2]
|
最後一樣組合起來就大功告成:
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
| function whoWin(str) { for(let i=0; i<3; i++) { let n = i*3 if(str[n] === str[n+1] && str[n+1] === str[n+2]) { return str[n] } } for(let i=0; i<3; i++) { if(str[i] === str[i+3] && str[i+3] === str[i+6]) { return str[i] } } if(str[0] === str[4] && str[4] === str[8]) return str[0] if(str[2] === str[4] && str[4] === str[6]) return str[2]
return 'DRAW' }
|