En elegant lösning på ett komplext problem


I ett av mina sidoprojekt som inkluderar beta-testning av XNA Game Studio 3.0 så behövde jag blanda en kortlek slumpmässigt. Ett inte helt trivialt problem som jag satt och skissade på ett tag och försökte hitta på en klurig lösning när jag plötsligt öppnade Juli-utgåvan av MSDN Magazine och hittade den här lösningen på samma problem fast gällande heltal:

Random rnd = new Random();
var integers = Enumerable.Range(1, 10).OrderBy( o => rnd.Next());

Tack vare att XNA Game Studio 3.0 har stöd för Visual Studio 2008 och även .NET Framework 3.5 så blev min lösning helt enkelt:

public static IList<Card> ShuffleDeck(List<Card> listOfCards)
{
    Random random = new Random();

    var shuffledDeck = from card in listOfCards
                       orderby random.Next()
                       select card;

    return shuffledDeck.ToList();
}

Funktionen tar en initierad lista av kort (som skapats med en uppsättning for-loopar) och returnerar en ny lista som är helt blandad.

Tack LINQ!

Comments (8)
  1. Anders Josefsson says:

    Hur stor blir skillnaden i IL koden emot:

    lList.Sort(delegate(Card a, Card b) { return lRand.Next(-1, 1); });

  2. JohanLindfors says:

    Anders: Jag böjer ödmjukast på huvudet och kommer hädanefter titulera dig Sensei!

    Snyggt.

    Skillnaden i IL blev några tecken men din lösning fungerar på tidigare versioner av ramverket också, och det förtjänar en viss respekt, för alla har nog inte hunnit uppgradera ännu 🙂

  3. Anders Josefsson says:

    Speciellt inte XNA-projekt då DBP kräver 2.0. /:

    Bra med LINQ exempel dock, blir intressant att se hur mycket garbage det genererar. Har du kollat något på det?

  4. JohanLindfors says:

    Din version ser trevligare ut där också.

    I mitt test (som är på 81 kort, för litet för att sparka igång GC osv) så allokeras 6840 bytes för LINQ-frågan, då för Card[] och i ditt exempel allokeras endast 1344.

    Snyggt, effektivt och elegant!

    Kudos Anders!

  5. Anders Josefsson says:

    En helt annan sak; jag skulle vilja se ett inlägg angående en lockless queue implementering i .NET som fungerar på Xbox och inte genererar någon garbage (tror det bara är möjligt mha av en pool, men det är okej). Jag har lyckats med en som fungerar bra på PC men får den inte att fungera i praktiken på Xbox (fungerar ~99% av gångerna dock) och känner ett visst behov av en. (:

  6. JohanLindfors says:

    Anders: Har undersökt din problemställning Anders och noterar att det har ställts liknande frågor i forumet på http://forums.xna.com och det verkar inte ha kommit någon lösning på problemet heller. Den som verkar ha kommit längst i området är, hör och häpna, Anders Josefsson 🙂

    Det ligger för närvarande utanför min expertis att försöka åstadkomma något liknande men förstår din förfrågan. Någon annan kanske är sugen på att bidra med idéer?

    En tävling för http://www.gamedev.se kanske?

    Johan

  7. Anders Josefsson says:

    Nog jag som tagit upp det mest på Creators (asmo), men var ett tag sedan. Tror det är en del som lyckas med en fungerade implementering på Xbox, även om de säkerligen är få.

    En tävling är en bra idé, ska se om jag kan hitta på något som kan skapa lite motivation.

Comments are closed.

Skip to main content