找到相对于任何位置的2D数组的对角线边缘 - Java

时间:2016-07-19 20:59:01

标签: java arrays matrix 2d

我有一个6x6数组:

        int[][] multi = new int[][]{
        {4, 2, 3, 2, 5, 1},
        {2, 5, 5, 4, 1, 1},
        {2, 4, 6, 7, 2, 4},
        {2, 1, 2, 3, 4, 3},
        {3, 5, 1, 4, 5, 2},
        {1, 2, 1, 4, 1, 2}
    };

如果我的起始位置是multi[2][3]。如何找到相对于该值的数组的对角线边缘?例如,在点multi[2][3]处,值为7.对角线应为点multi[0][1]multi[0][5]multi[4][5]multi[5][0]。这是我的代码目前所做的:

if (LocationValue == 7) {//find possible moves
            //There should be 4 potential moves

            ArrayList<Point> Moves = new ArrayList<Point>();
            Point DMove;

            for (int i = 0; i < multi.length; i++) {
                DMove = new Point(x + i, y + i);
                Moves.add(new Point(DMove));
            }
            for (int i = 0; i < multi.length; i++) {
                DMove = new Point(x - i, y + i);
                Moves.add(new Point(DMove));
            }
            for (int i = 0; i < multi.length; i++) {
                DMove = new Point(x - i, y - i);
                Moves.add(new Point(DMove));
            }
            for (int i = 0; i < multi.length; i++) {
                DMove = new Point(x + i, y - i);
                Moves.add(new Point(DMove));
            }

            ArrayList<Point> AlmostFinalMoves = FindPossibleMoves(Moves); //eliminate impossible moves
            ArrayList<Point> FinalMoves = FindSideMoves(AlmostFinalMoves, x, y); //Get bishop moves
            System.out.println("Possible Moves: " + FinalMoves);

          }//End of IF

然后,此方法消除了不可能的值:

    public static ArrayList<Point> FindPossibleMoves(ArrayList<Point> AllMoves) {

    ArrayList<Point> FinalMoves = new ArrayList<Point>();

    for (int i = 0; i < AllMoves.size(); i++) {

        if (AllMoves.get(i).getX() >= 0 && AllMoves.get(i).getX() <= 5 && AllMoves.get(i).getY() >= 0 && AllMoves.get(i).getY() <= 5) {
            FinalMoves.add(AllMoves.get(i));
        }
    }

    return FinalMoves;
}

最后,这种方法消除了阵列边缘上没有的所有移动。

    public static ArrayList<Point> FindSideMoves(ArrayList<Point> AllPossibleMoves, int xloc, int yloc) {

    ArrayList<Point> AlmostFinalSideMoves = new ArrayList<Point>();
    ArrayList<Point> FinalSideMoves = new ArrayList<Point>();

    for (int i = 0; i < AllPossibleMoves.size(); i++) {

        if (AllPossibleMoves.get(i).getX() == 0) {
            if (AllPossibleMoves.get(i).getY() == 0 || AllPossibleMoves.get(i).getY() == 1 || AllPossibleMoves.get(i).getY() == 2 || AllPossibleMoves.get(i).getY() == 3 || AllPossibleMoves.get(i).getY() == 4 || AllPossibleMoves.get(i).getY() == 5) {
                AlmostFinalSideMoves.add(AllPossibleMoves.get(i));
            }
        }
        if (AllPossibleMoves.get(i).getX() == 5) {
            if (AllPossibleMoves.get(i).getY() == 0 || AllPossibleMoves.get(i).getY() == 1 || AllPossibleMoves.get(i).getY() == 2 || AllPossibleMoves.get(i).getY() == 3 || AllPossibleMoves.get(i).getY() == 4 || AllPossibleMoves.get(i).getY() == 5) {
                AlmostFinalSideMoves.add(AllPossibleMoves.get(i));
            }
        }
        if (AllPossibleMoves.get(i).getX() == 1) {
            if (AllPossibleMoves.get(i).getY() == 0 || AllPossibleMoves.get(i).getY() == 5) {
                AlmostFinalSideMoves.add(AllPossibleMoves.get(i));
            }
        }
        if (AllPossibleMoves.get(i).getX() == 2) {
            if (AllPossibleMoves.get(i).getY() == 0 || AllPossibleMoves.get(i).getY() == 5) {
                AlmostFinalSideMoves.add(AllPossibleMoves.get(i));
            }
        }
        if (AllPossibleMoves.get(i).getX() == 3) {
            if (AllPossibleMoves.get(i).getY() == 0 || AllPossibleMoves.get(i).getY() == 5) {
                AlmostFinalSideMoves.add(AllPossibleMoves.get(i));
            }
        }
        if (AllPossibleMoves.get(i).getX() == 4) {
            if (AllPossibleMoves.get(i).getY() == 0 || AllPossibleMoves.get(i).getY() == 5) {
                AlmostFinalSideMoves.add(AllPossibleMoves.get(i));
            }
        }
    }

    for (int i = 0; i < AlmostFinalSideMoves.size(); i++) {//Check to see if any possible moves match the original location. If so, do not include in list
        if (AlmostFinalSideMoves.get(i).getX() == xloc && AlmostFinalSideMoves.get(i).getY() == yloc) {
            //Do Nothing!
        } else {
            FinalSideMoves.add(AlmostFinalSideMoves.get(i));
        }
    }

   return FinalSideMoves;
}

运行此程序会导致以下内容不正确。

Possible Moves: [java.awt.Point[x=0,y=3], java.awt.Point[x=0,y=5], java.awt.Point[x=2,y=5], java.awt.Point[x=4,y=5], java.awt.Point[x=5,y=3], java.awt.Point[x=5,y=0], java.awt.Point[x=2,y=0], java.awt.Point[x=0,y=1]]

找到方形2D数组中任意随机点的对角线的最简单方法是什么?此外,非常感谢有关如何简化我的代码的建议。

谢谢!

2 个答案:

答案 0 :(得分:2)

如果其中一个索引等于0,或者数组的长度/高度,则数字位于正方形的边缘上。假设数组已经是一个正方形(你可以自己检查):

int length = grid.length;
int height = grid[0].length;

假设你有原点的x和y坐标:

List<Point> findPossibleMoves(int x, int y) {
    int length = grid.length;
    int height = grid[0].length;
    int originalX = x;
    int originalY = y;
    //add (1, 1), (-1, 1), (-1, -1), (1, -1) to the original position until you reach an edge
}

但等等,我们真的需要一个循环吗?如果我们直接向x和y点添加一定值以在1步中到达边缘怎么办?我们怎么做?

以(2,3)为例(数组中的值= 7)。为了找到(0,0)角,我们使用这个逻辑:

  • x = 2接近于0而y更接近0所以我们得到(x - x,y - x)=(0,1)
  • 如果y比x更接近0,则适用:(x - y,y - y)=(x - y,0)

拿这个并申请说,(长度,高度)角:

  • (y = 3)更接近(height = 5)而不是(x = 2)到(length = 5)所以得到(x +(height-y),(y +(height-y))= (4,5)

翻译成代码的所有4个角落都是:

List<Point> findPossibleMoves(int x, int y) {
    List<Point> pointList = new ArrayList<Point>();
    int length = grid.length;
    int height = grid[0].length;

    pointList.add(new Point(x - Math.min(x, y), y - Math.min(x, y)));
    pointList.add(new Point(x + Math.min(length - x, y), y - Math.min(length - x, y)));
    pointList.add(new Point(x - Math.min(x, height - y), y + Math.min(x, height - y)));
    pointList.add(new Point(x + Math.min(length - x, height - y), y + Math.min(length - x, height - y)));

    return pointList;
}

可以清理到:

List<Point> findPossibleMoves(int x, int y) {
    List<Point> pointList = new ArrayList<Point>();
    int length = grid.length;
    int height = grid[0].length;

    int to00 = Math.min(x, y);
    int toL0 = Math.min(length - x, y);
    int to0H = Math.min(x, height - y);
    int toLH = Math.min(length - x, height - y);
    pointList.add(new Point(x - to00, y - to00));
    pointList.add(new Point(x + toL0, y - toL0));
    pointList.add(new Point(x - to0H, y + to0H));
    pointList.add(new Point(x + toLH, y + toLH));

    return pointList;
}

答案 1 :(得分:0)

我直接做得更多。只要我们认为multi是规则的,而不是衣衫褴褛的,我们甚至不需要事先知道它的尺寸是什么。它甚至不需要是方形的。

例如,这种方法比你的更简洁:

if (LocationValue == 7) {
    int maxRow = multi.length - 1;
    int maxColumn = multi[0].length - 1;
    int[][] directions = { { 1, 1 }, { 1, -1 }, { -1, 1}, { -1, -1 } };
    ArrayList<Point> finalMoves = new ArrayList<>();

    for (int[] direction : directions) {
        int x1 = x;
        int y1 = y;

        // Proceed in the current direction until we reach an edge
        while (true) {
            int x2 = x1 + direction[0];
            int y2 = y1 + direction[1];

            if ((x2 < 0) || (x2 > numColumns)
                    || (y2 < 0) || (y2 > numRows)) {
                // Moving in farther would take the piece off the board
                break;
            } else {
                x1 = x2;
                y1 = y2;
            }
        }

        finalMoves.add(new Point(x1, y1));
    }

    // ...
}

特别注意我们可以非常容易地知道边缘上的哪些点(如图所示)。如果您愿意,可以将给定条件包装在一个方法中,但它并不多。无论哪种方式,都没有特别需要创建我们知道不在边缘的Point,或者进行两轮过滤或任何其他过滤。

另请注意,我已通过引入directions数组来干掉您的代码。您执行以处理每个方向的操作是相同的,但对于两个轴的增量(+1或-1)。 direction的元素捕获了这些差异,消除了对重复代码的需求。

最后,请注意,如果初始位置在边缘上,则计算出的两个&#34;移动&#34;将这件作品保留在初始位置,如果初始位置在一个角落,那么其中三个动作将把它留在同一个地方。如果您愿意,可以通过在向x1添加移动之前测试y1和/或finalMoves来消除这些内容。当然,如果你这样做,那么结果有时会少于四次。