2017-07-26 1 views
1

So habe ich CardBase abstrakte Klasse und Ich möchte einige zufällige Kartenelemente extrahieren einige spezifische Liste ausschließen. Also habe ich das gefallen.Wie wählt man zufällige Elemente aus der Liste aus?

public List<CardBase> GetRandExclude(List<CardBase> list, int elementsCount, List<CardBase> excludeList) 
{   
    var returnCards = from card in list 
           where !excludeList.Contains(card) 
           select card; 
    foreach (CardBase cd in returnCards.Take(elementsCount)) 
    { 
     Debug.Log("Selected random card is "+cd.name); 
    } 
    return (List<CardBase>) returnCards.Take(elementsCount); 
} 

Habe ich richtig gemacht? Gibt es einen besseren Weg? Vielen Dank im Voraus.


Also änderte ich ein wenig so. Und das scheint funktioniert.

public List<CardBase> GetRandExclude(List<CardBase> list, int elementsCount, List<CardBase> excludeList) 
{   
    var returnCards = from card in list 
           where !excludeList.Contains(card) 
           select card; 
    foreach (CardBase cd in returnCards.OrderBy(arg => Guid.NewGuid()).Take(elementsCount).ToList()) 
    { 
     Debug.Log("Selected random card is "+cd.name); 
    } 
    return returnCards.OrderBy(arg => Guid.NewGuid()).Take(elementsCount).ToList(); 
} 
+0

mit Ich stelle mir vor, dass man bestimmte Ausnahmen und/oder unerwünschte Ergebnisse mit Ihrem aktuellen Ansatz bekommen. Fügen Sie daher eine kleine Beispielliste hinzu, um alle Aspekte Ihres gewünschten Ergebnisses anzuzeigen. – grek40

+0

Ich denke, wenn Sie es zufällig machen möchten, sollten Sie die [System.Random-Klasse] (https://msdn.microsoft.com/en-us/library/system.random (v = vs .110) .aspx # Anchor_4), um eine Zufallszahl zu generieren, die Ihnen mitteilt, wie viele Nummern Sie aus den verbleibenden Listenelementen entnehmen und dieselbe Klasse verwenden sollten, um den Index für jede aus der Liste zu wählende Zahl zu generieren. – Yatin

Antwort

1

Sie können den Linq Weg gehen und verwenden Except vorgesehen CardBase irgendeine Form von Gleichheit Vergleich hat. Sonst könnten Sie die Überladung verwenden und eine IEqualityComparer<CardBase> comparer

Von dort wollen Sie nach dem Zufallsprinzip Karten aus den verbleibenden verfügbaren Karten auswählen.

static Random randomizer = new Random(); 
public List<CardBase> GetRandExclude(List<CardBase> list, int elementsCount, List<CardBase> excludeList) { 
    var availableCards = list.Except(excludeList).ToList(); 
    int count = Math.Min(elementsCount, availableCards.Count); 
    var selectedCards = new HashSet<CardBase>(); 
    do{ 
     var index = randomizer.Next(0, availableCards.Count); 
     var card = availableCards[index]; 
     selectedCards.Add(card); 
    } while (selectedCards.Count < count); 
    foreach (CardBase cd in selectedCards) { 
     Debug.Log("Selected random card is " + cd.name); 
    } 
    return selectedCards.ToList(); 
} 
+0

Danke, also gab es das einfachste Keyword, außer. Und ich benutze Unity Game Engine jetzt, so dass Einheit Random.Range-Funktion zur Verfügung gestellt. Dann brauche ich vielleicht nicht system.random()? – leegod

+0

Ich bin nicht vertraut mit der Einheit, also kann ich nicht sagen. In Ihrer Frage gab es keinen Hinweis darauf, dass es sich um eine Einheit handelte. – Nkosi

+0

Sieht so aus, als ob es die doppelte Auswahl derselben Karte erlaubt ... habe ich etwas übersehen? – grek40

0

Sie erhalten eine Casting-Ausnahme mit Ihrem Code.

Also zuerst die IEnumerable von CardBase.

dann die Liste zurück ToList()

public List<CardBase> GetRandExclude(List<CardBase> list, int elementsCount, List<CardBase> excludeList) 
     { 
      var returnCards = from card in list 
           where !excludeList.Contains(card) 
           select card; 
      foreach (CardBase cd in returnCards.Take(elementsCount)) 
      { 
       //Debug.Log("Selected random card is " + cd.name); 
      } 
      IEnumerable<CardBase> newList = returnCards.Take(elementsCount); 
      return newList.ToList(); 
     } 
+0

Danke kommentieren. – leegod

Verwandte Themen