Link to home
Start Free TrialLog in
Avatar of ScottBlinn
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(Player p1, Player p2) { return p1.Initiative.CompareTo(p2.Initiative); });
Avatar of rendaduiyan
rendaduiyan
Flag of China image

How about this one:
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 .
Avatar of Mike Tomlinson
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;
        }
 
    }

Open in new window

Avatar of ScottBlinn
ScottBlinn

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?
ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
This did the trick. Thank you Idle Mind.