It’s incredibly hard to do this, unless you’re a naturally gifted programmer and can “think in algorithms”.
Here’s an example of a routine that makes really beautiful patterns.
In answer to your specific question, sure, deal in int[,] to pass around such concepts.
“look for a better way to assign the pattern to an array other than hardcoding it” Sure, start with simple routines which do things like “mirror” patterns from one of your quadrants.
/*
Makes pretty patterns .. in the abstract
*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public static class Pretty
{
public static int ColorInt() // just a color code, 1 to 10
{
return Random.Range(1,11);
}
// ChallengePattern is a random pattern with only one color having three-count
// (for the most challenge) the others have a higher count.
// Compare PatternOfInts which is simple and symmetrical (example use: foyer)
public static int[,] ChallengePattern(int kount)
{
if ( kount < 4 ) {Debug.Log("just too hard"); Debug.Break();}
int fullCountOfItems = kount*kount;
// step one, make a list of our colors in a random order.
// in fact, we know that the codes range from 1 to 10
int[] orderOfColors = Pretty.TheNumbers1To10Shuffled();
int[] countOfColors = Pretty.DecideCountsTotalBeing( fullCountOfItems );
// attention...
if ( countOfColors.SumArray() != fullCountOfItems )
{Debug.Log("Algorithm woe, oh oh."); Debug.Break();}
// don't forget to just let the GemInfo know what is happening:
Grid.gemInfo.RememberCounts( orderOfColors, countOfColors );
// now simply load a linear list like that.
List<int> linear = new List<int>();
for ( int t=0; t<10; ++t )
{
int whichColor = orderOfColors[t];
int howManyOfThatColor = countOfColors[t];
for (int k=0; k< howManyOfThatColor; ++k )
linear.Add( whichColor );
}
countOfColors.DebugShow();
linear.ToArray().DebugShow();
// finally, merely shuffle that linear list, and load to the square
linear = linear.OrderBy(Rx => Random.value).ToList();
linear.ToArray().DebugShow();
int[,] rr = linear.ToArray().Squareize();
return rr;
}
public static int[] DecideCountsTotalBeing(int desiredTotal)
{
// for example, if the total is 50, we might go..
// 3, 7, 10, 30
// or perhaps
// 3, 5, 12, 15, 15
// we do want to START WITH A THREE because that's how the game works.
// TBC we "know" there are ten slots (at most),
// (the game simply has ten colors and that's it)
if ( desiredTotal < 20 ) {Debug.Log("just too hard"); Debug.Break();}
int[] result = new int[10];
int traverse = 0;
int remaining = desiredTotal;
// we always start with 3!!
int thisTime = 3;
result[traverse] = thisTime;
++traverse;
remaining -= 3;
// the second one (only) can be reasonably small
thisTime = Random.Range(5,9);
result[traverse] = thisTime;
++traverse;
remaining -= thisTime;
// after this, ensure they are at least 7 in size
while ( remaining > 7 && traverse < 10 )
{
// thisTime = Random.Range(9,20); // means 9 through 19
thisTime = Random.Range(9,17); // means 9 through 16
// that value tunes well...
if ( thisTime > remaining )
thisTime = remaining;
result[traverse] = thisTime;
++traverse;
remaining -= thisTime;
}
// ensure that we got enough.
int total = result.SumArray();
if ( total < desiredTotal )
{
// Note that if we need to adjust one, we just adjust the "fourth one".
// It makes absolutely no difference which one you adjust,
// but it should be one that is not-zero.
// the last one is often zero, so, don't just adjust the last one.
// The adjustment number might be small -- say "2" -- in which case
// if you apply it to a zero item, you'd get a small count.
// (Of course, do not adjust the special three-count item, ie item zero.)
int stillNeeded = desiredTotal - total;
int lastOne = result[3];
// in this algorithm, the fourth one works perfectly in all cases.
lastOne = lastOne + stillNeeded;
result[3] = lastOne;
}
return result;
}
public static int[] TheNumbers1To10Shuffled()
{
List<int> ints = new List<int>();
for (int load=1; load<=10; ++load)
ints.Add(load);
return ints.OrderBy(Rx => Random.value).ToArray();
// to unit test, what about...
// Pretty.TheNumbers1To10Shuffled().DebugShow();
}
public static int[] IndicesUpToWhateverShuffled( int whatever )
{
List<int> ints = new List<int>();
for (int load=0; load<whatever; ++load)
ints.Add(load);
return ints.OrderBy(Rx => Random.value).ToArray();
// to unit test, what about...
// Pretty.TheNumbers1To10Shuffled().DebugShow();
}
// PatternOfInts is a simple symmetrical pattern
public static int[,] PatternOfInts(int kount)
{
// identical to PatternWithStrings,
// but result is ints 1 to 10 (matching our available gem codes)
if ( kount < 1 ) { Debug.Log("woe"); Debug.Break(); }
int[,] rr = new int[kount,kount];
int half = kount/2;
if (kount % 2 > 0) ++half;
int highestIndex = kount-1;
for ( int across = 0; across < half; ++across )
for ( int down = 0; down < half; ++down )
rr[across,down] = Pretty.ColorInt();
// in fact, diagonally mirror that quadrant...
for ( int across = 0; across < half; ++across )
for ( int down = 0; down < half; ++down )
{
if ( across >= down )
rr[down,across] = rr[across,down];
}
// in fact, make a diagonal line always
for ( int across = 0; across < half; ++across )
for ( int down = 0; down < half; ++down )
{
if ( across == down )
rr[across,down] = rr[0,0];
}
// fill the other three qudrants
// mirror across...
for ( int across = 0; across < half; ++across )
for ( int down = 0; down < half; ++down )
rr[ highestIndex -across, down ] = rr[ across, down ];
// mirror down...
for ( int across = 0; across < kount; ++across )
for ( int down = 0; down < half; ++down )
rr[ across, highestIndex -down ] = rr[ across, down ];
return rr;
}
public static void Log( this string[,] squarray )
{
int kount = squarray.GetLength(0);
string res = "
“;
for ( int across = 0; across < kount; ++across )
{
string line = “”;
for ( int down = 0; down < kount; ++down )
line = line +” " +squarray[across,down];
res = res + line + "
";
}
res = res + "
";
Debug.Log(res);
}
}