方法不会经过二维数组。

huangapple go评论72阅读模式
英文:

Method doesn't go through 2d array

问题

public static boolean MagicBoard_recursive(int[][] board, int size, int startRow, int startCol) {
    boolean solvable = true;
    int number = board[startRow][startCol];
    
    int[] moves = {startRow + number, startRow - number, startCol + number, startCol - number}; // This array contains all the possible moves we can do
    
    for (int i = 0; i < 4; i++) {
        // If we reached the position containing the integer 0
        if (board[startRow][startCol] == 0) {
            solvable = true;
            break;
        }
        if (startRow + number > size && startRow - number < 0 && startCol + number > size && startCol - number < 0) {
            solvable = false;
            break;
        }
        solvable = true;
        // If we try moving south
        if (i == 0) {
            // If we move to this position, will we be able to continue, if not, then we try another move
            if (startRow + number > size) {
                solvable = false;
                continue;
            } else {
                while (solvable) {
                    startRow += number;
                    System.out.print("Move south " + number + ", ");
                    MagicBoard_recursive(board, size, startRow, startCol);
                }
            }
        }
        
        // If try moving north
        else if (i == 1) {
            // If we move to this position, will we be able to continue. If not, then we try another move
            if (startRow - number < 0) {
                solvable = false;
                continue;
            } else {
                while (solvable) {
                    startRow -= number;
                    System.out.print("Move south " + number + ", ");
                    MagicBoard_recursive(board, size, startRow, startCol);
                }
            }
        }
        
        // If try moving east
        else if (i == 2) {
            if (startCol + number > size) {
                solvable = false;
                continue;
            } else {
                while (solvable) {
                    startCol += number;
                    System.out.print("Move east " + number + ", ");
                    MagicBoard_recursive(board, size, startRow, startCol);
                }
            }
        }
        
        // If try moving west
        else if (i == 3) {
            if (startCol - number < 0) {
                solvable = false;
                break;
            } else {
                while (solvable) {
                    startCol -= number;
                    System.out.print("Move west " + number + ", ");
                    MagicBoard_recursive(board, size, startRow, startCol);
                }
            }
        }
    }
    return solvable;
}
英文:

<br/>
I am doing a method that goes through a 2d array like a maze and the goal is to reach the position containing the integer 0. I am able to document the path, but it won't move, it stays at the initial position. <br/>
Here is an example of what I mean by doesn't move:

Please input the size of the board (between 5 and 20):
5
Please choose a starting index from the 4 options below:
Press 1 for &quot;top-left&quot;
Press 2 for &quot;top-right&quot;
Press 3 for &quot;bottom-left&quot;
Press 4 for &quot;bottom-rigth&quot;
Enter your choice:
1
2	1	1	1	4	
2	3	4	1	3	
1	1	1	2	4	
3	0	3	3	2	
3	2	3	4	2	
Move south 2, Move north 2, Move east 2, Move west 2, 

Can someone help me please? <br/>
Here is my method so far:

public static boolean MagicBoard_recursive(int[][] board, int size, int startRow, int startCol) {
boolean solvable = true;
int number = board[startRow][startCol];
int[] moves = {startRow+number, startRow-number, startCol+number, startCol-number}; // This array contains all the possible moves we can do
for(int i = 0; i &lt; 4; i++) {
// If we reached the position containing the integer 0
if(board[startRow][startCol] == 0) {
solvable = true;
break;
}
if(startRow+number &gt; size &amp;&amp; startRow-number &lt; 0 &amp;&amp; startCol+number &gt; size &amp;&amp; startCol-number&lt;0) {
solvable = false;
break;
}
solvable = true;
// If we try moving south
if(i == 0) {
//int destinationNumber = board[startRow+number][startCol];
// If we move to this position, will we be able to continue, if not, then we try another move
if(startRow+number &gt; size) {
solvable = false;
continue;
}
else {
while(solvable) {
startRow +=number;
System.out.print(&quot;Move south &quot; + number + &quot;, &quot;);
MagicBoard_recursive(board, size, startRow, startCol);
}
}
}
// If try moving north
else if(i == 1) {
// If we move to this position, will we be able to continue. If not, then we try another move
if(startRow-number &lt; 0) {
solvable = false;
continue;
}
else {
while(solvable) {
startRow -=number;
System.out.print(&quot;Move south &quot; + number + &quot;, &quot;);
MagicBoard_recursive(board, size, startRow, startCol);
}
}
}
// If try moving east
else if(i == 2) {
if(startCol+number &gt; size) {
solvable = false;
continue;
}
else {
while(solvable) {
startCol += number;
System.out.print(&quot;Move east &quot; + number + &quot;, &quot;);
MagicBoard_recursive(board, size, startRow, startCol);
}
}
}
// If try moving west
else if(i == 3) {
if(startCol-number &lt; 0) {
solvable = false;
break;
}
else {
while(solvable) {
startCol -=number;
System.out.print(&quot;Move west &quot; + number + &quot;, &quot;);
MagicBoard_recursive(board, size, startRow, startCol);
}
}
}
}
return solvable;
}

Here is a picture that shows an example of the movement that the program would do to solve a board:

方法不会经过二维数组。
方法不会经过二维数组。

答案1

得分: 1

我认为你所采取的方法比必要的困难。

考虑使用类似于 Tile[][] 的东西,而不是表示棋盘的 int[][] 数组,其中 Tile 是一个包含以下属性的类。

public class Tile {
    boolean visited;
    int value; //也许使用 short 就足够了?
}

visited 属性的目的是确保你不会重复测试已经访问过的可到达的方块,就像广度优先搜索或深度优先搜索一样。

然后你可以有一个使用队列的类。虽然我已经有一段时间没有使用 Java 了,但对于这种情况,ArrayDeque 似乎是一个合适的选择(因为它可以调整大小)。在包含你的方法的类中,你可以将这个作为成员添加进来。

ArrayDeque<TileCoordinate> tilesToVisit = new ArrayDeque<>();

TileCoordinate 对象只是一个包含你的对象坐标的类。如果你愿意,你也可以直接将坐标放入 Tile 中,但我更喜欢将它们分开。

public class TileCoordinate {
    public int x;
    public int y;

    public TileCoordinate(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

然后这里是如何简化你的问题。当用户首次选择起始角落时,你将坐标插入队列中,而不是直接处理它。随后,你可以创建一个循环,访问队列中的任何坐标。

//从用户那里获取关于起始角落的输入,然后
tilesToVisit.add(new TileCoordinate(x, y)); //将角落坐标插入队列

while (!tilesToVisit.isEmpty() && solvable == false) {
    TileCoordinate tileToVisit = tilesToVisit.removeFirst();
        
    Visit(tileToVisit); //这是你的业务逻辑发生的地方
}

//如果在将 solvable 设置为 true 之前完成循环,这意味着它不可解

然后在你的 process 方法中,你会想要应用你的移动逻辑,以确定在队列中还有什么其他地方要访问。

public static void Visit(TileCoordinate coord) {
    Tile tile = board[coord.x][coord.y];
    tile.visited = true; //确保你首先做这个,这样你不会在以后再次处理它!
    
    if (tile.value == 0) {
        //将 solvable 标记为 true,这将是一个类状态变量
    }
    
    //对于从此块可到达且 visited = false 的每个块,将 'unvisitedReachableTileCoordinate' 添加到你的队列中
    tilesToVisit.add(unvisitedReachableTileCoordinate);
}

很抱歉,我已经有一段时间没有编写 Java 代码了,而且我的 NetBeans 设置混乱了。但是,我在 Oracle 文档中查找了许多这些函数,所以它应该基本上可以工作。这应该能给你这种方法的一般想法。

英文:

I think the approach you are taking is more difficult than it needs to be.

Consider instead of a int[][] array representing the board use something like Tile[][] where Tile is a class containing the following properties.

public class Tile {
boolean visited;
int value; //Maybe short will suffice instead?
}

The point of the visited property is to ensure you don't repeatedly test reachable tiles that you already visited before, as in a breadth-first or depth-first search.

Then you might have a class that makes use of a Queue. It's been a while for me and Java but a candidate seems like ArrayDeque for this situation (due to it's resizability). In the class containing your method you would add this as a member.

ArrayDeque&lt;TileCoordinate&gt; tilesToVisit = new ArrayDeque&lt;&gt;();

The TileCoordinate object is simply a class containing the coordinates for your object. You can instead put the coordinate directly into Tile if you wish to but I prefer to keep them separate.

public class TileCoordinate
{
public int x;
public int y;
public TileCoordinate(int x, int y) {
this.x = x;
this.y = y;
}
}

Then here's how this can help simplify your problem. When the user first chooses the starting corner you instead insert the coordinate into your queue rather than processing it directly. Following that you can create a loop which visits any coordinate that is in the queue.

//Get input regarding starting corner from user then,
tilesToVisit.add(new TileCoordinate(x, y)); //Insert coordinate corner into queue
while (!tilesToVisit.isEmpty &amp;&amp; solvable == false) {
TileCoordinate tileToVisit = tilesToVisit.removeFirst();
Visit(tileToVisit); //This is where your business logic happens
}
//If loop is completed before solvable is set to true, this means it&#39;s not solvable

Then in your process method you would want to apply your movement logic to determine what else to visit in your queue.

public static void Visit(TileCoordinate coord) {
Tile tile = board[coord.x, coord.y];
tile.visited = true; //Make sure you do this first so you don&#39;t process this again later!
if (tile.value == 0) {
//mark solvable to true, which would be a class state variable
}
//Foreach tile that is reachable from this tile where visited = false, add into your queue &#39;unvisitedReachableTileCoordinate&#39;
tilesToVisit.Add(unvisitedReachableTileCoordinate);
}

I apologize I haven't coded Java in a while and my netbeans setup is messed up. However I did lookup many of these functions in oracle documentation so it should generally work. This should give you the general idea of this approach.

huangapple
  • 本文由 发表于 2020年10月25日 06:00:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/64518413.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定