如何在矩阵中按特定顺序移动?

时间:2015-04-03 22:55:33

标签: c# arrays matrix

所以我遇到了这个问题:我想从黑点转移到另一个像这样:

enter image description here

但每当我尝试这样做时,它会像这样移动:

enter image description here

您只能向一个方向移动:一次向北,向南,向东和向西移动。 我试着做这样的事情:

        int distance = game.Distance(myPirate.Loc,loc);
        List<Direction> allDirections = new List<Direction>() { Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST, Direction.NOTHING };
        Location destination;
        foreach (Direction dir in allDirections)
        {
            destination = game.Destination(myPirate, dir);
            int distance2 = game.Distance(destination, loc);
            if (distance2 < distance) return dir;
        }
        return Direction.NOTHING;

但每当我尝试这段代码时,我都会得到以下结果:

enter image description here

任何人都可以帮我弄清楚如何像第一张照片一样移动而不是第二张照片吗?您将获得矩阵中2个黑色方块的位置。 如果您还需要更多信息,请告诉我。

2 个答案:

答案 0 :(得分:1)

正如@ap和@AlexeiLevenkov在评论中已提到的那样,您可以使用任何线条绘制算法来解决您的任务。

将矩阵视为像素字段(屏幕)。您希望以最短的方式从起点移动到终点,这当然是一条直线(我相信您可以从几何课程中记住这一点)。因此,您必须在栅格像素字段上的两个点之间“绘制”一条直线。这正是那些线条绘制算法的重点。

让我们使用简单的DDA。

首先,您必须确定路径斜率:

double slope = (endPoint.Y - startPoint.Y) / (double)(endPoint.X - startPoint.X);

然后你应该看看斜率绝对值是小于还是大于1.这是根据算法。如果它小于或等于1,那么我们将在每个步骤中沿水平方向移动(因此我们用 dX = 1 “采样”。在另一种情况下,我们将在垂直方向上移动(“采样”, dY = 1 )。

我们必须准备“线”:我们根据斜率计算 dX dY 偏移量。对于 dX == 1 的情况,我们将在每次移动时向左或向右移动,此外,使用 dY 值计算下一个垂直“跳跃”。如果我们确定我们应该向上或向下移动,我们通常会另外这样做。但由于每次迭代只允许一次移动,我们需要跳过水平移动并改为垂直移动。

在下一个示例代码中,我将省略 dY == 1 的情况。你一定可以自己写。此外,这段代码并不是那么整洁,但为了简单起见,我就这么说了。你可以优化和重构它。

private double dX, dY;
private double currentX, currentY;

void PrepareMoving(Point startPoint, Point endPoint)
{
    double slope = (endPoint.Y - startPoint.Y) / (double)(endPoint.X - startPoint.X);
    if (Math.Abs(slope) <= 1.0)
    {
        this.dX = Math.Sign(endPoint.X - startPoint.X);
        this.dY = slope;
    }
    else
    {
        this.dY = Math.Sign(endPoint.Y - startPoint.Y);
        this.dX = slope;
    }

    this.currentX = startPoint.X;
    this.currentY = startPoint.Y;
}

Direction DoNextMove(Point target)
{
    // If we already have reached the destination...
    if (new Point((int)this.currentX, (int)this.currentY) == target)
    {
        return Direction.NOTHING;
    }

    // if the horizontal moving is "primary"
    if (Math.Abs(this.dX) == 1.0)
    {       
        double nextValue = this.currentY + this.dY;
        try
        {
            // we have to move up or down if we've got a "jump"
            if (Math.Round(nextValue) != Math.Round(this.currentY))
            {
                return this.dY > 0 ? Direction.SOUTH : Direction.NORTH;
            }
            // otherwise, just perform the "normal" left or right move
            else
            {
                this.currentX += this.dX;
                return this.dX > 0 ? Direction.EAST : Direction.WEST;
            }
        }
        finally
        {
            // ensure we set the current values for the next move
            this.currentY = nextValue;
        }
    }
    else
    {
        // You know what to do here: vertical moving is "primary"
    }       
}

答案 1 :(得分:0)

尝试在“(allDirections中的方向目录)”中使用Random for dir,这样它每次都会检查不同的方向顺序并以锯齿形方式进行..

因为它始终以相同的方向顺序检查北方&gt; south&gt; west&gt; east&gt;没有任何东西直线进行..