从目标列表生成所有可能的x量目标

时间:2015-09-07 10:26:51

标签: c#

我有一张卡片(目标)列表,其中包含卡片游戏中卡片的所有可能目标。但是,我需要使用TargetCount卡的所有可能组合来创建minimax树。我应该如何在C#中解决这个问题?

我尝试使用网站周围的CartesianProduct扩展程序,但它似乎不起作用(当我尝试使用它时出现编译错误)。

我只是将目标存储在List<Card>中,并且已经拥有所有可能的目标。现在,对于每种可能的X卡组合,我想在搜索树中添加一个包含每个X可能目标的List<Card>,如下所示。我该怎么做呢?

List<GameDecision> Out = new List<GameDecision>();

foreach(Card SpellCard in PlayerSpellbook(Player))
{
    List<Card> PossibleTargets = GetPossibleTargets(SpellCard);

    foreach(all combinations of possible targets)
    {
        List<Card> Targets = new list of Card.TargetCount targets;
        Out.Add(new GameDecision() { Type = GameDecisionType.PlayCard, TheCard = SpellCard, Targets = Targets });
    }
}

1 个答案:

答案 0 :(得分:1)

你的问题有点不清楚。

你说组合。组合只是每个可用选项的列表。例如,您有数组{ 1, 2, 3 },并且您希望组合长度为2,您将获得数组:

  1. { 1, 2 }
  2. { 1, 3 }
  3. { 2, 3 }
  4. 您可能意味着排列。排列是每个顺序中的每个组合。所以,从{ 1, 2, 3 }之前的相同数组开始,长度为2的所有排列都是:

    1. { 1, 2 }
    2. { 1, 3 }
    3. { 2, 1 }
    4. { 2, 3 }
    5. { 3, 1 }
    6. { 3, 2 }
    7. 要获得所有排列而不管数组长度如何,首先需要找到组合并计算排列。

      无论您选择哪种选项,这里都有一些有用的扩展方法。

      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 };
          }
      }
      

      获取排列

      听起来你只想得到一个组合的所有排列(在你的情况下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 });
      }
      

      获取组合

      如果你确实意味着组合,那么你还需要提供要解决的结果数组的长度。您将其指定为X,但您的代码中没有任何迹象表明X可能是什么。为了使其正常工作,X必须小于Permutations.Count(),否则您将始终获得由列表中的每个元素组成的1个组合。

      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 });
      }
      

      通常的做法是遍历每个可能的长度(从Combinations.Length到1)以获得任何长度的每种可能组合。

      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 });
          }
      }
      

      获取每个长度的所有排列

      此示例获取每个可能长度的每个排列(任意顺序的卡片组合)。

      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 });
              }
          }
      }
      
相关问题