Java 被这段代码卡住了
我正在做的是创建一个命令行游戏,其中有一个3x3网格阵列,您可以通过键入上、下、左、右方向来移动1 例如: 0 0 0 0110 0 0 0 我已经这样做了,如果1位于数组的边缘,则不允许它移出读取的边界:导致索引外错误 我完全迷失了方向,因为每当我尝试向右移动时,我都会收到以下信息:Java 被这段代码卡住了,java,Java,我正在做的是创建一个命令行游戏,其中有一个3x3网格阵列,您可以通过键入上、下、左、右方向来移动1 例如: 0 0 0 0110 0 0 0 我已经这样做了,如果1位于数组的边缘,则不允许它移出读取的边界:导致索引外错误 我完全迷失了方向,因为每当我尝试向右移动时,我都会收到以下信息: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3 at Logic.setMove(Logic.java:87) at
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at Logic.setMove(Logic.java:87)
at Logic.getMove(Logic.java:10)
at GridGameMain.main(GridGameMain.java:13)
这是我的密码:
public class GridGameMain {
static int[][] board = new int[3][3];
public static void main(String[] args){
board[(int) (Math.random() * 2.5)][(int) (Math.random() * 2.5)] = 1;
for (int i =0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
System.out.print(" " + board[j][i]);
}
System.out.println("");
}
Logic l = new Logic();
l.getMove();
}
}
import java.util.Scanner;
public class Logic extends GridGameMain{
void getMove(){ //takes user input then calls setMove
String direction; //string to hold the direction
Scanner user_input = new Scanner(System.in);
direction = user_input.next();
Logic l = new Logic();
l.setMove(direction);
}
void setMove(String direction){ //called when user presses enter upon typing a move
Logic l = new Logic();
if(direction.equals("up")){
if(board[0][0] == 1 || board[1][0] == 1 || board[2][0] == 1 ){
System.out.println("Invalid move!");
l.getMove();
}else{
for(int a = 0; a < 3; a++){
for(int b = 0; b < 3; b++){
if(board[a][b] == 1){
board[a][b-1] = 1;
board[a][b] = 0;
break;
}
}
}
l.printBoard();
System.out.println("you moved up");
l.getMove();
}
}
if(direction.equals("down")){
if(board[0][2] == 1 || board[1][2] == 1 || board[2][2] == 1 ){
System.out.println("Invalid move!");
l.getMove();
}else{
for(int a = 0; a < 3; a++){
for(int b = 0; b < 3; b++){
if(board[a][b] == 1){
board[a][b+1] = 1;
board[a][b] = 0;
break;
}
}
}
l.printBoard();
System.out.println("you moved down");
l.getMove();
}
}
if(direction.equals("left")){
if(board[0][0] == 1 || board[0][1] == 1 || board[0][2] == 1 ){
System.out.println("Invalid move!");
l.getMove();
}else{
for(int a = 0; a < 3; a++){
for(int b = 0; b < 3; b++){
if(board[a][b] == 1){
board[a-1][b] = 1;
board[a][b] = 0;
break;
}
}
}
l.printBoard();
System.out.println("you moved left");
l.getMove();
}
}
if(direction.equals("right")){
if(board[2][0] == 1 || board[2][1] == 1 || board[2][2] == 1 ){
System.out.println("Invalid move!");
l.getMove();
}else{
for(int a = 0; a < 3; a++){
for(int b = 0; b < 3; b++){
if(board[a][b] == 1){
board[a+1][b] = 1;
board[a][b] = 0;
break;
}
}
}
l.printBoard();
System.out.println("you moved right");
l.getMove();
}
}
}
void printBoard(){
for (int i =0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
System.out.print(" " + board[j][i]);
}
System.out.println("");
}
}
}
我只是不知道为什么我不能向右移动,当我可以向上、向下和向左移动都很好的时候。请告诉我我没有疯 向右移动时:
for(int a = 0; a < 3; a++){
for(int b = 0; b < 3; b++){
if(board[a][b] == 1){
board[a+1][b] = 1; // what if a is 2??
board[a][b] = 0;
break;
}
}
当a为2时,访问板[a+1][b]即访问板[3][b]。在一个3*3的板上,这是超越界限的
编辑:问题是因为在移动1后,继续执行外部循环,但没有初始边界检查。因此,在将1从中心柱移动到右侧柱后,再次尝试移动它。由于“为什么要循环”,这只会在向右移动时发生
有两种简单的解决方案:
使用一些标志,以确保您也打破了外部循环,或者更好-
根据实际要检查的内容更改fors的边界。如果不移动列2上的1,则可以在0和1之间创建一个循环。没有理由上升到2,如果你永远不会让它从那一点移动。所有其他移动也一样-将适当的边界从<3更改为<2。
右转:
for(int a = 0; a < 3; a++){
for(int b = 0; b < 3; b++){
if(board[a][b] == 1){
board[a+1][b] = 1; // what if a is 2??
board[a][b] = 0;
break;
}
}
当a为2时,访问板[a+1][b]即访问板[3][b]。在一个3*3的板上,这是超越界限的
编辑:问题是因为在移动1后,继续执行外部循环,但没有初始边界检查。因此,在将1从中心柱移动到右侧柱后,再次尝试移动它。由于“为什么要循环”,这只会在向右移动时发生
有两种简单的解决方案:
使用一些标志,以确保您也打破了外部循环,或者更好-
根据实际要检查的内容更改fors的边界。如果不移动列2上的1,则可以在0和1之间创建一个循环。没有理由上升到2,如果你永远不会让它从那一点移动。所有其他移动也一样-将适当的边界从<3更改为<2。
我认为问题在于,你检查以确保1不在最右边,然后你开始把东西移到右边。这意味着,如果1位于列0上,它将移动到列2,然后在下一次也是最后一次迭代中,它将移动到列3 还有,你确定你下楼时不会发生这种情况吗? 向下时不会发生这种情况,因为正如@Keppil所说,您打破了行相关循环,而向右时,您打破了列1,这不是您想要的
此外,您还可以使用标记打破任何循环 我想问题是,你检查一下,确保1不在最右边,然后你就开始把东西移对了。这意味着,如果1位于列0上,它将移动到列2,然后在下一次也是最后一次迭代中,它将移动到列3 还有,你确定你下楼时不会发生这种情况吗? 向下时不会发生这种情况,因为正如@Keppil所说,您打破了行相关循环,而向右时,您打破了列1,这不是您想要的
此外,您还可以使用标记打破任何循环 问题在于,您将1从左向右移动,因此,由于您将第一个打断为,因此不会打断第二个,因此它将继续移动1,直到将其置于数组ArrayIndexOutOfBoundsException之外 解决这个问题的一个例子是:
boolean found = false;
for(int a = 0; a < 3; a++){
for(int b = 0; b < 3; b++){
if(board[a][b] == 1){
board[a+1][b] = 1;
board[a][b] = 0;
found = true;
break;
}
if(found){
break;
}
}
}
问题是,您正在将1从左向右移动,因此,由于您将第一个打断为,因此不会打断第二个,因此它将继续移动1,直到将其置于数组ArrayIndexOutOfBoundsException之外 解决这个问题的一个例子是:
boolean found = false;
for(int a = 0; a < 3; a++){
for(int b = 0; b < 3; b++){
if(board[a][b] == 1){
board[a+1][b] = 1;
board[a][b] = 0;
found = true;
break;
}
if(found){
break;
}
}
}
休息;在for循环内部,似乎只中断内部for循环。在破坏forint b=0后;b<3;b++{..},外部循环没有理由停止
循环在[1][1]处找到1并将其向右移动。然后它打破了内部循环。尽管如此,它还是调用a=2的内部循环,其中现在是1。他又试着换衣服。。并且异常失败。中断;在for循环内部,似乎只中断内部for循环。在破坏forint b=0后;b<3;b++{..},外部循环没有理由停止
循环在[1][1]处找到1并将其向右移动。然后它打破了内部循环。尽管如此,它还是调用a=2的内部循环,其中现在是1。他又试着换衣服。。并且异常地失败。我认为当你向右移动时,应该会出现错误。原因是当你向右移动一个时,你会断开,然后增加
但是你没有检查它是否再次出界。一旦“b”循环完成,然后递增“a”,则它将注册为值为1,并再次向右移动。这会一直持续到它出界为止。纠正代码的一个简单方法是反转循环,使外循环递增“b”,内循环递增“a”。我认为当你向右移动时,应该会出现错误。原因是当你向右移动一个时,你打破了,然后增加了一个,但是你没有检查它是否再次超出了界限。一旦“b”循环完成,然后递增“a”,则它将注册为值为1,并再次向右移动。这会一直持续到它出界为止。纠正代码的一个简单方法是反转循环,使外循环递增“b”,内循环递增“a”。如果您查看稍高于for语句,您可以看到我有一个If语句检查,以查看右边缘上的任何内容是否等于1。我没有任何其他方向的问题。是的,这很有效,谢谢!我完全忽略了那一部分=/若你们稍微看一下for语句,你们可以看到我有一个If语句检查,看看右边的任何东西是否等于1。我没有任何其他方向的问题。是的,这很有效,谢谢!我完全忽略了那一部分=/顺便问一下,为什么逻辑要扩展GridGameMain?我会因为这么说而大吃一惊,但这是我刚刚想到的一件非常快的事情,我扩展了它以访问板数组值。除了你的例外,你每次递归调用setMove都会创建一个新的逻辑对象。在类中使用this.getMove和this.setMove时,您应该只创建一个逻辑对象。为什么您仍然要创建新的逻辑实例,而不是调用this.getMove;您正在获得特定问题的答案。现在,附带一个话题,仅仅作为一个建议:如果你设计这个,这样你就可以存储1的位置,并在需要的时候简单地画一块板,你可能会有一个更轻松的时间。在处理更大的电路板时,它也会更有效。顺便问一下,为什么逻辑要扩展GridGameMain?我会因为这么说而感到厌烦,但这是我刚刚想到的一件非常快的事情,我扩展了它以访问电路板数组值。除了你的例外,您正在使用setMove的每次递归调用创建一个新的逻辑对象。在类中使用this.getMove和this.setMove时,您应该只创建一个逻辑对象。为什么您仍然要创建新的逻辑实例,而不是调用this.getMove;您正在获得特定问题的答案。现在,附带一个话题,仅仅作为一个建议:如果你设计这个,这样你就可以存储1的位置,并在需要的时候简单地画一块板,你可能会有一个更轻松的时间。在处理较大的电路板时,它也会更有效。OP在内部循环上执行中断,因此这只能在外部循环变量递增时发生,例如向右。@Keppil啊,是的,你是对的。所以,这只会发生在正确的情况下,因为您碰巧选择了先循环列,然后再循环Rowsah Miquel,非常感谢这个链接。我刚刚完成了Head First Java,从未遇到过标记系统,因此这将派上用场!:D@EnviousNoob我已经用Java编程多年了,几个月前我才发现这个链接;OP在内部循环上执行一个中断,因此只有当外部循环变量递增时才会发生这种情况,例如向右运行。@Keppil啊,是的,你是对的。所以,这只会发生在正确的情况下,因为您碰巧选择了先循环列,然后再循环Rowsah Miquel,非常感谢这个链接。我刚刚完成了Head First Java,从未遇到过标记系统,因此这将派上用场!:D@EnviousNoob我已经用Java编程多年了,几个月前我才发现这个链接;这个修好了,谢谢!如此少的一点代码会有很大的帮助!这个修好了,谢谢!如此少的一点代码会有很大的帮助!