0

Scenario image

I am recreating a edge-link system from the game "Rimworld".

The purple squares are individual squares that need to form "links", in the direction the arrows are drawn in, with that exact length.

Currently, I don't know how to do this better than by placing all of those squares in a dictionary where I mark a square's position and its direction (which can be UP or RIGHT), like this:

Dictionary<Vector3Int, bool> linkSquares;

I want to sort this dictionary so that the KV pairs that come first are the ones where the Vector3Int.x is lowest and then where the Vector3Int.y is lowest.

That way, I could always start at those squares (marked with numbers 1-4 on the picture) and go in the appropriate arrow direction, removing those squares as I go, which would only leave other starting squares.

I've read that dictionaries can't be sorted, but I don't know how I would use a SortedDictionary for this case. This whole system seems overly dirty but I don't know how else I would achieve my goal here, so any design change suggestions are highly appreciated.

  • the first key is vectorx and second key ,when vectorx are equals, is vectory? – Frenchy Jan 26 '21 at 10:49
  • Yes, I basically always want the bottom-left-most Vector3Int's to come first, so that I can start from them and go UP or RIGHT to form these links, as drawn by the arrows. – franticabyss Jan 26 '21 at 10:51

2 Answers2

3

you could use OrderBy for the first key and ThenBy for the second key (Linq) and put the result in new dictionary (sorted):

        var dictsorted= linkSquares.OrderBy(k => k.Key.x).ThenBy(k => k.Key.y).ToDictionary(k => k.Key, k=> k.Value);
Frenchy
  • 9,646
  • 2
  • 9
  • 27
  • This does _not_ guarantee that the dictionary is sorted in the order the OP expects. See my comments at https://stackoverflow.com/a/50837837/34092 . – mjwills Feb 03 '21 at 12:31
  • i understand, but i have never had problem on this way to do. maybe the problem exists on big dictionary... – Frenchy Feb 03 '21 at 15:10
  • Read my comments on the other thread. It works today - but it is explicitly not _guaranteed_ to work. `For purposes of enumeration, each item in the dictionary is treated as a KeyValuePair structure representing a value and its key. The order in which the items are returned is undefined.` `undefined` doesn't mean "it won't work" - so saying it isn't a problem isn't an argument. `undefined` (in this context) means "don't rely on it" - and your solution here **specifically relies on it**. – mjwills Feb 03 '21 at 22:15
2

Try to define a custom class which includes the vector3 and bool together and the make list of objects from that class. Then you can sort the class in any you want.

If you only need the bool for filtering then you can just sort the dictionary into a list. An example of sorting dictionary into list is as below:

List<Vector3Int> productList = myDictionary.OrderBy(kp => kp.key.x).ThenBy(kp => kp.key.y)
                                      .ToList();

Check this, and this for more sample codes.

Majid khalili
  • 462
  • 1
  • 4
  • 18