C#Circle寻路

时间:2012-11-14 21:24:44

标签: c# path-finding

昨天我在C#代码中发现了一个奇怪的行为。 我的设置是(不完全,但可以比较)以下内容:

用户看到一个网格的复选框,其中我在coords 0,0的中间指定了复选框。

我写了一个结构,以便更容易地比较两个坐标:

public struct Coord
{
  public int x, y;

  public static bool operator == (Coord coord1, Coord coord2)
  {
    return coord1.x == coord2.x && coord1.y == coord2.y;
  }

  public static bool operator != (Coord coord1, Coord coord2)
  {
    return coord1.x != coord2.x || coord1.y != coord2.y;
  }

  public override int GetHashCode()
  {
    return this.x.GetHashCode() ^ this.y.GetHashCode();
  }

  public override bool  Equals(object obj)
  {
    if (!(obj is Coord))
      return false;

    Coord coord = (Coord)obj;

    if (coord.x == this.x && coord.y == this.y)
      return true;
    return false;
  }
}

对于一个复选框,我使用一个名为Position的类,它继承自标准的WinForms复选框:

public class Position : CheckBox
{
  public Coord coord;
  public List<Position> nearPositions = new List<Position>();

  public Position(int x, int y)
  {
    this.coord.x = x;
    this.coord.y = y;
  }

  protected override void OnClick(EventArgs e)
  {
    if (this.Checked)
      return;

    base.OnClick(e);

    this.checkConnections();
  }

  private void checkConnections()
  {
    foreach (Position position in this.nearPositions)
    {
      Route route = new Route(this, position);
    }
  }
}

如您所见,用户只能点击每个复选框一次 列表nearPositions仅包含此附近的点击复选框 现在在checkConnections()方法中我试图找出所有(或仅一些)点击的复选框可以连接到一个圆圈。 因此,我为每个可能的路径创建了我的类Route的新对象。

public class Route
{
  private Position startPosition;
  private List<Position> nodes = new List<Position>();

  public Route(Position startPosition, Position nextPosition)
  {
    this.startPosition = startPosition;
    this.nodes.Add(nextPosition);
    this.findConnection();
  }

  public Route(Route route, Position nextPosition)
  {
    this.startPosition = route.startPosition;
    this.nodes = route.nodes;
    this.Add(nextPosition);
    this.findConnection();
  }

  private void findConnection()
  {
    if (this.nodes.Count > 2 && this.nodes[this.nodes.Count - 1].nearPositions.Contains(this.startPosition))
    {
      //HERE THE ROUTE IS A CIRCLE
      return;
    }
    List<Position> nextPositions = this.nodes[this.nodes.Count - 1].nearPositions.FindAll(p => !p.Equals(this.startPosition) && !this.nodes.Contains(p));
    foreach (Position position in nextPositions)
    {
      if (this.nodes[this.nodes.Count - 1].nearPositions.FindAll(p => !p.Equals(this.startPosition) && !this.nodes.Contains(p)).Contains(position)) //TODO strange problem here...bad workaround need to fix
      {
        Route route = new Route(this, position);
      }
    }
  }
}

请记住,我为每个可能性创建了一个Route对象。因此,如果圆圈包含许多复选框,则同时存在许多Route对象。也许重现我的问题很重要 Route始终具有相同的startPosition。它是用户点击的位置 在List节点中,我保存了构建cricle的步骤。

现在我得到的是findConnection()方法内部的List nextPosition有时包含在this.nodes [this.nodes.Count - 1] .nearPositions列表中甚至不存在的位置。这就是我在foreach循环中添加额外条件的原因。

我的想法,它可能是.FindAll()方法的一个错误,或同时出现多个eoutes的问题。

所以我的问题:
 你能重现一下我的问题吗?  它来自哪里?
 3.我该如何解决?

感谢您的回复!

2 个答案:

答案 0 :(得分:1)

您应该尝试查明问题并发布更短的代码,以显示不适合您的内容。阅读所有细节并找出算法有点费时,大部分细节都不相关。

那就是说,你所看到的一件可疑的事情就是你定义Coord结构的方式。你赋予它一个相等的运算符覆盖,它正确地比较了成员,但在你的Equals覆盖中你不比较成员。

如果您的问题是FindAll无法正常运行,并且您使用调试器验证了列表内容是否正确,则此Equal覆盖可能是问题的原因。< / p>

您还应该更改GetHashCode覆盖以合并成员的值。

答案 1 :(得分:0)

我找到了解决方案 问题出在

public Route(Route route, Position nextPosition)
{
  this.startPosition = route.startPosition;
  this.nodes = route.nodes;
  this.Add(nextPosition);
  this.findConnection();
}

新路由仅获取对前一路由节点的引用,但它应具有自己的节点列表 所以我把它改成了

public Route(Route route, Position nextPosition)
{
  this.startPosition = route.startPosition;
  this.nodes.AddRange(route.nodes);
  this.Add(nextPosition);
  this.findConnection();
}
我应该早点看到。对不起!
但无论如何,谢谢你的帮助!