ScottBlinn
asked on
Determain and assign a play order based on player initiative within a list in C#
I have a list of players. Each player has two properties, Initiative (int) and TurnOrder (int). In C# (.Net 2.0 for this please) I would like to assign each player in the list a unique integer for their TurnOrder (1 through X) based on which player's have the highest initiative (numerically speaking). I would want to randomly break ties between players with the same initiative value, which could be between two or more players (each player with a matching initiative would "roll the dice" to see what the final order would be between them).
The idea would be once I have assigned each player in the list a unique TurnOrder, I could then simply sort the list by TurnOrder:
PlayerList.Sort(delegate(P layer p1, Player p2) { return p1.Initiative.CompareTo(p2 .Initiativ e); });
The idea would be once I have assigned each player in the list a unique TurnOrder, I could then simply sort the list by TurnOrder:
PlayerList.Sort(delegate(P
Here is an implementation:
public class Player
{
public int TurnOrder;
public int Initiative;
public Player(int Initiative) { this.Initiative = Initiative; }
}
public partial class Form1 : Form
{
private Random R = new Random();
List<Player> PlayerList = new List<Player>();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
PlayerList.Add(new Player(5));
PlayerList.Add(new Player(2));
PlayerList.Add(new Player(1));
PlayerList.Add(new Player(7));
PlayerList.Add(new Player(5));
PlayerList.Add(new Player(5));
PlayerList.Add(new Player(4));
}
private void button1_Click(object sender, EventArgs e)
{
PlayerList.Sort(SortByInitiative);
for (int i = 0; i < PlayerList.Count; i++)
{
PlayerList[i].TurnOrder = i + 1;
}
PlayerList.Sort(delegate(Player p1, Player p2) { return p1.TurnOrder.CompareTo(p2.TurnOrder); });
foreach (Player p in PlayerList)
Console.WriteLine(p.TurnOrder.ToString() + " --> " + p.Initiative.ToString());
}
private int SortByInitiative(Player p1, Player p2)
{
if (p1.Initiative != p2.Initiative)
return p2.Initiative.CompareTo(p1.Initiative);
else
return R.Next() >= .5 ? 1 : -1;
}
}
ASKER
Thank you guys.
Idol Mind: I implemented your solution and it almost does the trick. It seems that because it only takes in two players to compare at once, you end up with the same pattern/order between all players with the same Initiative value (so all players with an Initiative of 5 show up in the same order/are assigned the same TurnOrder value within the final list). What would I need to do to assign a random order between the players with the same Initiative each time the code is run?
Idol Mind: I implemented your solution and it almost does the trick. It seems that because it only takes in two players to compare at once, you end up with the same pattern/order between all players with the same Initiative value (so all players with an Initiative of 5 show up in the same order/are assigned the same TurnOrder value within the final list). What would I need to do to assign a random order between the players with the same Initiative each time the code is run?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
This did the trick. Thank you Idle Mind.
1) sorting the players by Initiative, high to low
2) use a loop to give each player a TurnOrder value by:
2-1) if n nad n+1 has same Initiative, find the one bigger than n;
a) randomly assign TurnOrder for n, n+1, ...
2-2) assigne a TurnOrder .