讓我們一起來玩掃雷游戲!
給定一個代表游戲板的二維字符矩陣, 'M' 代表一個未挖出的地雷,'E' 代表一個未挖出的空方塊,'B' 代表沒有相鄰(上,下,左,右,和所有4個對角線)地雷的已挖出的空白方塊,數字('1' 到 '8')表示有多少地雷與這塊已挖出的方塊相鄰,'X' 則表示一個已挖出的地雷,
現在給出在所有未挖出的方塊中('M'或者'E')的下一個點擊位置(行和列索引),根據以下規則,回傳相應位置被點擊后對應的面板:
- 如果一個地雷('M')被挖出,游戲就結束了- 把它改為 'X',
- 如果一個沒有相鄰地雷的空方塊('E')被挖出,修改它為('B'),并且所有和其相鄰的未挖出方塊都應該被遞回地揭露,
- 如果一個至少與一個地雷相鄰的空方塊('E')被挖出,修改它為數字('1'到'8'),表示相鄰地雷的數量,
- 如果在此次點擊中,若無更多方塊可被揭露,則回傳面板,
示例 1:
輸入:
[['E', 'E', 'E', 'E', 'E'],
['E', 'E', 'M', 'E', 'E'],
['E', 'E', 'E', 'E', 'E'],
['E', 'E', 'E', 'E', 'E']]
Click : [3,0]
輸出:
[['B', '1', 'E', '1', 'B'],
['B', '1', 'M', '1', 'B'],
['B', '1', '1', '1', 'B'],
['B', 'B', 'B', 'B', 'B']]
示例 2:
輸入:
[['B', '1', 'E', '1', 'B'],
['B', '1', 'M', '1', 'B'],
['B', '1', '1', '1', 'B'],
['B', 'B', 'B', 'B', 'B']]
Click : [1,2]
輸出:
[['B', '1', 'E', '1', 'B'],
['B', '1', 'X', '1', 'B'],
['B', '1', '1', '1', 'B'],
['B', 'B', 'B', 'B', 'B']]
注意:
- 輸入矩陣的寬和高的范圍為 [1,50],
- 點擊的位置只能是未被挖出的方塊 ('M' 或者 'E'),這也意味著面板至少包含一個可點擊的方塊,
- 輸入面板不會是游戲結束的狀態(即有地雷已被挖出),
- 簡單起見,未提及的規則在這個問題中可被忽略,例如,當游戲結束時你不需要挖出所有地雷,考慮所有你可能贏得游戲或標記方塊的情況,
class Solution {
/**
* 未挖出的地雷
*/
public static final char UNREVEALED_MINE = 'M';
/**
* 未挖出的空白區域
*/
public static final char UNREVEALED_EMPTY_SQUARE = 'E';
/**
* 已挖出的空白區域
*/
public static final char REVEALED_BLANK_SQUARE = 'B';
/**
* 已挖出的地雷,游戲結束
*/
public static final char REVEALED_MINE = 'X';
/**
* 數字,'1' ~ '8' 代表臨近的地雷數量
*/
public static final char DIGIT_0 = '0';
/**
* 8 個方向
*/
private static final int[][] DIRECTIONS = {{-1, -1}, {-1, 0}, {-1, +1}, {0, -1}, {0, +1}, {+1, -1}, {+1, 0}, {+1, +1}};
public char[][] updateBoard(char[][] board, int[] click) {
// 點擊坐標
int x = click[0];
int y = click[1];
// 如果一個地雷('M')被挖出,游戲就結束了- 把它改為 'X',
if (board[x][y] == UNREVEALED_MINE) {
board[x][y] = REVEALED_MINE;
return board;
}
dfs(board, x, y);
return board;
}
/**
* @param board 游戲板
* @param x X坐標
* @param y Y坐標
*/
private void dfs(char[][] board, int x, int y) {
// 游戲板邊界
int X = board.length;
int Y = board[0].length;
// 計數器
int mineCounter = 0;
// 掃描周邊8個方向
for (int[] direction : DIRECTIONS) {
int dx = direction[0] + x;
int dy = direction[1] + y;
// 越界
if (dx < 0 || dy < 0 || dx >= X || dy >= Y) {
continue;
}
// 掃到地雷,計數器加一
if (board[dx][dy] == UNREVEALED_MINE) {
++mineCounter;
}
}
// 掃描到地雷數量大于0,滿足條件3
// 如果一個至少與一個地雷相鄰的空方塊('E')被挖出,修改它為數字('1'到'8'),表示相鄰地雷的數量
if (mineCounter > 0) {
board[x][y] = (char) (mineCounter + DIGIT_0);
return;
}
// 如果一個沒有相鄰地雷的空方塊('E')被挖出,修改它為('B'),并且所有和其相鄰的未挖出方塊都應該被遞回地揭露
board[x][y] = REVEALED_BLANK_SQUARE;
for (int[] direction : DIRECTIONS) {
int dx = direction[0] + x;
int dy = direction[1] + y;
// 越界
if (dx < 0 || dy < 0 || dx >= X || dy >= Y || board[dx][dy] != UNREVEALED_EMPTY_SQUARE) {
continue;
}
dfs(board, dx, dy);
}
}
}
JS寫的一個小游戲
<iframe height="265" style="width: 100%;" scrolling="no" title="掃雷游戲" src="https://codepen.io/hiro93-the-animator/embed/wvGzOKy?height=265&theme-id=light&default-tab=html,result" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> See the Pen 掃雷游戲 by Hiro (@hiro93-the-animator) on CodePen. </iframe>轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/2197.html
標籤:其他
上一篇:LeetCode-二叉樹
