我目前正在做一个扫雷舰程序,我需要一点帮助来揭示其中的邻居。目前,我的程序可以为做的事情如下
1将是被选中的按钮,行是我需要填充的内容。目前,所选按钮周围的按钮是我可以填写的内容。
如果有必要,我可以发布代码。
提前感谢您的帮助。

1是一个地雷,4是阵列上的一个标记点
public int findneighbors(int row, int col) {
int count = 0;
if (board[row][col] == 2)
try {
if (board[row][col + 1] == 1 || board[row][col + 1] == 4)
count ++;
}
catch( ArrayIndexOutOfBoundsException e)
{
}
try {
if (board[row + 1][col + 1] == 1 || board[row + 1][col + 1] == 4)
count ++;
}
catch( ArrayIndexOutOfBoundsException e)
{
}
try {
if (board[row + 1][col - 1] == 1 || board[row + 1][col - 1] == 4)
count ++;
}
catch( ArrayIndexOutOfBoundsException e)
{
}
try {
if (board[row - 1][col - 1] == 1 || board[row - 1][col - 1] == 4)
count ++;
}
catch( ArrayIndexOutOfBoundsException e)
{
}
try {
if (board[row][col + 1] == 1 || board[row][col + 1] == 4)
count ++;
}
catch( ArrayIndexOutOfBoundsException e)
{
}
try {
if (board[row + 1][col] == 1 || board[row + 1][col] == 4)
count ++;
}
catch( ArrayIndexOutOfBoundsException e)
{
}
try {
if (board[row - 1][col] == 1 || board[row - 1][col] == 4)
count ++;
}
catch( ArrayIndexOutOfBoundsException e)
{
}
try {
if (board[row][col - 1] == 1 || board[row][col - 1] == 4)
count ++;
}
catch( ArrayIndexOutOfBoundsException e)
{
}
try {
if (board[row - 1][col + 1] == 1 || board[row - 1][col + 1] == 4)
count ++;
}
catch( ArrayIndexOutOfBoundsException e)
{
}
return count;
}
public int buttonFloodFill(int r, int c)
{
int loopCount = 0;
int rowCount = 1;
int colCount = 1;
while (loopCount < 1)
{
try {
if (g.getFloodValue(r,c + colCount) == true) {
board[r][c + colCount].setText(Integer.toString(g.findneighbors(r,c + colCount)));
board[r][c + colCount].setEnabled(false);
}
}
catch( ArrayIndexOutOfBoundsException e)
{
}
try {
if (g.getFloodValue(r,c - colCount) == true) {
board[r][c - colCount].setText(Integer.toString(g.findneighbors(r,c - colCount)));
board[r][c - colCount].setEnabled(false);
}
}
catch( ArrayIndexOutOfBoundsException e)
{
}
try {
if (g.getFloodValue(r + rowCount,c + colCount) == true) {
board[r + rowCount][c + colCount].setText(Integer.toString(g.findneighbors(r + rowCount,c + colCount)));
board[r + rowCount][c + colCount].setEnabled(false);
}
}
catch( ArrayIndexOutOfBoundsException e)
{
}
try {
if (g.getFloodValue(r + rowCount,c - colCount) == true) {
board[r + rowCount][c - colCount].setText(Integer.toString(g.findneighbors(r + rowCount,c - colCount)));
board[r + rowCount][c - colCount].setEnabled(false);
}
}
catch( ArrayIndexOutOfBoundsException e)
{
}
try {
if (g.getFloodValue(r - rowCount,c - colCount) == true) {
board[r - rowCount][c - colCount].setText(Integer.toString(g.findneighbors(r - rowCount,c - colCount)));
board[r - rowCount][c - colCount].setEnabled(false);
}
}
catch( ArrayIndexOutOfBoundsException e)
{
}
try {
if (g.getFloodValue(r - rowCount,c + colCount) == true) {
board[r - rowCount][c + colCount].setText(Integer.toString(g.findneighbors(r - rowCount,c + colCount)));
board[r - rowCount][c + colCount].setEnabled(false);
}
}
catch( ArrayIndexOutOfBoundsException e)
{
}
try {
if (g.getFloodValue(r - rowCount,c) == true) {
board[r - rowCount][c].setText(Integer.toString(g.findneighbors(r - rowCount,c)));
board[r - rowCount][c].setEnabled(false);
}
}
catch( ArrayIndexOutOfBoundsException e)
{
}
try {
if (g.getFloodValue(r + rowCount,c) == true) {
board[r + rowCount][c].setText(Integer.toString(g.findneighbors(r+ rowCount,c)));
board[r + rowCount][c].setEnabled(false);
}
}
catch( ArrayIndexOutOfBoundsException e)
{
}
rowCount ++;
colCount ++;
loopCount ++;
}
return 0;
}发布于 2012-02-17 07:09:01
虽然我还没有读过您的代码,但看起来您需要学习一些更基本的技术,比如循环和使用小辅助函数进行重构。我可以看出您对异常处理不感兴趣,这对于这种规模的程序目前来说还不错,但还有更多视觉上令人愉悦(和可读性更高)的解决方案,比如将连续的try-catch块合并为一个块,或者简单地声明函数可能会抛出。
至于你的问题,递归是答案。您不能一直检查邻居和邻居的邻居及其邻居等等。你需要想出一个重复的模式。Flood fill才是真正的答案,但您需要熟悉recursion,并学会识别它可能解决的问题。
发布于 2012-02-17 07:07:58
好吧,看过你的代码后,我认为最好是给你一些通用的指导方针,而不是试图解决这个特定的问题。
Java是一种为面向对象编程而设计的语言。您所做的更多的是一种过程化的方法,当然这也是可行的,但是由于您正在使用Java,所以我假设您希望使用对您有利的语言特性。
让我们看看我们可以在你的项目中找到什么样的“对象”。您已经有了一个电路板,即单元数组。您显示的代码将是这个板的一部分,您可以将其与与板无关的代码分开。
目前,您的电路板由表示该单元状态的整数组成。现在,让cell也成为一个对象不是很有趣吗?这样一来,电路板就会有一个单元数组,这些单元有一个状态。现在你可以说,这只是增加了你必须推理的级别的数量。在某种程度上,这也是正确的,然而,这些层次中的每一个都是一个明确定义的概念,你可以单独对其进行推理。让我们看一些示例代码:
class Cell {
private int state; //whatever your default is
public Cell(int state) {
this.state = state;
}现在我们可以添加一些方法来检查状态:
public boolean hasMine() {
return state == 1;
}
public boolean isFlagged() {
return state == 4;
}类似地,您可以添加方法来更改状态:
public void flag() {
state = 4;
}我只列出了几个方法,我想应该很清楚如何编写更多的方法。(另外,我现在将状态保持为一个整数。一旦您对面向对象编程有了更深入的了解,您可能会想看看Java Enumerations或State模式)
现在让我们看一下棋盘。您当前有一个名为findneighbours的方法,它返回形容词挖掘的数量。就我个人而言,我会把这个方法称为更清楚的东西,比如getAdjecentMineCount。但是,我希望还有一个getNeighbours方法,它返回一个单元格的所有形容词单元格。然后,您可以使用此getNeighbours方法轻松查找形容词挖掘的数量,如下所示:
public int getAdjecentMineCount(int row, int col) {
int count=0;
for (Cell c : getNeighbours(row, col)) //this iterates over the neighbours that are returned by the getNeighbours function
if (c.hasMine())
count++;
return count;
}现在,让我们来看一下如何揭示一个细胞。让我们不要让它变得困难,而是创建一个名为revealCell的方法:
public void revealCell(int row, int col) {
if (board[row][col].hasMine())
System.out.println("BOOM"); //whatever has to happen when you click on a bomb
//now we also want to reveil any non-diagonal neighbour that doesn't have a mine
for (Cell c : getNonDiagonalNeighbours(row, col))
if (!c.hasMine() && !c.isRevealed())
reveilCell(rowOf(c), columnOf(c));
}注意对同一方法的递归调用。这将导致细胞链暴露。
我故意在代码中留下了一些漏洞,比如查找邻居的方法。我希望我的解释将推动您以正确的方式,并希望您可以自己更多地了解该语言。如果您有进一步的问题,请随时与我联系。
(免责声明:我绝不会声称我在这里提供给您的解决方案是理想的解决方案。我所要做的就是引导你编写更干净、更面向对象的代码。)
发布于 2012-02-17 07:25:04
请原谅我重新实现了你的整个代码,但这比试图理解你的代码要快得多。
public class Minefield {
int mx, my;
/** whether a mine is present */
boolean[][] mined;
/** the number of mines in neighboring cells */
int[][] mines;
/** whether this cell is revealed */
boolean[][] revealed;
public Minefield() {
Random chaos = new Random();
mx = 10;
my = 10;
for (int x = 0; x < mx; x++) {
for (int y = 0; y < my; y++) {
mined[x][y] = chaos.nextFloat() < 0.2;
}
}
for (int x = 0; x < mx; x++) {
for (int y = 0; y < my; y++) {
mines[x][y] = 0;
for (int nx = max(x - 1, 0); nx < mx && nx <= x + 1; nx++) {
for (int ny = max(y - 1, 0); ny < my && ny <= y + 1; ny++) {
if (mined[nx][ny]) {
mines[x][y]++;
}
}
}
}
}
}
void stepOn(int x, int y) {
reveal(x, y);
if (mined[x][y]) {
throw new GameOverException();
}
}
void reveal(int x, int y) {
if (!revealed[x][y]) {
revealed[x][y] = true;
if (mines[x][y] == 0) {
for (int nx = max(x - 1, 0); nx < mx && nx <= x + 1; nx++) {
for (int ny = max(y - 1, 0); ny < my && ny <= y + 1; ny++) {
reveal(nx, ny);
}
}
}
}
}注意:我还没有测试过该代码,但我希望您能理解。
https://stackoverflow.com/questions/9320073
复制相似问题