我有一个包含所有Piece对象的2D数组,每个对象都是Rook,Bishop,King等实例......
如何判断srcX,srcY到dstX,dstY的路径是否被其他路径阻挡?
我唯一能想到的就是涉及大量繁琐的代码= /
答案 0 :(得分:7)
你对“大量繁琐的代码”的评论是一种夸张的夸张。棋盘上的路径不超过八个方格,并且所有这些路径都可以跟随一个简单的算法 - 递增或递减行和/或列计数器。 (除了骑士,它只能移动到八个方格并且不能被阻挡。)我怀疑任何一块的代码需要超过二十行。
例如,这里是主教的代码:
// check move legality not taking into account blocking
boolean canMoveBishopTo(int srcx,int srcY,int destX,int destY) {
if (srcX<0 || srcX>7 ||srcY<0 || srcY>7 || destX<0 || destX>7 ||destY<0 || destY>7) {
throw new IllegalArgumentException();
}
if ((srcX==destX || srcY==destY) {
return false;
}
if (Math.abs(destX-srcX) == Math.abs(srcY-destY) {
return true;
}
return false;
}
boolean isBishopMoveBlocked(int srcx,int srcY,int destX,int destY) {
// assume we have already done the tests above
int dirX = destX>srcX ? 1 : -1;
int dirY = destY>srcY ? 1 : -1;
for (int i=1;i<Math.abs(destX-srcX)-1;++i) {
if (pieceOnSquare(srcX+i*dirX,srcY+i*dirY) {
return false;
}
}
return true;
}
答案 1 :(得分:4)
我们有一个起点和目的地点,并知道我们只需要看水平,垂直或对角线。
首先,计算方向向量。这是一个2D点,其值为
Point north = new Point(0,1);
Point northEast = new Point(1,1);
Point east = new Point(1,1);
// ...
Point northWest = new Point(-1,1);
这很简单:
Point start = getStart();
Point dest = getDest();
Point direction = new Point(Math.signum(dest.x-start.x),
Math.signum(dest.y-start.y));
(例如:start =(2,2),destination =(7,7) - &gt;(signum(7-2),signum(7-2))=(1,1))
现在只需通过方向点增加纸板位置,直到到达目的地并检查每个2D点,如果该地方包含一块。
这是一个快速草案(如果它不编译则将其作为伪代码;)
Point start = getStart();
Point dest = getDest();
if (start.equals(dest)) return false; // nothing in between by definition
Point direction = new Point(Math.signum(dest.x-start.x),
Math.signum(dest.y-start.y));
Point current = new Point(start.x+direction.x, start.y+direction.y);
while(!current.equals(dest)) {
if (isOccupied(board[current.x][current.y])) // test to be implemented
return true; // something in between
current.x = current.x + direction.x;
current.y = current.y + direction.y;
}
return false; // nothing in between
答案 2 :(得分:1)
需要满足两个条件:
dst
不能被a占用
一块相同的颜色src
和dst
答案 3 :(得分:0)
不是每次想要知道它而是计算它,可能更容易跟踪每件作品的所有可能性。
答案 4 :(得分:0)
我看看A *,它是最受欢迎的路径算法之一: http://en.wikipedia.org/wiki/A*_search_algorithm
它可能比您想要输入的代码更多,但它可能在其他地方使用的知识非常有用
答案 5 :(得分:0)
这完全取决于您选择的董事会代表。你选择的那个很容易开始,但你会很快遇到性能问题。所以是的,你需要编写一些繁琐的代码。它可以帮助您生成此代码,而不是手动编写。另一方面,您可能对其他表示感兴趣。例如,位板是最先进的,并且(正确实施)将提供巨大的加速。请注意,代码量可能仍然很大,当然要复杂得多。以下是Robert Hyatt(Crafty的作者)的介绍,您可能会感兴趣:boardrep。
祝你好运!答案 6 :(得分:0)
由于棋子都是直线移动而没有跳跃(除了骑士),所以编写一个函数来检查从src到dst的(直线)是否通过一个片段就足够了,并且每次都使用它除了骑士之外的部分(总是能够到达目的地)。
当然,对于所有作品,目的地广场应为空。
到达目的地实际上应该是一个合法的举动 - 如果有必要,也不应该太难检查。
主要功能只是获取使用的方向(通过dst-src
解释为类似比例的东西并简化为最简单的术语)并循环检查一块是否挡路。
答案 7 :(得分:0)
让2D数组代表棋盘,空格,棋子等等。
您需要检查8个方向。
现在你只需要知道如何增加/减少指数并测试空位的位置。
希望我没有放弃太多。
答案 8 :(得分:0)
这个问题很好地解决了数组解决方案(这可能是它被分配为数组练习的原因)。您似乎缺少的是,使用步骤的符号可以完成多个方向中的每个方向,因此在代码中您不需要明确地处理每个方向。在伪代码中:
steps_bishop = [[1,1], [1,-1], [-1, 1], [-1,-1]] # an array of each possible step direction (which are also arrays)
steps_rook = [[1,0], [-1,0], [0, 1], [0,-1]]
# everything else is agnostic to step direction:
current_position = get_current_position()
steps = steps_bishop # step like a bishop, for example
for step_direction in steps:
while still_on_board(current_position) and no_collision(current_position):
current_position += step_direction
答案 9 :(得分:-1)
您是否考虑将您的国际象棋棋盘表示为graph?然后,您可以简单地从A点到B点遍历图形,看看是否有任何“节点”。