0
\$\begingroup\$

I'm working in C# on a Unity 2D game that spawns a shape that has only one correct landing place. There are 7 basic shapes but the component 4 squares of each shape are unique, with each bearing, say, a unique number. There are many more than 7 unique shapes because any component square is unique to the shape set. So the shapes have squares bearing a unique number (1,2,3,4 on a square; 5,6,7,8 on another square; 9,10,11,12 in a line (I-shape), 13,14,15,16 in another line (I-shape), etc. each of these shapes must be moved (by dragging, dropping or rotating) to its particular place in the grid.

I need to swiftly (1) indicate whether a shape has landed correctly and, if not, (2) move the misplaced (and possibly mis-rotated) shape to its proper location so that remaining falling pieces are not blocked from attaining their correct placements.

For (1), I'm using a dictionary with a string for the key that identifies the square component of the shape and an integer 2D array for the grid location values. Here is the declaration:

Dictionary<string, int[,]> dictOfProperLocations = new Dictionary<string, int[,]>();

Visual Studio is OK with that. But I am unable so far to allocate key-value pairs to the dictionary. I've tried the following and variants to indicate that a straight shape (an I-shape) bearing the numbers 1-4 belongs at the origin at its left end and stretches straight to the right:

dictOfProperLocations.Add("1", [0,0]);
dictOfProperLocations.Add("2", [1,0]);
dictOfProperLocations.Add("3", [2,0]);
dictOfProperLocations.Add("4", [3,0]);

But Visual Studio objects to that. I find many examples for C# dictionaries with string-keys and 1D-array-values, but no examples for this case with 2D-array-values.

Or might this be better handled with a 2D Transform[,] for the values representing the proper grid locations? Thank you.

\$\endgroup\$
2
\$\begingroup\$

First, you need to understand that just because you need two elements in your array does not make it a two-dimensional array.

We can define a one-dimensional array with two elements like this:

int[] myArray = new int[]{1, 2};

This array is one-dimensional: you need only one index input to select either myArray[0] == 1 or myArray[1] == 2

A two-dimensional array is an array that needs two indices to select an element. eg..

int[,] myMatrix = new int[,]{
 {0, 1, 2},
 {3, 4, 5},
 {6, 7, 8}
};

When we want to index this array, we need to specify both the row and the column we want to address: myMatrix[1, 0] == 3

But if you know in advance that you just need a pair of coordinates, an array is overkill. We can store our coordinates more efficiently like this:

in Int2.cs:

public struct Int2 {
    public int x;
    public int y;
    public Int2(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

At the top of your Board class, where you define member variables:

public Dictionary<int, Int2> dictionaryOfProperLocations = new Dictionary<int, Int2>();

When you want to define a new location mapping inside that type:

dictionaryOfProperLocations.Add(0, new Int2(0, 0));

This way you have fewer heap allocations, array bounds checks, etc. Using an integer as a key instead of a string containing an integer makes the hashing work of the Dictionary a little easier too.

I'm not sure if using a dictionary in this way is necessarily the best way to implement the gameplay you're describing, but for now I'll just address the syntax. If you want advice on algorithms & data structures for doing spatial queries about tetrominos, that might be a separate question we could help you with.

\$\endgroup\$
  • \$\begingroup\$ I copied all of your public struct Int2 code in your initial response and pasted it into the existing board class. Then I tried posting this all above and outside the board class, but I get the same errors. \$\endgroup\$ – WPWPWP Sep 2 '18 at 18:03
  • \$\begingroup\$ Since I haven't seen your class structure, that's not something I can help you with. Pay attention to your compiler errors and you'll be able to sort it out. If you're getting "name does not exist" errors, then you're trying to use a variable outside of the scope in which you defined it, or you've spelled the name differently in two places. As a general rule, code shared online isn't meant to be copy-pasted as a block. It's an example to read, understand, and implement yourself according to your needs. \$\endgroup\$ – DMGregory Sep 2 '18 at 18:12
  • \$\begingroup\$ Oh, there are additional errors including: "The modifier new is not valid for this item" and "Method must have a return type" and "Accessibility modifiers required." \$\endgroup\$ – WPWPWP Sep 2 '18 at 18:16
  • \$\begingroup\$ I'm unable to reproduce the errors you describe, so there must be an issue in how you've incorporated these examples into your code. Make sure you've defined your struct in its own file, defined the dictionaryOfProperLocations collection as a member variable of the type you want to host it, and placed your Add lines in the corresponding initialization methods for that type / in whatever method you use to determine the desired locations. When in doubt, working your way through some beginner C# tutorials can help you get more familiar with how the language is structured. \$\endgroup\$ – DMGregory Sep 2 '18 at 18:24
  • \$\begingroup\$ Thanks for your exceptional help. I think you just nailed at least part of the problem - I did not declare the struct in its own file. That occurred to me earlier but I haven't tried it yet. \$\endgroup\$ – WPWPWP Sep 2 '18 at 18:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.