我有一个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数组中任意随机点的对角线的最简单方法是什么?此外,非常感谢有关如何简化我的代码的建议。
谢谢!
答案 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)角,我们使用这个逻辑:
拿这个并申请说,(长度,高度)角:
翻译成代码的所有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
来消除这些内容。当然,如果你这样做,那么结果有时会少于四次。