Your question is a bit unclear.
You say combinations. A combination is simply a list of each available option. For example, you have the array { 1, 2, 3 }
and you want a combination length of 2, you will get the arrays:
{ 1, 2 }
{ 1, 3 }
{ 2, 3 }
You might mean permutations. A permutation is every combination in every order. So, beginning with the same array we had before { 1, 2, 3 }
all of the permutations of length 2 are:
{ 1, 2 }
{ 1, 3 }
{ 2, 1 }
{ 2, 3 }
{ 3, 1 }
{ 3, 2 }
To get all of the permutations regardless of the array length, you would need to find combinations first and calculate permutations.
Whichever option you may mean, here are a couple of useful extension methods.
using System;
using System.Collections.Generic;
using System.Linq;
public static class IEnumerableExtensions
{
// Can be used to get all combinations at a certain level
// Source: http://stackoverflow.com/questions/127704/algorithm-to-return-all-combinations-of-k-elements-from-n#1898744
public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> elements, int k)
{
return k == 0 ? new[] { new T[0] } :
elements.SelectMany((e, i) =>
elements.Skip(i + 1).Combinations(k - 1).Select(c => (new[] { e }).Concat(c)));
}
private static IEnumerable<TSource> Prepend<TSource>(this IEnumerable<TSource> source, TSource item)
{
if (source == null)
throw new ArgumentNullException("source");
yield return item;
foreach (var element in source)
yield return element;
}
// This one came from: http://stackoverflow.com/questions/774457/combination-generator-in-linq#12012418
public static IEnumerable<IEnumerable<TSource>> Permutations<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
throw new ArgumentNullException("source");
var list = source.ToList();
if (list.Count > 1)
return from s in list
from p in Permutations(list.Take(list.IndexOf(s)).Concat(list.Skip(list.IndexOf(s) + 1)))
select p.Prepend(s);
return new[] { list };
}
}
Getting Permutations
It sounds like you just want to get all of the permutations of a combination (in your case PossibleTargets
).
foreach (var permutation in PossibleTargets.Permutations())
{
List<Card> Targets = new List<Card>(permutation);
Out.Add(new GameDecision() { Type = GameDecisionType.PlayCard, TheCard = SpellCard, Targets = Targets });
}
Getting Combinations
If you do in fact mean combinations, then you need to also provide the length of the result array to solve for. You specify this as X
, but you have no indication in your code what X
might be. For this to work right, X must be less than Permutations.Count()
, or you will always get exactly 1 combination consisting of every element in the list.
var length = X;
foreach (var combination in PossibleTargets.Combinations(length))
{
List<Card> Targets = new List<Card>(combination);
Out.Add(new GameDecision() { Type = GameDecisionType.PlayCard, TheCard = SpellCard, Targets = Targets });
}
A common practice is to loop through every possible length (from Combinations.Length to 1) in order to get every possible combination of any length.
for (var length = PossibleTargets.Count(); length > 0; length--)
{
foreach (var combination in PossibleTargets.Combinations(length))
{
List<Card> Targets = new List<Card>(combination);
Out.Add(new GameDecision() { Type = GameDecisionType.PlayCard, TheCard = SpellCard, Targets = Targets });
}
}
Getting All Permutations of Every Length
This example gets every permutation (combination of cards in any order) of every possible length.
for (var length = PossibleTargets.Count(); length > 0; length--)
{
foreach (var combination in PossibleTargets.Combinations(length))
{
foreach (var permutation in combination.Permutations())
{
List<Card> Targets = new List<Card>(permutation);
Out.Add(new GameDecision() { Type = GameDecisionType.PlayCard, TheCard = SpellCard, Targets = Targets });
}
}
}