- Home /
Loop through multidimensional array in C#(Unity)
I have this data
As you can see there's a 2nd board there.
Now what i want is something like this
PSEUDO CODE
If the first boards table[1,1] is not `NULL` and it has Green value then we will start at the 2nd
column.
Now if column 0 has the same length as column 1
Next to this rule is compare the 2nd column 1st
row to 1st column 1st row if they are the same in length
Next to this the 2nd column 2nd row
compare it again to the 1st column 2nd row and so on.
If we are always on the top row like the 3rd
column 1st row(0 index) we will compare the 2nd column 1st row(0 index) to 1st column 1st row(0
index)
then display in the 2nd board a blue circle if it is the same in length if
not red circle.
But if the table[1,1] is not`NULL` and not Green value then I need to compare 1st column and
2nd column if they have the same length
then display in the 2nd board a blue circle if it is the same in length if
not red circle
END PSEUDO CODE
Here's by the way my code of getting the BIG ROAD
string[,] table = new string[104, 6];
int xIndex = 0;
int yIndex = 0;
string newPrevious = "placeholder";
//P = BLUE, B = RED, T = GREEN
string[] strData = { "P ,P ,P ,B ,T ,P ,P B,P ,P ,P ,B ,B ,T ,B ,P ,T ,P " };
string OriginalData = "";
void Start()
{
StartCoroutine("Win_Log");
}
IEnumerator Win_Log()
{
yield return new WaitForEndOfFrame();
for (int i = 0; i < strData.Length; i++)
{
OriginalData += strData[i];
OriginalData += ",";
}
string[] newNewData = OriginalData.Split(',');
string result = "";
string previous = "";
int counterForTie = 0;
int counterForRow = 1;
int justMoveToY = 1;
int moveRow = 1;
int moveCol = 1;
foreach (string newStrData in newNewData)
{
//Debug.Log("This is the data : " + newStrData);
GameObject o = Instantiate(prefab_gameobject) as GameObject;
o.transform.SetParent(pos_big_road);
o.transform.localScale = Vector3.one;
img = (RawImage)o.GetComponent<RawImage>();
//check the length so that it won't throw an exception
if (newStrData.Length > 1)
{
//get only the first letter of the value P,B,T
result = newStrData.Substring(0, 1);
}
else
{
result = "";
}
#region BIG ROAD
if (table.GetLength(0) < xIndex)
{
break;
}
if (result.Equals(newPrevious) || result.Equals("T") && yIndex < table.GetLength(1))
{
if (counterForRow == 1)
{
yIndex = 0;
counterForTie++;
table[xIndex, yIndex] = result;
counterForRow++;
}
else
{
yIndex += 1;
counterForTie++;
table[xIndex, yIndex] = result;
}
}
else if (result.Equals(newPrevious) && previous.Equals("T") && yIndex < table.GetLength(1))
{
yIndex += 1;
counterForTie++;
table[xIndex, yIndex] = result;
}
else
{
if (justMoveToY == 1 && counterForRow == 1)
{
xIndex = 0;
yIndex = 0;
table[xIndex, yIndex] = result;
justMoveToY++;
counterForRow++;
}
else if (justMoveToY == 1)
{
xIndex = 0;
yIndex += 1;
table[xIndex, yIndex] = result;
justMoveToY++;
}
else
{
xIndex += 1;
yIndex = 0;
table[xIndex, yIndex] = result;
counterForTie = 0;
}
}
previous = result;
if (!result.Equals("T"))
{
newPrevious = previous;
}
if (counterForTie < 6)
{
o.transform.localPosition = new Vector3(xIndex * 56, yIndex * -45, 0f);
}
else
{
int reminder = counterForTie % 5;
o.transform.localPosition = new Vector3((xIndex + reminder) * 93, -465, 0f);
}
#region CONDITION
if (newStrData.Contains(scoreBoard[0]))
{
img.texture = NewTexture[0];
o.SetActive(true);
}
if (newStrData.Contains(scoreBoard[1]))
{
img.texture = NewTexture[1];
o.SetActive(true);
}
if (newStrData.Contains(scoreBoard[2]))
{
img.texture = NewTexture[2];
o.SetActive(true);
}
if (newStrData.Contains(scoreBoard[3]))
{
img.texture = NewTexture[0];
o.SetActive(true);
}
if (newStrData.Contains(scoreBoard[4]))
{
img.texture = NewTexture[1];
o.SetActive(true);
}
#endregion
what do you mean by "length of table[1,1]"? From your last questions i'd assume you need to find the colums length. This question suggests you want the length of the entry at index 1,1.
What i meant was the length of the whole column 1 .
I don't understand what you mean, the column length is gonna be the length of the value inside of that index no? arr[1,1].Length
will return the amount a char's in the value, assu$$anonymous$$g arr is a string[,]
To get respective dimension's length use m$$anonymous$$ultiArray.GetLength(dimensionIndex) example
$$anonymous$$Type[,,] m$$anonymous$$ultiArray = new $$anonymous$$Type[2,3,4];
//m$$anonymous$$ultiArray.GetLength(0) = 2
//m$$anonymous$$ultiArray.GetLength(1) = 3
//m$$anonymous$$ultiArray.GetLength(2) = 4
Array's length is fixed and set upon initiation, that's why nobody knows what do you mean with column length which is set to 6 according to the image.
To loop through a column :
//multiArray[4,4]
for(int i =0;i< multiArray.GetLength(0); i++)
{
//multiArray[i,3] //which is the element on *i* row 4th column
}
In case you want the column* length to vary but still be fixed* you can use an array of arrays
ex int[][]
consider Lists too for none fixed size. Cheers!
Answer by Scribe · May 23, 2018 at 08:33 PM
So I got some time to look up the rules of Baccarat so here's some code. There seem to be a lot of intricacies that I have probably overlooked:
using UnityEngine;
using System.Collections.Generic;
public class BigEyeRoadBuilder {
private string[,] bigRoad;
public BigEyeRoadBuilder(string[,] bigRoad) {
this.bigRoad = bigRoad;
}
// Find the 'length' of a column conting all non-null elements
private int columnLength(int column){
int sum = 0;
for(int y = 0; y < bigRoad.GetLength(1); y++){
if(bigRoad[column, y] != null){
sum++;
}
}
return sum;
}
// do these two values match
private bool matchingValue(string a, string b){
return a == b;
}
// Do these two columns have the same 'length'
private bool matchingLength(int columnA, int columnB){
return columnLength(columnA) == columnLength(columnB);
}
// Work out the starting point, either (1,1) or (2,0) if (1,1) is nothing
private Vector2Int startingPosition(){
return bigRoad[1, 1] == null ? new Vector2Int(2, 0) : new Vector2Int(1, 1);
}
// If the previous two columns are the same length return red otherwise blue
private string newColumnCalculation(int x){
return matchingLength(x-2, x-1) ? "red" : "blue";
}
// If the square to the left of this, and the one above it are the same then return red, otherwise blue
private string standardCalculation(int x, int y){
return matchingValue(bigRoad[x-1, y-1], bigRoad[x-1, y]) ? "red" : "blue";
}
private string[,] toArray(List<List<string>> bigEyeTable){
int width = bigEyeTable.Count;
int height = 0;
foreach(List<string> l in bigEyeTable){
height = Mathf.Max(l.Count, height);
}
string[,] arr = new string[width, height];
int x = 0;
foreach(List<string> l in bigEyeTable){
int y = 0;
foreach(string s in l){
arr[x, y] = s;
y++;
}
x++;
}
return arr;
}
public string[,] Calculate(){
Vector2Int start = startingPosition();
List<List<string>> bigEyeTable = new List<List<string>>();
List<string> bigEyeColumn = null;
string lastColour = null;
// Loop through all elements in the 'bigRoad'
for(int x = start.x; x < bigRoad.GetLength(0); x++){
for(int y = start.y; y < bigRoad.GetLength(1); y++){
// If the element is null then don't bother with calculations
if(bigRoad[x, y] == null){
continue;
}
// Find the colour based on either the new column calculation or the standard calculation
string colour = y == 0 ? newColumnCalculation(x) : standardCalculation(x, y);
// If we have changed colour then create a new column
// This happens the first time as well as lastColour equals null and null != colour
if(!matchingValue(colour, lastColour)){
bigEyeColumn = new List<string>();
bigEyeTable.Add(bigEyeColumn);
}
// Add the colour to our active column
bigEyeColumn.Add(colour);
// Keep track of the previous colour so we know when to change column again
lastColour = colour;
}
}
return toArray(bigEyeTable);
}
}
You can then use it as:
string[,] bigRoad = ...;
new BigEyeRoadBuilder(bigRoad).Calculate();
Hope that finally answers your question! Let me know if not and I can try and help you here rather than opening a new question.
Good day sir . Sorry for the late response . Is this public BigEyeRoadBuilder(string[,] bigRoad) { this.bigRoad = bigRoad; }
only because it says get me a return type so i put a void
And also sir the Vector2Int is getting an error The type or namespace name 'Vector2Int' could not be found(are you missing a using directive or an assembly reference?)
That is a constructor not a method, if it is in a class of the same name it should not complain about a return type. Constructors are a very fundamental concept so if you do not understand them please Google them a little.
Vector2Int is a class in newer versions of unity but you can create your own if you don't wish to update. The use case here requires a very simple implementation of a class with just two integer values x and y and a constructor!
Yup got the error out . Sorry about that . Now I am confuse with this sir
new BigEyeRoadBuilder(bigRoad).Calculate();
I'm not sure what you don't understand, you can create an instance of BigEyeRoadBuilder by giving it a 2D string array:
string[,] table = {your calculation};
BigEyeRoadBuilder bigEyeBuilder = new BigEyeRoadBuilder(table);
And then BigEyeRoadBuilder has a method on it Calculate
which returns a 2D string array:
string[,] bigEyeTable = bigEyeBuilder.Calculate();