C++实现扫雷游戏FloodFill算法时递归陷入无限循环的问题排查
解决扫雷游戏中0单元格递归无限循环的问题
嘿,我一眼就看出你遇到的无限递归问题出在哪了——你的floodFill函数没有检查目标单元格是否已经被揭开(也就是buttons[row][col].second的状态),导致相邻的0单元格会互相反复调用对方,直接陷入死循环。
举个具体场景:假设单元格(0,0)和(0,1)都是0,当你点击(0,0)时,它会调用(0,1)的floodFill;而(0,1)处理完自身后,又会回头调用(0,0)的floodFill。这时候(0,0)已经被标记为揭开状态了,但你的代码没做这个判断,就会再次执行递归逻辑,无限重复这个过程。
修复后的代码方案
只需要在处理每个相邻单元格前,先检查它未被揭开且不是地雷,再执行后续操作:
void MainWindow::floodFill(int row, int col) { // 先确认当前单元格是0,否则直接返回 if(buttons[row][col].first->text() != "0") { return; } // 上方单元格 if(row > 0 && !buttons[row-1][col].second && buttons[row-1][col].first->text() != "*") { buttons[row-1][col].first->setStyleSheet("background-color: grey; color: red; font-size: 24px"); buttons[row-1][col].second = true; floodFill(row-1,col); } // 下方单元格 if(row < 9 && !buttons[row+1][col].second && buttons[row+1][col].first->text() != "*") { buttons[row+1][col].first->setStyleSheet("background-color: grey; color: red; font-size: 24px"); buttons[row+1][col].second = true; floodFill(row+1,col); } // 右方单元格 if(col < 9 && !buttons[row][col+1].second && buttons[row][col+1].first->text() != "*") { buttons[row][col+1].first->setStyleSheet("background-color: grey; color: red; font-size: 24px"); buttons[row][col+1].second = true; floodFill(row,col+1); } // 左方单元格 if(col > 0 && !buttons[row][col-1].second && buttons[row][col-1].first->text() != "*") { buttons[row][col-1].first->setStyleSheet("background-color: grey; color: red; font-size: 24px"); buttons[row][col-1].second = true; floodFill(row,col-1); } }
额外优化建议
你会发现四个方向的代码重复度很高,可以把设置单元格状态的逻辑抽成一个辅助函数,让代码更简洁:
void MainWindow::revealCell(int row, int col) { buttons[row][col].first->setStyleSheet("background-color: grey; color: red; font-size: 24px"); buttons[row][col].second = true; if(buttons[row][col].first->text() == "0") { floodFill(row, col); } } // 修改clickCell和floodFill中的调用 void MainWindow::clickCell(int row, int col) { revealCell(row, col); } void MainWindow::floodFill(int row, int col) { if(buttons[row][col].first->text() != "0") { return; } if(row > 0 && !buttons[row-1][col].second && buttons[row-1][col].first->text() != "*") { revealCell(row-1, col); } // 其他方向同理... }
这样不仅减少了重复代码,也让逻辑更清晰,后续维护起来更方便。
内容的提问来源于stack exchange,提问作者user15941196
相关产品推荐
相关产品推荐

