Reputation: 13
I'm still learning C# so bear with me as I attempt to explain. Basiclly what I'm trying to do is deal a deck of cards. So arrayA (arrayGameBlessings in my example) has 52 elements and I want to move 10 cards to arrayB (arrayBlessings) while also removing them from arrayA. Here's what I got so far
for (int i = 0; i <= arrayGameBlessings.Length; i++)
{
int bless = rnd.Next(arrayBlessings.Length);
arrayGameBlessings[i] = arrayBlessings[bless];
arrayBlessings = arrayBlessings.Where(w => w != arrayBlessings[bless]).ToArray();
}
But this doesn't do anything as far as I can tell... What would be the best way to achieve something like this? Preferably a super simple one, two line method that's easy to understand and modify. Thanks!
Upvotes: 1
Views: 819
Reputation: 613053
Card dealing is typically done like this:
A shuffle is done like so. Put integers 0 to 51 into an array. Then shuffle them with, for instance, Fisher-Yates shuffle. Perhaps like this:
int[] shuffle()
{
int[] cards = Enumerable.Range(0, 52).ToArray();
for (int i = cards.Length; i > 1; i--)
{
int j = random.Next(i);
int temp = cards[j];
cards[j] = cards[i-1];
cards[i-1] = temp;
}
return cards;
}
int[] deal(int N)
{
int[] result = new int[N];
Array.Copy(shuffle(), 0, result, N);
return result;
}
If you wanted to be more adventurous you could adapt the shuffle to pick just N cards.
You don't need to remove any elements from the shuffled deck. You just need to remember how many you took so far. And even then, you only need to do that if you are going to take any more at a later time without a new shuffle.
Upvotes: 1
Reputation: 40220
Your approach is not wrong per se, the only detail is that the for
should use <
instead of <=
, that is:
void Main()
{
var arrayBlessings = new int[]{1, 2, 3, 4, 5, 6};
var arrayGameBlessings = new int[5];
var rnd = new Random();
for (int i = 0; i < arrayGameBlessings.Length; i++)
{
int bless = rnd.Next(arrayBlessings.Length);
arrayGameBlessings[i] = arrayBlessings[bless];
arrayBlessings = arrayBlessings.Where(w => w != arrayBlessings[bless]).ToArray();
}
Console.WriteLine(arrayBlessings);
Console.WriteLine(arrayGameBlessings);
}
Note: code tested on LinqPad.
With that said, your approach is very inneficient. Each call to ToArray
will create a new array, which is too much. Instead you may want to try List<T>
:
void Main()
{
const int amount_to_deal = 5;
var arrayBlessings = new List<int>{1, 2, 3, 4, 5, 6};
var arrayGameBlessings = new List<int>();
var rnd = new Random();
for (int i = 0; i < amount_to_deal; i++)
{
int bless = rnd.Next(arrayBlessings.Count);
arrayGameBlessings.Add(arrayBlessings[bless]);
arrayBlessings.RemoveAt(bless);
}
Console.WriteLine(arrayBlessings);
Console.WriteLine(arrayGameBlessings);
}
As mentioned by David Heffernan, an array would be enough to shuffle, for example the following code will shuffle the array:
void Main()
{
var array = new int[]{1, 2, 3, 4, 5, 6};
var rnd = new Random();
for (int i = 0; i < array.Length - 1; i++)
{
int j = i + rnd.Next(array.Length - i);
var tmp = array[j];
array[j] = array[i];
array[i] = tmp;
}
Console.WriteLine(array);
}
Upvotes: 2
Reputation: 6265
//I assume you have a Card class, but this can be anything, integers, for example
void MoveRandomCards(List<Card> source, List<Card> dest, int cards)
{
var rnd = new Random();
for(int i = 0;i<cards && source.Count>0;i++)
{
// random card position to remove from source
var idxSrc = rnd.Next(source.Count);
// random position in destination to insert new card
var idxDst = rnd.Next(dest.Count);
dest.Add(idxDst, source[idxSrc]);
source.RemoveAt(idxSrc);
}
}
Upvotes: 0