【问题标题】:Programming challenges Minesweeper help: How to check for a "*" in a 2D string array?编程挑战扫雷帮助:如何检查二维字符串数组中的“*”?
【发布时间】:2013-03-27 02:37:37
【问题描述】:

我正在尝试为编程挑战网站编写扫雷程序,但无法检测 2D 数组中的某个元素是否为地雷并增加周围区域。 这是我的代码,用于检查数组角落中的地雷并增加周围区域

  public void constructPointers(){
    int counter = 0;
    for(int i = 0; i<row;i++){
        for(int j = 0;j<colm;j++){
            if(minefield[i][j].equals("*")){
                if(i == 0 && j == 0){
                    int val = Integer.parseInt(minefield[i+1][j]);
                    val++;
                    minefield[i+1][j] = "" + val;

                    val = Integer.parseInt(minefield[i][j+1]);
                    val++;
                    minefield[i][j+1] = "" + val;
                    val = Integer.parseInt(minefield[i+1][j+1]);
                    val++;
                    minefield[i+1][j+1] = "" + val;
                }
                if(i == minefield.length -1 && j == 0){
                    int val = Integer.parseInt(minefield[i-1][j]);
                    val++;
                    minefield[i-1][j] = "" + val;
                    val = Integer.parseInt(minefield[i][j+1]);
                    val++;
                    minefield[i][j+1] = "" + val;
                    val = Integer.parseInt(minefield[i-1][j+1]);
                    val++;
                    minefield[i-1][j+1] = "" + val;
                }
                if(i == 0 && j == minefield[i].length - 1){
                    int val = Integer.parseInt(minefield[i+1][j]);
                    val++;
                    minefield[i+1][j] = "" + val;
                    val = Integer.parseInt(minefield[i][j-1]);
                    val++;
                    minefield[i][j-1] = "" + val;
                    val = Integer.parseInt(minefield[i+1][j-1]);
                    val++;
                    minefield[i+1][j-1] = "" + val;
                }
                if(i == minefield.length - 1 && j == minefield[i].length -1){
                    int val = Integer.parseInt(minefield[i-1][j-1]);
                    val++;
                    minefield[i-1][j-1] = "" + val;
                    val = Integer.parseInt(minefield[i-1][j]);
                    val++;
                    minefield[i-1][j] = "" + val;
                    val = Integer.parseInt(minefield[i][j-1]);
                    val++;
                    minefield[i][j-1] = "" + val;
                }
                if(i == 0){
                    int val = Integer.parseInt(minefield[i+1][j]);
                    val++;
                    minefield[i+1][j] = "" + val;
                    val = Integer.parseInt(minefield[i][j+1]);
                    val++;
                    minefield[i][j+1] = "" + val;
                    val = Integer.parseInt(minefield[i+1][j+1]);
                    val++;
                    minefield[i+1][j+1] = "" + val;
                }
            }

如果我输入:

*.*
...
*.*

这段代码将输出:

* 2 *
2 4 2
* 2 *

我的问题是:如何让我的代码“跳过”相邻的地雷并增加周边区域? 如果我输入了

*.*
*..
*.*

我希望它输出:

    * 3 *
    * 5 2
    * 3 *

编辑:你们所有人都有很好的答案,但我选择了最佳答案,因为它解决了我遇到的许多其他我没有提到的问题。谢谢大家的帮助!

【问题讨论】:

  • 不要将代码写出 8 次,而是写一个 Direction 枚举,其中包含您可以移入的所有单步增量。例如,Java 中的 pastebin.com/06yNW2TD

标签: java matrix multidimensional-array arrays minesweeper


【解决方案1】:

只是为您的矿山更新循环提供建议:

// You are on a mine
if(minefield[i][j].equals("*")){

    // Now go around your current position
    for(int tempRow = i-1; tempRow <= i+1; tempRow++) {
        for(int tempCol = j-1; tempCol <= j+1; tempCol++) {
            // If a valid square and not a mine
            if(tempRow >= 0 && tempRow < row &&
                tempCol >= 0 && tempCol < colm &&
                !minefield[tempRow][tempCol].equals("*")) 
            {
                // Do your update stuff
                int val = Integer.parseInt(minefield[tempRow][tempCol]);
                val++;
                minefield[tempRow][tempCol] = "" + val;
            }
        }
    }
}

这个循环也可以更轻松地扩展到更大的电路板尺寸......

注意:如果不是地雷,我假设雷区初始化为“0”。否则第一个parseInt会有问题。

【讨论】:

  • 哇。我不敢相信我没有想到这一点。非常感谢!
  • 看起来您只是遍历每个单元格,并且对于每个不是地雷的单元格,计算单元格周围的地雷数。换句话说,您一次计算每个单元格的计数。这处理了有关如何处理相邻地雷的问题。
  • @ChrisGerken 上面的 sn-p 意味着存在于访问每个单元格的 OP 的原始循环中。第一个测试将检查当前单元格是否为地雷。然后内部循环将绕过它并增加非地雷空间的每个计数。我选择了这个模式来支持“做每个单元格并累积计数”模式,因为我假设我的单元格比非地雷单元格少,所以在外循环中瞄准只有我的单元格将限制次数内循环需要运行。
【解决方案2】:

您可能会发现遍历每个单元格更容易,并且对于每个不是地雷的单元格,计算单元格周围的地雷数。换句话说,您一次计算每个单元格的计数。这可以解决您关于如何处理相邻地雷的问题。

【讨论】:

    【解决方案3】:
    if(minefield[i][j] == "*"){
        // do stuff
    }
    

    我不明白有什么大不了的,嗯。

    编辑

    不正确 - 如 cmets 所述:

    if(minefield[i][j].equals("*")){
        // do stuff, they are equal.
    }
    

    附言不是很有建设性的答案,但我因为建设性的 cmets 而离开了它。

    【讨论】:

    • == 是比较字符串的糟糕方法。 equals() 是正确的方法,就像他在代码中所做的那样。
    • 哦,当然,失败了。我会删除我的答案,因为它没有建设性。
    • 同意@Pescis 永远不要对字符串使用 ==,因为这会检查引用相等而不是实际相等。使用 .equals();
    • 我会说整数作为内部表示 TBH 会更好。就像使用 -1 代表我的地雷,其余的代表相邻地雷的数量。计算机更喜欢整数而不是字符和字符串
    • @Pescis 一个字符一个整数.. 一个字符串是一个字符序列。 (操作的界限将根据可变性/不变性和索引而有所不同 - 当然在 Java 中是不可变的。)
    猜你喜欢
    • 2013-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-19
    • 2013-12-25
    • 2015-04-11
    • 2018-07-10
    • 2014-09-21
    相关资源
    最近更新 更多