Is there a better way to randomly select an used spawn point?

I have 9 spawn points along the top of the screen (none of which are 0). The following code selects a random spawn point for 6 spawns and makes sure they don;t repeat their location during the spawn.

void SpawnNormalApple ()
{
	float addXPos;

	//add to gold and combo counters
	comboCounter++;
	goldCounter++;
	
	if (!firstSpawn) {
		do {
			addXPos = (float)a_locations [random.Next (a_locations.Length)];
		} while(lastSpawnLocation == addXPos && (addXPos != 0));
		lastSpawnLocation = addXPos;
	} else {
		firstSpawn = true;
		addXPos = (float)a_locations [random.Next (a_locations.Length)];
		lastSpawnLocation = addXPos;
	}
	
	Vector3 spawnPos = transform.position + new Vector3 (addXPos, 0, 0);
	switch (goldScript.CURRENT_EFFECT) {
	case AppleCollider.GOLD_EFFECTS.NONE:
		if (random.Next (100) > 80) {
			Instantiate (rottenPrefab, spawnPos, Quaternion.identity);
		} else {
			Instantiate (applePrefab, spawnPos, Quaternion.identity);
		}
		break;
	case AppleCollider.GOLD_EFFECTS.REPEL:
		Instantiate (applePrefab, spawnPos, Quaternion.identity);
		break;
	case AppleCollider.GOLD_EFFECTS.FRENZY:
		if (random.Next (100) < 50) {
			Instantiate (comboPrefab1, spawnPos, Quaternion.identity);
		} else {
			Instantiate (comboPrefab2, spawnPos, Quaternion.identity);
		}
		break;
	case AppleCollider.GOLD_EFFECTS.SUPERFRENZY:
		if (random.Next (100) < 50) {
			Instantiate (comboPrefab1, spawnPos, Quaternion.identity);
		} else {
			Instantiate (comboPrefab2, spawnPos, Quaternion.identity);
		}
		break;
	default:
		break;
		
	}
	
	if ((comboCounter == 5) && (goldCounter != 50)) {
		comboCounter = 0;
		SpawnComboApple ();
	} else if (goldCounter == 50) {
		comboCounter = 0;
		SpawnComboApple ();
		goldCounter = 0;
		SpawnGoldApple ();
	}
}

Though sometimes the code will spawn it at coordinates x = 0. Is there a reason for that occurring. Is there a better way to approach this?

1 Answer

1

Another approach would be to add the spawn points to a list and shuffle the list. To select a spawn point…

if (list is empty)
  generate new spawn list

get the spawn point at the top of the list and remove it
use the new spawn point

Think of it like a deck of cards. Once you remove a card it can’t be picked again until you’ve removed them all. Once the deck is empty you reshuffle and start again.