dictionary (of integer, list of integer) befüllen und initiallisieren

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von Visual_Prog.

    dictionary (of integer, list of integer) befüllen und initiallisieren

    Moin, ich wollte mal fragen, ob Jemand weißt, wie man einen dictionary of integer, list of integer anhand eines einfaches Beispieles initialisieren und befüllen kann.
    Für das Beispiel unten beispielsweise z.B. 5 keys mit entsprechenden 5 values als list of integer

    VB.NET-Quellcode

    1. Dim inventory As New Dictionary(Of Integer, List(Of Integer))
    So?

    VB.NET-Quellcode

    1. Dim inventory As New Dictionary(Of Integer, List(Of Integer))
    2. for i as integer = 0 to 100
    3. Dim lst as New List(Of integer)
    4. lst.Add(1)
    5. lst.Add(2)
    6. lst.Add(3)
    7. lst.Add(4)
    8. lst.Add(5)
    9. inventory.Add(i,lst)
    10. Next


    Edit: Schleife drum rum gebastelt.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „mrMo“ ()

    ok danke schon mal. Hintergrund der Frage ist folgender:

    ich habe einen spieler mit einer list of integer an karten, die ihn fehlen.
    dazu habe ich noch 3 weitere spieler, mit karten, die sie doppelt haben.

    nun soll das programm herausfinden, welche doppelte karten von den jeweils 3 spielern in der liste der fehlenden karten vom spieler mit den fehlenden karten auch vorhanden sind.
    es soll dann ausgeben von wie viele karten tauschbar sind, welche davon sind tauschbar und zwischen welche spielern.

    VB.NET-Quellcode

    1. inventory.Add(0, spieleranzahl(0).welchenichtvorhanden)
    2. inventory.Add(1, spieleranzahl(1).doppeltekartenliste)
    3. inventory.Add(2, spieleranzahl(2).doppeltekartenliste)
    4. inventory.Add(3, spieleranzahl(3).doppeltekartenliste)


    jetzt habe ich einen ansatz mit directory of, bin mir jedoch nicht sicher ob es wirklich das richtige tool hier ist.
    Wann wirst Du endlich von Deinen Integerlisten wegkommen und mit Spielkartenobjekten anfangen?

    So aus dem Kopf als Anfang.

    VB.NET-Quellcode

    1. For Each Player In spieleranzahl 'warum "spieleranzahl"?!? Es ist eine Spielerliste!
    2. If Player Is CurrentPlayer Then Continue For
    3. MessageBox.Show($"Spieler {Player.Name} hat für {CurrentPlayer.Name} {CurrentPlayer.welchenichtvorhanden.Where(Sub(x) Player.doppeltekartenliste.Contains(x)).Count} Karten.")
    4. Next
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Visual_Prog schrieb:

    (...) list of integer an karten (...)
    Hört sich komisch an. Würde sich deutlich besser anhören wenn du eine List(Of Karte) hättest...

    Es scheint, also wäre dein Datenmodell Grütze bzw. nicht vorhanden. Ohne das, kannst das ganze vergessen. Das weißt du aber sicher selber schon. Du bist ja gerade dabei es irgendwie hin zu biegen, ohne dein ganzes Programm zu ändern, indem du versuchst mit dem Dictionary ein Datenmodell abzubilden.

    Ich würde es mit einer Klasse Spieler und eine Klasse Karte machen und mein Programm von Grund auf überarbeiten.

    Spieler:
    - ID
    - Name
    - Karten auf der Hand (List (Of Karte)
    - Fehlende Karten (List (Of Karte)

    Karte
    - ID
    - Name
    - Wert



    Wenn du dann auf die Eigenschaften „Fehlende Karten“ zugreifst kannst du z.B. im Getter deine Logik (oder die von @VaporiZed implementieren).

    Oder so ähnlich. Kenne dein Spiel ja nicht.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „mrMo“ ()

    ok also ich hab das nochmal neu angefangen mit einer klasse karte und mit einer klasse spieler.
    Berechnet werden sollen alle listen und variablen, die in der klasse spieler enthalten sind, mal schauen ob ich das mit dem neuen Modell umsetzen kann. Später kommt evtl noch was in der Art "tauschbareKarten" hinzu, was sich auf Beitrag #3 und #4 bezieht.
    Wäre noch gut zu wissen ob das jetzt einigermaßen hinkommt.

    VB.NET-Quellcode

    1. Public Class karte
    2. Public kartennummer As Integer
    3. Public kartenname As String
    4. End Class
    5. Public Class spieler
    6. Public Shared zufallkarten As New Random
    7. Public kartenvorhanden As Integer = zufallkarten.Next(0, gesamtkarten + 1) 'Anzahl der Karten eines jeden Spielers
    8. Public fehlendeAnzahlAnKarten As Integer = gesamtkarten - kartenvorhanden 'Wie viele Karten fehlen jeden Spieler
    9. Public welchevorhanden As Integer 'Zuordnungsvariable um welchekartenhatDerSPieler zu erstellen
    10. Public WelcheKartenHatDerSpieler As New List(Of karte) 'Liste der vorhandenen Karten eines jeden Spielers
    11. Public WelcheKartenFehlenDemSpieler As New List(Of karte) 'Liste der fehlenden Karten eines jeden Spielers
    12. Public AnzahlDoppelterKarten As Integer 'Wie viele Karten hat der Spieler doppelt
    13. Public Welchedoppelt As Integer 'Zuordnungsvariable um DoppeltekartenDesSpielers zu erstellen
    14. Public DoppelteKartenDesSpielers As New List(Of karte) 'welche Karten hat der Spieler doppelt
    15. End Class
    16. Public gesamtkarten As Integer
    17. Public spieleranzahl As Integer
    18. Public spielerliste(spieleranzahl) As spieler
    19. Public kartenliste(gesamtkarten) As karte
    20. Public Sub simulation()
    21. Console.WriteLine("Geben Sie die Anzahl as Spielern an: ")
    22. spieleranzahl = CInt(Console.ReadLine())
    23. Console.WriteLine("Geben Sie die Anzahl der Karten im Spiel an: ")
    24. gesamtkarten = CInt(Console.ReadLine)
    25. ReDim spielerliste(spieleranzahl)
    26. ReDim kartenliste(gesamtkarten)
    27. For i = 0 To spieleranzahl
    28. spielerliste(i) = New spieler
    29. Next
    30. For i = 0 To gesamtkarten
    31. kartenliste(i) = New karte
    32. Next
    33. For i = 0 To gesamtkarten
    34. kartenliste(i).kartennummer = i
    35. Next
    36. End Sub
    In meiner Welt ist 'Karte' auch ein bischen was komplizierteres.
    Zumindest bei Skat, Doppelkopf etc. hat eine Karte eine Farbe (karo, Herz, Pik, Kreuz), und einen Wert (zB Skat: 7,8,9,10, Bube, Dame, König, Ass).
    Aber wenn du Tarot-Karten modellierst mag das anders aussehen - da mag eine Karte mit einem kartenname auskommen (kenne mich mit Tarot nicht so aus).
    Du speicherst in der Klasse Spieler (Typen werden immer groß geschrieben) jede Mange redundante Informationen ab, die es schwierig bis unmöglich machen einen konsistenten Zustand zu erreichen bzw. aufrecht zu erhalten. Beispielsweise hast du die Membervariablen WelcheKartenHatDerSpieler, WelcheKartenFehlenDemSpieler und DoppelteKartenDesSpielers (dazu noch weitere die die Anzahl der Karten der einzelnen Kategorien wiedergeben). Wenn der Spieler jetzt eine neue Karte erhält musst du diese der WelcheKartenHatDerSpieler-Auflistung hinzufügen, bei WelcheKartenFehlenDemSpieler löschen und prüfen, obs ein Duplikat ist und es ggf. der DoppelteKartenDesSpielers-Auflistung hinzufügen (Und natürlich die ausgelassenen Anzahlsmember updaten). Klingt nach recht viel Arbeit und sorgt wahrscheinlich früher oder später für inkonsistente Daten.

    Besser:
    Du hast an einer zentralen Stelle die Auflistung aller möglichen Karten (globale Variablen sollte man eigentlich meiden, an dieser Stelle erachtete ich diese allerdings für sinnvoll, da diese zum allgemeinen Kontext der Kartenspiele-Welt gehören) (-> AllCards)
    Die Klasse Spieler enthält eine Auflistung der Karten, die sich in seinem besitzt befinden (-> WelcheKartenHatDerSpieler)

    Alle weiteren Member deiner Spieler-Klasse kannst du aus diesen beiden Werten ableiten:
    WelcheKartenFehlenDemSpieler -> AllCards.Except(WelcheKartenHatDerSpieler)
    kartenvorhanden -> WelcheKartenHatDerSpieler.Count()
    fehlendeAnzahlAnKarten -> WelcheKartenFehlenDemSpieler.Count()
    DoppelteKartenDesSpielers -> WelcheKartenHatDerSpieler.GroupBy(Function(x) x.Number).Where(Function(x) x.Count > 1).Select(Function(x) x.First)
    AnzahlDoppelterKarten -> DoppelteKartenDesSpielers.Count()

    Beispielcode:
    Spoiler anzeigen


    VB.NET-Quellcode

    1. Public Class Card
    2. Public ReadOnly Property Number As Integer
    3. Public ReadOnly Property Name As String
    4. Public Sub New(number As Integer, name As String)
    5. Me.Number = number
    6. Me.Name = name
    7. End Sub
    8. Public Overrides Function Equals(obj As Object) As Boolean
    9. Dim other = TryCast(obj, Card)
    10. If other Is Nothing Then Return False
    11. Return Me.Equals(other)
    12. End Function
    13. Public Overloads Function Equals(card As Card) As Boolean
    14. Return Me.Number.Equals(card.Number)
    15. End Function
    16. Public Overrides Function GetHashCode() As Integer
    17. Return Me.Number.GetHashCode()
    18. End Function
    19. Public Overrides Function ToString() As String
    20. Return $"[{Me.Number}: {Me.Name}]"
    21. End Function
    22. End Class


    VB.NET-Quellcode

    1. Module GlobalContext
    2. ReadOnly Property AllCards As IReadOnlyList(Of Card) = New List(Of Card) From
    3. {{New Card(number:=1, name:="Karte1")},
    4. {New Card(number:=2, name:="Karte2")},
    5. {New Card(number:=3, name:="Karte3")},
    6. {New Card(number:=4, name:="Karte4")}}
    7. End Module


    VB.NET-Quellcode

    1. Public Class Player
    2. Public ReadOnly Property Name As String
    3. Public ReadOnly Property Cards As IReadOnlyList(Of Card) = New List(Of Card)()
    4. Public Sub New(name As String, cards As List(Of Card))
    5. Me.Name = name
    6. Me.Cards = cards
    7. End Sub
    8. Public ReadOnly Property Count() As Integer
    9. Get
    10. Return Me.Cards.Count()
    11. End Get
    12. End Property
    13. Public ReadOnly Property Missing() As IReadOnlyList(Of Card)
    14. Get
    15. Return AllCards.Except(Cards).ToList()
    16. End Get
    17. End Property
    18. Public ReadOnly Property Duplicates() As IReadOnlyList(Of Tuple(Of Card, Integer))
    19. Get
    20. Return Me.Cards.GroupBy(Function(x) x.Number) _
    21. .Where(Function(x) x.Count > 1) _
    22. .Select(Function(x) New Tuple(Of Card, Integer)(x.First, x.Count)) _
    23. .ToList()
    24. End Get
    25. End Property
    26. Public Overrides Function ToString() As String
    27. Dim sb = New StringBuilder()
    28. sb.AppendLine($"Name: {Me.Name}")
    29. sb.AppendLine($"Karten: {String.Join(", ", Me.Cards.OrderBy(Function(x) x.Number))}")
    30. Dim duplicateNodes = Me.Duplicates.Select(Function(x) $"{x.Item1}: {x.Item2}x")
    31. sb.AppendLine($"Duplikate: {String.Join(", ", duplicateNodes)}")
    32. sb.AppendLine($"fehlende Karten: {String.Join(", ", Me.Missing)}")
    33. Return sb.ToString()
    34. End Function
    35. End Class


    VB.NET-Quellcode

    1. Public Class Game
    2. Private ReadOnly Property Players As List(Of Player) = New List(Of Player)()
    3. Public Sub New()
    4. With Players
    5. .Add(New Player(name:="Spieler1", cards:=RandomCards()))
    6. .Add(New Player(name:="Spieler2", cards:=RandomCards()))
    7. .Add(New Player(name:="Spieler3", cards:=RandomCards()))
    8. End With
    9. End Sub
    10. Private Shared Function RandomCards() As IReadOnlyList(Of Card)
    11. Static random As Random = New Random()
    12. 'Karten mehrmals zusammenwerfen, damit auch Duplikate entstehen
    13. Dim cardsWithDuplicates = GlobalContext.AllCards.ToList().Concat(GlobalContext.AllCards) _
    14. .Concat(GlobalContext.AllCards)
    15. Return cardsWithDuplicates.OrderBy(Function(x) random.Next) _
    16. .Take(random.Next(cardsWithDuplicates.Count)).ToList()
    17. End Function
    18. Public Sub Simulate()
    19. For Each player In Me.Players
    20. Console.WriteLine(player.ToString())
    21. Next
    22. End Sub
    23. End Class


    Dateien
    • CardGame.zip

      (311,85 kB, 62 mal heruntergeladen, zuletzt: )

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ChristianT.“ ()

    Ja so wie @ChristianT. das geschrieben hat kommt schaut das schon gut aus. So hatte ich mir das gedacht.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen