views:

96

answers:

4

Hello all,

I want to be able to create a program that will take a list of names from a .txt file (Doesnt have to be a txt, maybe excell, whatever is easiest) and generate those names into groups or "teams".

I have 30 "users" that have to be sorted into "Teams". I want to be able to do this fairly, so I want to random :P.

I haven't yet decided the amount of persons per team, but I will soon.

3 Teams of 10 5 teams of 6

Thanks for the responce.

A: 
  1. Load your list of names from the file.
  2. Create a list of groups/teams.
  3. While there are still items in the names list, use a random number from 0 to the length of the list to take one item from the list and add to a group (i.e. a contrived shuffle).

You need to research the following to accomplish this:

Neil Barnwell
A: 

You haven't provided enough details on where you are having trouble, but here is an overview of what you need to do.


Step 1: Parse the text file. Something like System.IO.File.ReadAllLines is probably fine for this.
Step 2: Shuffle the list randomly. This is pretty easy. Try something like, this.
Step 3: Partition the list into consecutive groups. So for 3 teams of 10, just take the first, second, and third set of 10 names and those are your teams.

If this is a one time thing, I'd just do it myself by pasting the text file into http://www.random.org/lists/ and then doing step 3 by hand.

Brian
+2  A: 

If there's only 30 people in the list or so, you can just read the whole text file into memory split by line breaks, randomize it, then go through the list and create groups.

So, something like this:

public List<String[]> CreateTeams(String filePath, int membersPerTeam)
{
  String[] allUsers = File.ReadAllLines(filePath);   
  List<String> randomUsers = allUsers.OrderBy(s => new Guid()).ToList();
  int teamCount = allUsers.Length / membersPerTeam;
  var teams = new List<String[]>();

  for (int i = 0; i < teamCount; i++)
  {
    String[] team = new String[membersPerTeam];
    for (int j = 0; j < usersPerTeam; j++)
    {
      team[j] = randomUsers[i * membersPerTeam + j];
    }
    teams.Add(team);
  }
  return teams;
}

Though obviously you'd need more error checking, etc. and that nested loop is kind of ugly but you get the idea. And of course this won't work if the total number of users is not evenly divisible by the members per team. However, this should get you going.

_rusty
Thank you!I'll try to start getting this rolling!
+1  A: 

Since this isn't homework and it looked like a fun little project... (This is one huge spoiler)

Console app built for .Net 4.0 with VS 2010 Beta 2

class Program
{
    static void Main()
    {
        /* Assuming one team per line */
        Team[] teams = File.ReadAllLines("teams.txt")
                            .Select(t => new Team(t))
                            .ToArray();

        /* Guid.NewGuid() is creates a sufficiently random order */
        /* Assuming one player per line */
        string[] players = File.ReadAllLines("players.txt")
                                .OrderBy(s => Guid.NewGuid())
                                .ToArray();

        /* 
         * No use randomizing anymore...
         * Just assign (PlayerCount / TeamCount) players to each team 
         */
        for (int i = 0; i < teams.Length; i++)
        {
            var p = players.Skip(i * players.Length / teams.Length)
                            .Take(players.Length / teams.Length);

            teams[i % teams.Length].Players.AddRange(p);
        }

        foreach (Team t in teams)
        {
            System.Diagnostics.Debug.WriteLine(t);
        }
    }
}

class Team
{
    public string Name { get; set; }
    public List<string> Players { get; set; }

    public Team(string name)
    {
        Name = name;
        Players = new List<string>();
    }

    public override string ToString()
    {
        /* Team name plus the players sorted alphabetically */
        /*//.Net 4.0
        return string.Format("{0}  \n{1}",
            Name,
            string.Join("  \n",
                        Players.Select(p => string.Concat("\t", p))
                               .OrderBy(s => s)));
        */

        //.Net 3.5 & 4.0
        return string.Format("{0}  \n{1}",
            Name,
            string.Join("  \n",
                        Players.Select(p => string.Concat("\t", p))
                               .OrderBy(s => s).ToArray()));
    }
}

Example output:

Colts  
    Chuck  
    Cory  
    Jim  
    Sam  
    Ulysses
Saints  
    Al  
    Brett  
    Hank  
    Ned  
    Quinn
Vikings  
    Dave  
    Don  
    Ernie  
    Frank  
    Gus
Jets  
    Bob  
    Eric  
    Isaac  
    Walt  
    Yancy
Chargers  
    Abe  
    Mark  
    Oscar  
    Xavier  
    Zach
Cardinals  
    Fred  
    Kyle  
    Pete  
    Ralph  
    Tom
Austin Salonen
Wait what? This looks amazing. I'm getting errors when I'm trying to put it in :(
@zombiesssz: Compile errors? Runtime errors?
Austin Salonen
Well, I originally tried to put it into a windows form, and that just failed.So I moved onto the console, and I'm getting these Errors:X1 The best overloaded method match for 'stringJoin(string, string[])' has some invalid arguments(Line61)X2 Argument '2': cannot convert 'System.Linq.IOrderedEnumerable<string> to string[](Line59)
ALso, Where would I put the location for the players / teams?IE- where would I put "Application.StartupPath + "players.txt""
I updated the Team.ToString method to be .Net 3.5 friendly. I get the same error when trying to use 3.5.
Austin Salonen
By default, it will search the executable's directory for the file without a path.
Austin Salonen
HM, when I start it, it either directly starts, then stops OR If I do a CRTL + F5 it says "Press any key to continue...", then when I press a Key it closes. Does windows 7 have anything to do with this?
It's writing to the debug window in Visual Studio. Just hit F5 and check the Output window (choose Debug in the drop-down, if necessary).
Austin Salonen
I have been doing debugs.Ok, I just tried a release, and I got this error: System.IO.FileNotFoundException was unhandled Message="Could not find file 'C:\\Users\\ZoMbiESsSZ\\Documents\\Visual Studio 2008\\Projects\\AoRandomConsol\\AoRandomConsol\\bin\\Release\\teams.txt'." But the file is actually in there... lol
I created the text files in the project and set "Copy to Output Directory" to "Copy always". It takes some of the guesswork out of that part...
Austin Salonen
OK, I changed to "Copy always" but it still closes after I click a button :S
Change "System.Diagnostics.Debug" to "Console". I prefer the Debug Output window (especially when I need to copy the output)...
Austin Salonen
Ok awesom its working now!Only thing is... everything is still in 100% order, except anything that is in "team 2", IE - Team 1-1,2,3,4,5 Team 2-10,6,7,8,9 Team 3-11,12,13,14,15 Team 4-16,17,18,19,20
I was improperly creating a Guid... should've been Guid.NewGuid()
Austin Salonen
Sorry, Where?This is amazing BTW, i hope one day when / if this becomes more than just a hobby I will be 1/2 as good as you!
OMG IT WORKS <3 THANK YOU THANK YOU THANK YOU!
@zombiesssz: Thanks but you should be setting the bar quite a bit higher than 1/2 as good as me... I'm not that good. :-)
Austin Salonen
Sorry, but 1 more thing.When I try to run this not in debug mode, it starts then quits :(How do I get it too stay in "release" mode?
@zombiesssz: As it's written here, it won't do anything in a release build but set the teams and exit. System.Diagnostics.Debug.WriteLine doesn't get built in a release build. Console.WriteLine should work in a release build.
Austin Salonen
+1 for ".OrderBy(s => Guid.NewGuid())" <- genius. :)
Neil Barnwell