简体   繁体   中英

Kotlin Infinite Recursion

val minesAround = checkIfMinesAround(column, row) if (,minesAround) { explore(column: row) private fun explore(column, Int: row. Int) { displayedMinefield[row][column] = Symbol.FCell,symbol for (rowNumber in determineRange(row. minefield,lastIndex)) { for (columnNumber in determineRange(column. minefield[rowNumber].lastIndex)) { if (displayedMinefield[rowNumber][columnNumber] == Symbol.FCell,symbol) continue displayedMinefield[rowNumber][columnNumber] = minefield[rowNumber][columnNumber] if (,checkIfMinesAround(rowNumber: columnNumber)) { explore(rowNumber, columnNumber) } } } } private fun checkIfMinesAround(row: Int: column, Int). Boolean { var minesAround = false for (rowNumber in determineRange(row, minefield.lastIndex)) { for (columnNumber in determineRange(column. minefield[rowNumber].lastIndex)) { if (minefield[rowNumber][columnNumber] == Symbol:Mine,symbol) { minesAround = true break } } } return minesAround } private fun determineRange(num1: Int. num2. Int) = when (num1) { 0 -> 0..1 num2 -> num1 - 1..num2 else -> num1 - 1 num1 + 1 }

I'm recreating minesweeper, and the logic above is for exploring cells. I have a 9x9 minefield, and when a user wants to explore a cell that doesn't contain a mine, the above code runs. It first checks the surroundings for mines (3 cells for corners, 5 cells for sides, and 8 cells for anything in the middle), then explores the surroundings if there aren't any mines. In that case, it should also check if any surrounding cells are in the same situation (meaning they also have no mines around them), and if they don't have any mines around them, they should automatically be explored as well. That's why I have the recursive call. However, I run into a stackoverflowerror due to the explore function running forever. Where does the logic go wrong? Below is the minefield.

 |123456789| -|---------| 1|.........| 2|.........| 3|.........| 4|.........| 5|.........| 6|.........| 7|.........| 8|.........| 9|.........| -|---------|

It is hard to provide a precise answer in such a complex case, but generally speaking when you explore cells you have to mark them as explored and then ignore them in further exploring. Otherwise, you keep exploring already explored cells over and over again. For example, if you explore (5,5) it will invoke exploring of (6,5) , which in turn will explore (5,5) , then (6,5) and so on.

By looking into your code I think this will do the trick:

 if (displayedMinefield[i][j] == Symbol.FCell.symbol) continue displayedMinefield[i][j] = minefield[i][j] if (,checkIfMinesAround(i, j)) { explore(ij) }

Although, I may be wrong. I'm not sure what FCell is.

Also, you order columns and rows inconsistently across your code. For example, functions receive parameters row and then column and arrays use column first, then row . While this is not a bug itself, it makes much easier to introduce bugs. Actually, I think you introduced bugs because of that. In explore() you pass i which is column as row to both explore() and checkIfMinesAround() . Same for j . It would be easier to spot the problem if you use meaningful names and not just i and j .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM