Removing objects from SortedSet

716 views Asked by At

I've been looking at this for far too long, hopefully someone can help.

The general jist is;

  1. I have a SortedSet of player objects (sorted by Y position), each player contains a sortedset of 'Polygon' objects which in turn contain a list of three point objects, obviously forming a triangle.

  2. This polygon set is sorted by area of said polygon, smallest to largest.

  3. What I want to do is iterate through the set of players and;

I. Assign the point at index[1] (the 'peak' of the triangle) from the first object in the polygon SortedSet to another variable inside the player.

II. Once the point at index[1] has been assigned to a player, I need to iterate through every player and remove any instance of a polygon that contains the current point at ElementAt(1) so no subsequent players in the 'parent' iteration can be assigned a polygon that contains that Point.

It's probably important to note that the point at polygonPoints[1] is based on the enemy position so they're consistent across all players, this is why I'm trying to use it as my 'reference' point to remove any polygon objects that contain said point.

It's a convoluted explanation but hopefully you've been able to follow.

Right now I've got the first part working, but the second part is proving to be a serious pain - I've tried remove and removewhere (using criteria that should remove everything) and the set stubbornly stays the same length no matter what I do.

For reference here's the latest iteration of code that I'm wrangling with.

List<PointF> duplicates = new List<PointF>();

foreach (Player p in playerSet)
{
    //Assign lowest cost polygon to current player, then remove all polygons containing the point at p.triangleSet.ElementAt(0).polygonPoints[1] from every other player so it can't be assigned to any subsequent player.
    p.currentAttackingPoint = p.triangleSet.ElementAt(0).polygonPoints[1];

    //I use this method to keep track of which 'attacking points' have been assigned.
    add(p.currentAttackingPoint);

    //Then, in theory, I use this method to remove all polygons that contain any point in the duplicates list from every other player. Obviously this is proving to be the troublesome aspect.
    remove(duplicates);
}

...

private void add(PointF i)
{
    duplicates.Add(i);
}

private void remove(List<PointF> dupes)
{
foreach(PointF p in dupes)
{
    foreach (Player l in playerSet)
    {
        //Outputs 100
        textBox3.AppendText(l.triangleSet.Count.ToString() + "\r\n");

        l.triangleSet.RemoveWhere(e => e.polygonPoints[1] == p);
        //l.pressingTriangleSet.RemoveWhere(e => e.polygonPoints[1].X > 0);     --Doesn't work either, despite it being true of every point in the set.

        //Still 100
        textBox3.AppendText(l.triangleSet.Count.ToString() + "\r\n");
    }
}
}

Please bear in mind that the set of polygons inside each player, whilst the same length all have largely different content, they're based on the position of the player the position of the enemy and another arbitrary fact about the game state - so I can't just remove the first polygon from each player's set.

I'm thinking about converting each set to a list once they've been created because this is bizarre, it's got to be some order of operations issue that I'm overlooking.

Purely for my own sanity I knocked this out http://pastie.org/private/ikq5lhhacxxvfaoervauw and it works exactly as you'd expect it to.

EDIT - For anyone who finds this looking for a solution to a similar problem, don't waste your time using sortedsets to sort a collection of objects, you can use OrderBy to achieve the same thing with lists.

1

There are 1 answers

4
Eric On

This is a longshot but sometimes comparing floats and double is a bit tricky because of precision. For example a point 1.0 might be represented as 1.0000001 because of rounding errors. It is possible that your points are not compared correctly

Try something like

e.polygonPoints[1].X - p.X < 0.00001 
&& p.X - e.polygonPoints[1].X < 0.00001 
&& e.polygonPoints[1].Y - p.Y < 0.00001 
&& p.Y - e.polygonPoints[1].Y < 0.00001 

I would have assumed that PointF equality operator would take care of that but it may not