0

I am developing a card game and in this card game, you can build new cards up to the value of 10.

Before the player can build a new card he/she must first select a bunch of cards he wants to build with, each card that gets selected will be added to a list of selected cards.

What then needs to happen is the player must be shown what cards he can build using different combinations of the cards available in the list. e.g if you have a 2 and 3 in your list of selected cards you can build a 5 because of 2 + 3 = 5.

These combos will be added to a new list where the player will be able to select the new card he can build from that collection/combo

var listOfCardsSelected = new List<int>{2,5,6,8,7,3, 1};

// Get a list of card combo's that has a value <= 10 Combo e.g:

1 + 3 = 4 // This becomes a combo
2 + 5 = 7 // This becomes a combo 
3 + 2 = 5 // This becomes a combo 
6 + 2 = 8 // This becomes a combo
6 + 3 = 9 // This becomes a combo
7 + 3 = 10 // This becomes a combo

2 + 5 + 3 = 10 // This becomes a combo
2 + 5 + 1 = 8 // This becomes a combo
3 + 2 + 1 = 6 // This becomes a combo
6 + 3 + 1 = 10 // This becomes a combo

//OR   another random variation
var listOfCardsSelected  = new List<int>{2,5,2,8,1,3, 1};

1 + 1 + 3 + 2 + 2 = 9 // This becomes a combo
5 + 1 + 1 + 3 = 10 // This becomes a combo
5 + 2 + 2 + 1 = 10 // This becomes a combo

The example of code below works but it only returns combos that work with only 2 card combos, some combos need to be able to take bigger combos that take more values.

void CheckForCombo()
{       
 // For every card in our Selection
 foreach(int cardValue in listOfCardsSelected)
 {
   int comboTotal = 0;
   //Compare it to other cards
    for(int i =0; i< listOfCardsSelected.Count; i++)
     {
      // Card cant use it's own value
        if(listOfCardsSelected[i] != cardValue)
          {
             // If the value is <=10
             if((cardValue + listOfCardsSelected[i]) <= 10)
             {
               comboTotal = cardValue + listOfCardsSelected[i];
               comboCollection.Add(comboTotal);
             }
          }
     }
  }
}
Derik
  • 3
  • 2
  • Could you provide your code class Cardtype code ? –  Jul 10 '19 at 12:58
  • 1
    You have to create a recoursive call of your method. With that you can make combos with as many cards you want. – Presi Jul 10 '19 at 13:00
  • Bob - I have removed the CardType class that was used in the foreach and replaced it with a normal int – Derik Jul 10 '19 at 13:25
  • Persi can you please elaborate? what would be the best method of implementing a recursive method? I do understand that a recursive method is a method that can call itself up until a certain condition has been met – Derik Jul 11 '19 at 10:12

2 Answers2

0

With BackTracking, you can get the combination and the sum of the combination

void Main()
{
    var results = Combination(new[] { 2,2, 5, 6, 8, 7, 3, 1 });

    foreach (var result in results.OrderBy(x => x.Count))
    {
        Console.WriteLine($"{string.Join(",", result)} = {result.Sum()}");
    }
}

IList<IList<int>> Combination(IList<int> inputs)
{
    var res = new List<IList<int>>();
    BackTracking(inputs.OrderByDescending(x => x).ToList(), 0, 0, res, new List<int>());

    return res;
}

void BackTracking(IList<int> inputs, int currentIndex, int currentSum, IList<IList<int>> result, IList<int> currentCombo)
{
    if (currentIndex == inputs.Count)
    {
        if (currentCombo.Count != 0 && currentSum <= 10 && result.Any(x => x.SequenceEqual(currentCombo)) == false)
            result.Add(currentCombo.ToList());
        return;
    }

    BackTracking(inputs, currentIndex + 1,currentSum, result, currentCombo.ToList());
    currentCombo.Add(inputs[currentIndex]);
    BackTracking(inputs, currentIndex + 1, currentSum + inputs[currentIndex], result, currentCombo.ToList());
}
Han Eui-Jun
  • 142
  • 1
  • 8
0

Based on a previous SO answer:

    static List<List<int>> GetCombinations(List<int> list)
    {
        var allCombinations = new List<List<int>>();
        double count = Math.Pow(2, list.Count);
        for (int i = 1; i <= count - 1; i++)
        {
            string str = Convert.ToString(i, 2).PadLeft(list.Count, '0');
            int total = 0;
            var combination = new List<int>();
            for (int j = 0; j < list.Count; j++)
            {
                if (str[j] == '1')
                {
                    if (total + list[j] <= 10)
                    {
                        total += list[j];
                        combination.Add(list[j]);
                    }
                }
            }
            if (combination.Count > 1)
            {
                if (!allCombinations.Any(c => c.SequenceEqual(combination)))
                {
                    allCombinations.Add(combination);
                }
            }
        }
        return allCombinations;
    }

...and call it as

var numbers = new List<int> { 2, 5, 6, 8, 7, 3, 1 };
var result = GetCombinations(numbers);
kaffekopp
  • 2,551
  • 6
  • 13