Randomizing player turn order

Hioh all. In the process of trying to make a turn based game and I thought it might be a good little trick to randomize the initial player order, but I’ve hit a wall. Got a small script going that at least should work in Unity (using c#) but every time I try to run it, Unity (Using ver 4.6.2f1) hard locks and stops responding.

I’ve tried looking around a bit and I think I might be doing this wrong as well since I’m fairly new to scripting/coding in Unity, so I could use a bit of help as to what is wrong and if there may be a better way to go about it. Here’s the code in question.

	public string[] playerlist = {"1_JoESlayA","2_NoobiePwNER","3_Shazam", "4_BOOMSTIQ"};
	public string[] playerorder = new string[4];

	void Start () {
		for (int i = 0; i < playerlist.Length;){
			npos = Random.Range (0,playerlist.Length);
			if (playerorder[npos] == ""){
				print("Playerorder Slot " + npos + " is empty");
				playerorder[npos] = playerlist*;*
  •  		print ("Playerorder Slot " + npos + " now contains " + playerorder[npos]);*
    
  •  		i++;*
    
  •  	}*
    
  •  }*
    

Hope someone might be able to shed some light as to why this kills Unity and an idea of how to fix/replace. Thanks in advance.

Are you initialising the elements of your playerorder array somewhere else? If not then they’ll all be null (not “”) and so the if clause containing the loop counter increment will never be entered.

You could either initialise them all thus…

public string[] playerorder = { string.Empty, string.Empty, string.Empty, string.Empty };

…and continue to test for empty playerorder[npos], or change that test to check for null instead of (or as well as) the empty string. For example…

if ( string.IsNullOrEmpty(playerorder[npos]))
{
}

That’s where the bug is in your code and how to fix it, but you can achieve what you’re trying to do here better by constructing the playerorder array as a shuffled copy of the playerlist array. Less room for bugs and less wheel-reinvention.

public string[] playerlist = {"1_JoESlayA","2_NoobiePwNER","3_Shazam", "4_BOOMSTIQ"};
public string[] playerorder = null;
 
void Start () {
  System.Random rnd = new System.Random();
  playerorder = playerlist.OrderBy(x => rnd.Next()).ToArray();
}

Alright, here’s how I would make a randomly ordered string from a string:

using System.Linq;
using System.Collections.Generic;

public string[] RandomPlayerOrder(string[] players){
 List<string> playerlist = players.ToList();
 List<string> order = new List<string>();

 while(playerlist.Count > 0){
  string next = playerlist[Random.Range(0, playerlist.Count-1)];
  playerlist.Remove(next);
  order.Add(next);
 }

 return order.ToArray();
}

That’ll return a randomly ordered array of strings. That might not be the best way to do it, though - in cases like this, I usually have some kind of Player object to represent each player (they are usually a bit more complex than just a name), have a Player in my turn manager script with references to them, and use an int as a pointer to the currently active one.

Here’s a short script that will randomize the order of any given array:

private T[] RandomizeOrder<T>(T[] players) {
    SortedList<float, T> playersSorted = new SortedList<float, T>(); // Create a sorted list of type T values, with float number as key.
    for (int i = 0; i < players.Length; i++) {
        playersSorted.Add(Random.value, players*); // Add each player to the sorted list with a random key value between 0 and 1. Sorted list will automatically sort by this random number, creating a random order.*

}
return new List(playersSorted.Values).ToArray(); // Return the values in the new order, as an array.
}
With your array of strings, just use:
RandomizeOrder(players);