Making patterns in a 2D array

I want to make patterns using projectors at the bottom of the screen that shoot projectiles up in a pattern.

Now I’m not sure what’s the best approach for it, but right now what I’m trying to do is using a 2D array to store the pattern in, but I also want to be able to assign a color to each ‘projectile’. Also I’m trying to look for a better way to assign the pattern to an array other than hardcoding it. By maybe loading it in but I’m not sure how to do that.

Here’s an example of how It’s supposed to shoot projecitles, where the X is where he doesn’t shoot and O is where it shoots

XXXOOOXXX

OOOXXXOOO

XXXOOOXXX

XOOOXOOOX

XXOOOOOXX

And in stead of putting every single point in an array by hand, I was wondering if there was a way to put in in a file somewhere and load patterns in. As well as maybe being able to assign colors to each projectile.

You can create a projectile class like this:

public class Projectile{
    bool shoot;
    Color color;
}

and make an array or a list of this object, like

List<Projectile> projectiles = new List<Projectile>();

Then, you can read your data from a csv file with a script like this: http://wiki.unity3d.com/index.php?title=CSVReader

Or you can build a custom inspector to insert your data.

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);
		}
	
	}