Ok, let's go step by step. You have a list of names and you want to assign a unique random number to each name. The random numbers must be within the range [1, number of names in the list]
The naive brute force way would be to generate a random number, check if it has been rolled before and if not assign it to a name. Repeat the process for each name in the list in order and you are done.
With 4 or 5 names, this will actually run pretty fast but its wateful. Even more when lists get very big, getting to the point where its wasteful and performs horribly. Why? Well you need to roll many more times than necessary.
Is there a better way? Yes. Imagine you problem is: write a method that returns one by one random cards in a standard deck? Would you do it the same way? Or would you somehow store and ordered deck, shuffle it and then simply hand the cards out one by one?
Well, here its the same. Your standard deck is simply an ordered list of numbers from 1 to the total number of shooters: 1, 2, 3, ...., numberOfShooters
.
Now, how would you shuffle it. Well, a naive way would be to create a list, then randomly pick an index, pick the number stored in that list and then remove it from the list to avoid rolling it again. That would work, but again, its wasteful. Why? Because repeatedly removing items in a list can be expensive. Remember lists are just wrappers over a standar array; removing an item mid list entails that all following numbers must be shifted un position up in the array.
An easy way to shuffle a list without all these problems is to use linq (there are better ways but this should suffice in your case):
var numbersToShuffle = Enumerable.Range(1, numberOfShooters);
var rnd = new Random();
numbersShuffled = numbersToShuffle.OrderBy(i => rnd.Next());
The rest should be easy.