- Home /
Puzzle + Grid Instantiate - Random
Hey guys, the script below works fine, but I'm wondering how I could add more control in the way things are created randomly.
Script: The script below instantiates GameObjects per an X and Y grid. In the instantiation process, a random number is selected from the puzzleGridArray.length., which then assigns it a X and Y coordinate to go to. Pretty straightforward instantiate coding.
Problem: Sometimes the same prefab is created 3 times in a row, which is what I'd like to avoid when the board is created. The point of the game is to eliminate objects, so when this happens, the 3 destroy themselves immediately when the game starts. I'd like to even take this one step further where the prefab will not instantiate itself vertically in 3s as well (Which I think is even harder).
Question: How can I add layers of control to where if Random picks the same object 3 times in a row, it switches to another one instead and continues on its merry way?
#pragma strict
//Grid Script
//Inspector Variables
var gridPrefab : Transform;
var gridX : int = 8;
var gridY : int = 10;
var puzzleX : int = 8;
var puzzleY : int = 5;
var gridArray : Transform[,] = new Transform[gridX, gridY];
var puzzleArray : Transform[,] = new Transform[puzzleX, puzzleY];
var puzzleTypeArray : GameObject[];
function Start ()
{
SpawnGrid();
SpawnPuzzlePieces();
}
function SpawnGrid()
{
for(var i = 0; i < gridX; i++)
{
for(var j = 0; j < gridY; j++)
{
Instantiate(gridPrefab, Vector3(j, i, transform.position.z), Quaternion.identity);
}
}
}
function SpawnPuzzlePieces()
{
for(var i = 0; i < puzzleX; i++)
{
for(var j = 0; j < puzzleY; j++)
{
Instantiate(puzzleTypeArray[Random.Range(0, puzzleTypeArray.Length)], Vector3(j, i, transform.position.z), Quaternion.identity);
}
}
}
I don't want to quickly answer my own question after just posting it, but I may have just solved it (I'll wait for others to confirm). I can create a switch that generates a random int and the cases can change the number depending on what's picked.
So, if 0 is picked, the range 1-4 is only available, and so on.
Answer by VigorousApathy · Jan 12, 2013 at 12:30 AM
Nice! Didn't even know such a (detailed) doc page existed for random numbers. It essentially contains everything I said, and more.
Answer by Wolfram · Jan 11, 2013 at 10:21 PM
You can use weighted random numbers instead of purely random ones (see accepted answer in link).
The pseudocode explains the principle. For a dynamic version, you would initialize all weights to 1 (not 0!) and replace the return i
with:
if(...){
for(int j=0; j<num_choices; j++)
choice_weight[j]++; // increase weight of all numbers, to increase chance they'll be picked the next turn...
choice_weight[i]=0; // ...but *reset* the weight of our current number, so it won't be picked again
return i;
}
EDIT:
This ensures that:
the same number won't be picked twice in a row
numbers just picked recently have lower probabilities to be picked again
numbers not picked increase their chances to be picked the next turn
it is much more likely that all numbers are picked relatively evenly distributed with much fewer samples, as opposed to a purely random approach
You can even influence the probability for certain numbers, for example by initializing then with a value >1 (but then you'd have to handle the code pictured above differently, because it will override the initial weights over time.
Your answer
Follow this Question
Related Questions
instantiate a random object from multiples via 'tag' 1 Answer
How to instantiate the first 8 gameobjects in an array (UnityScript)? 1 Answer
multiple object in multiple spawn Point with out repeat 0 Answers
Randomly instantiate objects from array without choosing the same item twice. 2 Answers
OverlapSphere for parallel arrays 1 Answer