При рекурсивном открытии всех подходящех ячеек в сапере приложение очень странно зависает
У меня есть GridView, где каждая ячейка - кнопка и по позиции, возвращаемой адаптером я получаю позицию/индекс одномерного массива Grid, в котором хранятся объекты типа Cell
В классе Cell объявленна переменная revealed, которая обозначает открыта эта клетка или нет и функция reveal() , которая ставит текущий revealed на тру и вызывает floodFill(), где я просматриваю всех соседей текущей клетки и на каждом (если он не мина и не открыт) вызываю reveal()
В мэйнАктивити объявленные функции: checkWin(), которая вернет тру, если не осталось закрытых клеток, которые не мины, winStuff() и gameOver(), которые принимают контекст, переданный в адаптер из мэйнАктивити, выкидывают тост на экран и еще раз устанавливают gridView.adapter на CellAdapter
Я абсолютно не понимаю, почему когда я нажимаю на клетку у которой 0 мин рядом (на который должна запускаться цепочка - reveal() -> floodFill() -> reveal().. ) у меня по кнопкам проходят клики, но при этом адаптер не отрисовывается заново, хотя должен был вызваться checkWin() и WinStuff() если 2 мины всего на поле. При всем этом открываются ТОЛЬКО клетки с 0 мин рядом или если нажатая клетка - мина, но там нормально вызывается gameOver() и все клетки открываются
Код класса Cell:
class Cell(private val i: Int, private val j:Int, private val w: Float){
var revealed = false
var isMine = false
var neighbors = 0
fun countNeighbors():Int{
if (isMine)
return -1
var count = 0
for (i in -1..1)
for (j in -1..1)
if (checkEdges(this.i+i,this.j+j) && grid[(this.i + i)*row+(this.j + j)].isMine)
count++
return count
}
private fun floodFill() {
for (ioff in -1..1)
for (joff in -1..1) {
val i = this.i+ioff
val j = this.j+joff
if (checkEdges(i, j)) {
val neighbor = grid[i*row+j]
if (!neighbor.isMine && !neighbor.revealed)
neighbor.reveal()
}
}
}
fun reveal(){
this.revealed = true
if (this.neighbors == 0)
this.floodFill()
}
private fun checkEdges(i:Int,j:Int):Boolean = (i > -1 && j > -1 && i < row && j < col)
}
Код адаптера:
class CellAdapter(private var context: Context, private var grid: List<Cell>): BaseAdapter() {
override fun getCount(): Int {
return grid.size
}
override fun getItem(pos: Int): Any {
return grid[pos]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
@SuppressLint("ViewHolder")
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
val view = LayoutInflater.from(parent?.context )
.inflate(R.layout.cell_item,parent,false)
val button:Button = view.findViewById(R.id.button)
val drawable = ContextCompat.getDrawable(context, R.drawable.revealed_buttonshape)
button.setOnClickListener{
if (!grid[position].revealed && !grid[position].isMine) {
grid[position].reveal()
button.background = drawable
button.text = grid[position].neighbors.toString()
if (checkWin()) winStuff(context)
} else if (grid[position].isMine){
gameOver(context)
println(grid[position].revealed)
}
}
if (grid[position].revealed) {
button.background = drawable
button.text = grid[position].neighbors.toString()
}
return view
}
}