Question about using a Dictionary that includes another Dictionary

Hey!
I’m currently creating a small tabletop prototype. I’m trying to set up ground pieces on the board and setting them in some kind of data container. It currently has X-amount of (grey) main planes that are setup in order on rows and each plane is covered by (black) side planes. There are special corridors with functionality that are different colors. I got base codes for instantiating stuff on pools and then activating and setting their positions accordingly depending on player settings

9851064--1418268--Sieppaa.PNG

When I create a new game I want to store each side planes row (int 0,1,2,3…), left/right side (bool isRight) and if is occupied (bool occupied). So later I can check if that spot has a corridor, and forexample I can set the special corridor Zpos ±10 depending on side so that it doesnt overlap with the black corridor. I’m having trouble figuring out the best approach for this. What I’m currently testing is dictionary on this format:

 static Dictionary<int, Dictionary<bool, bool>> corridor = new Dictionary<int, Dictionary<bool, bool>>();

    public static void AssignCorridor(int row, bool isRight)
    {
         //(Check if spot is unoccupied)
         //Assign/Add to corridor int(row) and side (isRight true or false) as occupied (true)
    }
    public static bool CheckRow(int row, bool isRight)
    {
        //Check corridor at int(row) and side (isRight true or false) and return if is occupied(true/false)
    }
    public static void RemoveCorridor(int row, bool isRight)
    {
         //(Check if spot is occupied)
         //Remove corridor at int(row) and side (isRight true or false) and set as unoccupied (false)
    }

After googling and testing I can’t seem to figure out how to use this kind of dictionary within dictionary. I’ve been trying some workaround with Vector3[ ] arrays or adding all Corridor scripts to List/array and checking every one for the rows and side bools but I find those pretty unintuitive.

Question:

How would I use this kind of a dictionary and could I get some examples for each function? (assign, check and remove)

It’s also very much possible that my approach is a disaster, so If anyone has any better ways of doing this and preferably with examples I’m all ears!

It feels like you might need some kind of layered approach to your data.

For instance, the grid of planes might be just a 2D array of some kind that defines what type or color each one is.

Always better to go with some opaque logical thing like “grass” instead of “green,” so you can change the presentation later, such as if you decide you want purple grass. :slight_smile:

Adjacent to that you would have corridors, described perhaps in terms of the coordinate space of the planes.

Like if you’re talking the Chutes and Ladders game, it would be a grid of 10x10 of cells, along with a list of connections that referred to these cells. The connections would be either ladders (up) or chutes/snakes (down).

But wrapping your stuff up in a clear API (like you’re doing above) is definitely the way to go, and it also lets you think about “what do I want to do against this data,” such as ask “can I go from here to there?” or “what is the path from point A to point B, perhaps passing through point C.”

1 Like

The inner dictionary can only have two keys: true and false, each of which can have a value of either true or false. That doesn’t seem to make a whole lot of sense. :wink:

If you only need those two bool keys, use a Dictionary<int, bool[ ]> instead. Then simply assume that the bool array’s index 0 is the false “key” and index 1 is the true “key”.

1 Like

Thank you for the responses!

I managed to find out how to use the Dictionary, I got my plane placement working with this code + other checkers:

 static Dictionary<int, Dictionary<bool, bool>> corridor = new Dictionary<int, Dictionary<bool, bool>>();

    public static void InitializeCorridors(int maxCorridors)
    {
        for(int i = 0; i < maxCorridors; i++)
        {
            corridor[i] = new Dictionary<bool, bool>();
            corridor[i][true] = false;
            corridor[i][false] = false;
        }
    }

    public static void AssignCorridor(int row, bool isRight)
    {
        if (corridor[row] != null)
        {
            corridor[row][isRight] = true;
        }
    }

    public static bool CheckRow(int row, bool isRight)
    {
        bool value = corridor[row][isRight];
        return value;
    }

    public static void RemoveCorridor(int row, bool isRight)
    {
        if (corridor[row] != null)
        {
            corridor[row][isRight] = false;
        }
    }

I’m not sure if there is a better way to do this but atleast its working :smile:

Dictionaries of Dictionaries can get real confusing and unreadable real fast. Collections of collections in general can get real confusing real fast. Personally I try to avoid them because to make the code maintainable in any manner you have to document verbosely what exactly is going on here with the strange layout that instead you could have just… created a simple data structure that better self-documents the intent (named fields help with that).

You have a grid of tiles.

Create a struct/class for your tile itself with any data needed about it (state, if it’s occupied, etc):

//better define these, I'm just throwing what I see visually in your image here
public enum TileType
{
    Grey = 0,
    Black = 1,
    Green = 2,
}

public class Tile
{
    public TileType type;
    public bool isOccupied;
}

Then yeah, you can throw these into a 2d array that represents the grid. If you want to get a tile adjacent to a given tile you step over 1 index in that direction. Done.

2 Likes

I see! I’ll make sure to test this out too just for the simplicity, still learning new stuff. Thank you!