Objekte verbinden

  • VB.NET

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Objekte verbinden

    Hey,

    ich programmiere ein kleines Spiel,...habe bei dem folgenden Gedanken noch ein Problem,....

    Land(Objekt) soll einem Spieler(Objekt) zugeordnet werden,..
    So das ich sagen kann,...
    Spieler 1 gehört Deutschland
    Spieler 2 gehört Österreich

    Um es kurz und knapp zu halten ich möchte eine kleine Variante von Risiko porgrammieren mit nicht allen Regeln :D

    Jedoch habe ich ein kleines Problem mit dem verknüpfen :(

    LG

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

    wo genau ist dein problem?

    ich würde es außerdem etwas anders machen: eine liste mit allen ländern erstellen und eine liste mit allen spielern. der Spieler (oder das land, je nachdem was für das spiel am sinnvollesten ist - das musst du wissen) hat eine Variable die nicht eine ID inne hat sondern die instanz aus der entsprechenden liste. Das ist sehr praktisch, da klassen ja referenziert werden - d.h. wenn du dem spieler ein land aus der liste zuweist greifst du immer auf genau das gleiche land zu - nicht auf eine weitere instanz.

    egal wo du z.b. spielerXY.land.Name veränderst, jeder spieler der das land zugewiesen bekommen hat (=> referenz) wird die änderung mitbekommen. So kansnt du auf events einbauen aufdie weiterer programmcode reagieren kann

    lg
    hey, ich kenne das spiel nicht aber so würde ich etwas derartiges konstruieren (musst du eben für dich abändern):

    VB.NET-Quellcode

    1. Public Players As New List(Of Spieler)
    2. Public Länder As New List(Of Land)
    3. Sub Erstelle()
    4. Dim Deutschland As New Land("Deutschland") : Länder.Add(Deutschland)
    5. Dim Schweiz As New Land("Schweiz") : Länder.Add(Schweiz)
    6. Dim Spieler1 As New Spieler("Hinz", Deutschland) : Players.Add(Spieler1)
    7. Dim Spieler2 As New Spieler("Kunz", Schweiz) : Players.Add(Spieler2)
    8. End Sub
    9. Class Land
    10. Sub New(ByVal tName As String)
    11. LandName = tName
    12. End Sub
    13. Public LandName As String = "unbekannt"
    14. End Class
    15. Public Class Spieler
    16. Public Sub New(ByVal tName As String, ByVal tLand As Land)
    17. SpielerName = tName
    18. Land = tLand
    19. End Sub
    20. Public SpielerName As String = "Tinkiwinky"
    21. Public Land As Land = Nothing
    22. End Class


    wie gesagt, großer vorteil ist, dass du direkten zugriff auf alle spieler und länder hast (über players und länder). Jeder spieler enthält die referenz zu seinem land. ändert der spieler etwas an dem land (z.b. wieviel geld es besitzt) ändert sich auch das land in der länder-liste. gleiches gilt im umgekehrten fall.
    Da ein Land nicht mehreren Spielern gleichzeitig gehören kann, wäre es auch denkbar dem Spieler ne Property as List (Of Land) hinzuzufügen (Schließlich kann ein Spieler mehrere Länder besitzen). Damit hat der jeweilige Spieler vollen Zugriff auf alle Propertys des/der jeweiligen Länder. Und denn würd ich die Spieler ebenfalls in einer Liste verwalten.

    Fiel Fergnügen

    Vatter
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:

    Vatter schrieb:

    Da ein Land nicht mehreren Spielern gleichzeitig gehören kann, wäre es auch denkbar dem Spieler ne Property as List (Of Land) hinzuzufügen (Schließlich kann ein Spieler mehrere Länder besitzen)

    Klingt zwar atttraktiv, und wird bei sorgfältiger Programmierung wohl auch funktionieren. Allerdings ist die Beziehung eigentlich eher anders herum: jedes Land hat entweder genau 1 Besitzer oder keinen. Also wohl eher dem Land eine Property Owner as Player hinzufügen.
    @Kangaroo,
    Wenn, wie ich schrieb, 1 Land NICHT mehreren Spielern gehören kann, heißt das jedes Land hat entweder genau 1 Besitzer oder keinen. Bis dahin sind mer uns absolut einich.
    Da aber 1 Spieler durchaus mehrere Länders haben kann, würd ich die List(Of Länder) in die Spieler legen.
    Das Spiel läuft ja mE auch vom Ablauf her so, dass ein Spieler nach dem annern dran ist. Is also Spieler 1 an der Reihe, werden die Aktionen in den ihm gehörenden Länders ausgeführt (also die List(Of Länder) durchgeackert). Dann komt Spieler 2 usw..
    Bei deinem Vorschlag muß denn der Spieler in allen Ländern gesucht werden.

    Wenn wir das vertiefen, wecken wir EDR auf :thumbsup: und haben ein wunderschönes typisiertes Dataset, was dafür auch gehen würde.

    Vatter
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:

    Vatter schrieb:

    Bei deinem Vorschlag muß denn der Spieler in allen Ländern gesucht werden.

    und?

    dim r = from l in laender where l.owner = currentplayer select l


    ICH würde es aber NOCH anders lösen ;)

    Nur mal als "Idee":

    VB.NET-Quellcode

    1. Imports AsyncCtpExtensions
    2. Public Class Land
    3. Private Shared Alle As New List(Of Land)
    4. Public Sub New(Name As String)
    5. _Name = Name
    6. Alle.Add(Me)
    7. End Sub
    8. Public Overrides Function ToString() As String
    9. Return _Name
    10. End Function
    11. Public Shared Function GetLand(ByVal Name As String) As Land
    12. Return (From l In Alle Where l.Name.Equals(Name, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault
    13. End Function
    14. Private _Name As String
    15. Public ReadOnly Property Name As String
    16. Get
    17. Return _Name
    18. End Get
    19. End Property
    20. Private _Owner As Player = Nothing
    21. Public Property Owner As Player
    22. Get
    23. Return _Owner
    24. End Get
    25. Set(value As Player)
    26. If value IsNot _Owner Then
    27. Debug.Print(String.Format("{0} Set Owner: Current = {1}, New = {2}", _Name, If(_Owner Is Nothing, "(-)", _Owner.ToString), value.ToString))
    28. If _Owner IsNot Nothing Then _Owner.RemoveLand(Me)
    29. _Owner = value
    30. _Owner.AddLand(Me)
    31. Debug.Print(String.Format("{0} Set Owner: Owner is now {1}", _Name, value.ToString))
    32. End If
    33. End Set
    34. End Property
    35. End Class
    36. Public Class Player
    37. Public Sub New(ByVal Name As String)
    38. _Name = Name
    39. End Sub
    40. Public Overrides Function ToString() As String
    41. Return _Name
    42. End Function
    43. Private _Name As String
    44. Public ReadOnly Property Name As String
    45. Get
    46. Return _Name
    47. End Get
    48. End Property
    49. Private Laender As New List(Of Land)
    50. Public Sub AddLand(ByVal l As Land)
    51. If l.Owner Is Nothing Then
    52. Debug.Print(String.Format("{0} Add Land: Current = {1}", _Name, "(-)"))
    53. l.Owner = Me
    54. ElseIf l.Owner IsNot Me Then
    55. Debug.Print(String.Format("{0} Add Land: Current = {1}", _Name, l.Owner.ToString))
    56. l.Owner = Me
    57. End If
    58. If Not Laender.Contains(l) Then Laender.Add(l)
    59. End Sub
    60. Public Sub RemoveLand(ByVal l As Land)
    61. If Laender.Contains(l) Then
    62. Debug.Print(String.Format("{0} Remove Land: {1}", _Name, l.ToString))
    63. Laender.Remove(l)
    64. End If
    65. End Sub
    66. Public Iterator Function LaenderSet() As IEnumerable(Of Land)
    67. For Each l In Laender
    68. Yield l
    69. Next
    70. End Function
    71. End Class
    72. Public Class game
    73. Public Shared Sub test()
    74. Dim p As New Player("John")
    75. Dim q As New Player("Mary")
    76. p.AddLand(New Land("Deutschland"))
    77. p.AddLand(New Land("Frankreich"))
    78. p.AddLand(New Land("Schweden"))
    79. p.AddLand(New Land("Portugal"))
    80. q.AddLand(Land.GetLand("Deutschland"))
    81. End Sub
    82. End Class

    picoflop schrieb:

    und?

    dim r = from l in laender where l.owner = currentplayer select l


    Was heißt hier und?

    Wir denken sorum, dem Land ist es völlig Wurscht, wem es gehört. Die Bürger (unzufrieden oder nicht) zählen bei Risiko nicht.
    Das Land verhält sich IMMER gleich, der Spieler nicht. Denn er entscheidet, ob er es angreifen muss oder nicht, wenn es ihm gehört oder een nicht. Nicht das Land: Der will auf mich drauf, greift er mich an? Ich sag ihm das mal eben.

    Ich möchte als Spieler auf das Feld: Was ist schneller: "Land gehört du mir?" => Land ansprechen Land guckt nach, sagt ja oder nein. Benötigt einen weiteren Funktionsaufruf mit Referenztyp als Parameter (oder Id als Wertetyp => noch Langsamer da noch herauszufinden wer es denn jetzt ist...)
    Wir wissen ja, Aufrufe Kosten, mit Referenztypen als Parameter kosten sie noch mehr und das Land muss noch gucken, wird ja immermehr... Schneller: Habe ICH in MEINEN LÄNDERN dieses Land? Ja => Hingehen / nein => Angreifen.


    Ein weiteres: Ich bekomme jede Runde für meine Länder die ich hab, Figuren zum Platzieren.

    Was ist teurer oder billiger? Ich müsste jedes Land Fragen, ob ich sein Besitzer bin... Das LINQ an der Stelle ist teuer und unnötig... Lieber einfach gucken: MeineLänder.Count => Soviel Figuren bekomm ich.


    Alles kleine performance-Geschichten, aber auch auf die ganze Datenstruktur ausgeweitet... ein "Ja und" macht viele solcher Fehler, es wird unübersichtlich, schwer Wartbar...

    Daher sollte man sich das datenmodell vorher überlegen, und nicht einfach denken: Das ist an Stelle a praktischer zu handlen, die andern 100 Stellen gehen ja mit Linq... da mach ich lieber die eine Stelle mit Linq und die andern 100 einfach ;)

    Vatter schrieb:

    Bei deinem Vorschlag muß denn der Spieler in allen Ländern gesucht werden.

    Stimmt. Ich gebe zu ich hätte wie Picoflop eine LinQ Abfrage hinter einer Property verborgen, aber von einen (selbst fortgeschrittenen) Anfänger ist das vielleicht etwas viel verlangt. Deshalb gebe ich meistens auch nur Beispiele mit For Each Schleifen. Und wie gesagt: wenn man sauber die Länder bei einem Player austrägt und beim anderen wieder einträgt wird das auch funktionieren.

    Vatter schrieb:

    Wenn wir das vertiefen, wecken wir EDR auf :thumbsup: und haben ein wunderschönes typisiertes Dataset, was dafür auch gehen würde.

    Fielen Dank, You just made my day ! :D ( ... nur so als Gedanke: vielleicht könnte man ja auch eine Exception werfen, wenn ein Land 2x vorkommt ...)

    @Picoflop jetzt komm schon: mach das Spiel noch ganz fertig, fiel fehlt doch nicht mehr ;)
    ich gehe euch mal wieder mit einer Dataset-Lösung auf die Nerven ;)
    In der Ansicht "Player und Länder" können Player und Länder angelegt werden.
    In der Ansicht "Alle Länder" kann ein Land auch seinen Besitzer wechseln.

    Das Helpers-Projekt ist zunächstmal entbehrlich (ist garnet drauf verwiesen), habich aber drin gelassen, falls Erweiterungen erforderlich werden.

    Das Datenmodell geht leichtsinnigerweise davon aus, dass jedes Land irgendeinem Spieler gehört.
    Dateien
    • Risiko00.zip

      (36 kB, 136 mal heruntergeladen, zuletzt: )

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

    Hey,


    erstmal ein großes Dankeschön :)
    Hier wurden viele Interessantepunkte genanntn :)

    Prinzipiell ist erstmal die Performance egal, da ich ein Anfänger bin.

    Wenn ich mir die Lösung von picoflop anschaue sieht das für mich sehr verwendbar aus.
    Denn wenn ich das richtig beurteile, werden die Länder in die Liste der Spieler eingetragen, und so wüsste das Programm
    "Ah das Land gehört Spieler 1!"

    Ist es möglich, diese Liste mit Kontrollstrukturen zu überprüfen,..so das ich sich Spieler 1 nicht selber angreifen kann | das jedes Land einem Spieler gehört?
    Des Weitern muss es auch möglich sein,...Wenn Spieler 1 ein Land verliert, dies Spieler 2 bekommt.

    Ich setze mich gleich sofort mal ran :)

    Lieben Gruß

    Ps: Das Größte Problem ist es jedoch dynamisch zu halten :) Aber das ist was erstmal egal^^

    picoflop schrieb:

    Wenn Spieler 1 ein Land verliert, dies Spieler 2 bekommt.
    Ist doch eh schon implementiert.

    Zum Rest der Fragen: ALLES ist möglich ...
    Hey,

    erstmal danke :) Habe den COde jetzt soweit für meine Bedürfnisse angepasst :)
    Ich versuche schon die ganze zeit eine Ausgabe der Liste zu erreichen,...jedoch bekomme ich das nicht hin :(
    Kannst du mir nur einen Tip geben wie ich das am besten bewerkstellige?

    Lieben Gruß
    Zeige Deinen Code und stelle konkrete Fragen.
    Sonst kommt jemand auf die Idee, Du lässt alle Deine Hausaufgaben von anderen machen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Aus den beiden Liste versuche ich eine Ausgabe zuerzeugen,.... und nein ich weiß nicht wie vorgehen soll,..deswegen will ich ja nur einen Tipp damit ich das selber hinbekomme :)


    Lieben Gruß

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

    Editiere bitte Deinen letzten Beitrag und pack den gesamten Code in einen Expander.
    Gib Deinem Projekt Option Strict On
    Vielleicht meinst Du so etwas:

    VB.NET-Quellcode

    1. Private dd As New Dictionary(Of Spieler, Land)
    2. dd.Add(New Spieler("Müller"), New Land("Deutschland", 1))
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Editiere bitte Deinen letzten Beitrag und pack den gesamten Code in einen Expander.
    Gib Deinem Projekt Option Strict On
    Vielleicht meinst Du so etwas:

    VB.NET-Quellcode

    1. Private dd As New Dictionary(Of Spieler, Land)
    2. dd.Add(New Spieler("Müller"), New Land("Deutschland", 1))
    Hey,

    nein das meine ich leider nicht :)
    Es klappt ja alles wunderbar ich kann Spieler Müller gewisse Länder zuordnen oder auch abziehen:)
    Ich würde dies auch gerne in ein Label ausgeben können:

    So in der Art

    Spieler 1 gehören die Länder: Deutschland, Frankreich usw
    label1 = ("Spieler " & SpielerID & " gehören die Länder " & spieler.liste.ausgabe)

    Lieben Gruß
    Das sieht mir sehr nach der Logik einer Datenbankabfrage aus.
    Davon habe ich keine Ahnung, aber Du findest da viel zu im Forum.
    Ggf. solltest Du eine Daten völlig anders strukturieren, z.B. in 2 DataTables, da kannst Du solche Abfragen mit LINQ durchführen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!