我正在做的是创建一个命令行“游戏”,其中有一个3x3网格(数组),您可以通过键入方向(向上,向下,向左,向右)移动“1”。
例如:
0 0 0
0 1 0
0 0 0
如果1位于数组的边缘,则不允许它移出边界(读取:导致索引错误)。
当我试图向右移动时,我完全迷失了,我收到了以下内容:
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("");
}
}
}
我只是不确定为什么当我可以向上,向下移动并且离开时,我无法向右移动。请告诉我,我不是疯了!
答案 0 :(得分: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从中间列移动到右侧之后,您尝试再次移动它。由于您循环的原因,这只会在正确的移动中发生。
有两种简单的解决方案:
for
的界限。如果您不打算移动第2列上的1
,则可以在0和1之间循环a
。没有理由可以达到2,如果您永远不会让它从那一点开始。所有其他动作也是如此 - 将适当的界限从< 3
更改为< 2
。答案 1 :(得分:2)
我认为麻烦的是,你检查确保1不在最右边,而然后你开始正确地改变事情。这意味着,如果您的1位于第0列,它将移至第2列,然后在下一次和最后一次迭代时,它将移至第3列。
另外,你确定下去时不会发生这种情况吗?
这种情况不会发生,因为正如@Keppil所说,你打破了“行”(相关)循环,而当你走向正确时,你会突破第一列,这不是你想要的。
此外,您可以使用标签来突破您想要的任何循环。 Here's how
答案 2 :(得分:2)
问题是你是从左向右移动“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;
}
}
}
答案 3 :(得分:1)
for-loops中的break;
似乎只会中断内部for循环。在打破for(int b = 0; b < 3; b++){ .. }
之后,外循环没有理由停止。
你的循环在[1] [1]处找到1
并将其向右移动。然后它打破了内循环。然而,它调用a=2
的内循环,现在你的1
。他试图再次转移..并且例外地失败。
答案 4 :(得分:0)
我相信当你走向右边时,你应该会遇到错误。原因是因为当你向右移动一个时,你会中断,然后你增加一个,但你不会再检查它是否超出界限。一旦'b'循环结束然后递增'a',它就会将其注册为值为1并再次向右移动。这一直持续到它超出范围。纠正代码的一种简单方法是反转循环,使外循环递增'b',内循环递增'a'。