C#-Klasse kapselt Spielkarte mit einem Bild



  • Liebe Leute,

    ich habe eine Klasse namens Karte.cs entworfen, die eine Spielkarte modelliert. Die Klasse hat zwei Attribute (Kartenfarbe und Kartenwert), die über zwei enums gesetzt werden.

    Ich möchte nun gerne in jedem Karten-Objekt zusätzlich ein Bild (jpg oder png) speichern oder referenzieren, passend zu der jeweiligen Karte.

    Die Klasse sollte möglichst so sein, dass man sie ohne Änderungen sowohl in einem Konsolen- als auch in einem GUI Projekt verwenden kann. In der Konsole kann man dann das Bild nicht nutzen.

    Wie würdet ihr das machen?

    Liebe Grüße
    Uwe

    public class Karte
        {
            public Kartenfarbe Farbe { get; }
            public Kartenwert Wert { get; }
    
            public Karte(Kartenfarbe _farbe, Kartenwert _wert)
            {
                Farbe = _farbe;
                Wert = _wert;
            }
        }
    


  • Ich würde die Anwendung entscheiden lassen, ob sie ein Bild dazu hat oder nicht. Eine Formularanwendung pflegt eine Sammlung von Bilder und sucht sich die passende dazu raus, eine Konsolenanwendung tut das halt nicht.



  • @DocShoe Danke erstmal für Deine Antwort!

    Ich kann ja alle Bilder als Ressource in das Projekt laden, so dass die dann im EXE stehen.
    Welcher Datentyp wäre denn als Attribut (Feld im C# Jargon) dann nach Deiner Meinung sinnvoll? Wäre das eine Art Referenz auf die betreffende Ressource?
    Damit habe ich bisher noch keine Erfahrungen gemacht.

    LG Uwe



  • @uhomm
    Gar keine. Jede Karte ist durch Farbe/Wert eindeutig identifiziert, damit kann man ein Bild bestimmen. Ich kenn´ mich mit C# Hashtabellen nicht aus, keine Ahnung, ob man da Farbe/Wert zu einem Key zusammenbasteln und den für einen Lookup benutzen kann. Also sowas:

    Image ImageCollection::find_image( Kartenfarbe farbe, Kartenwert wert )
    {
        var xyz = make_key( farbe, wert );
        return Hashtable.find( xzy );
    }
    

    Die ImageCollection pflegt die Formularanwendung.



  • Sehe ich auch so wie @DocShoe: die Klasse sollte so bleiben wie sie ist und nur in der GUI-Anwendung solltest du eine Klasse bzw. Methode haben, welche dann das betreffende Bild lädt:

    Image GetImage(Karte karte)
    {
      string cardName = karte.Farbe + "_" + karte.Wert + ".jpg"; // oder so ähnlich
      
      return new Bitmap(cardName); // alternativ aus Ressource laden
    }
    

    Evtl. kannst du ja noch ein Caching einbauen (mittels eines Dictionary<string, Image>).

    Edit: Sehe gerade, daß @DocShoe auch fast zeitgleich mit mir geantwortet hat, jedoch ist Hashtable veraltet und sollte
    durch das generische Dictionary ersetzt werden (wie ich ja auch geschrieben habe).



  • @DocShoe @Th69

    Herzlichen Dank an Euch beide!
    Die Nutzung der generischen Dictionary-Klasse hatte ich mir auch schon überlegt, war mir aber nicht sicher, ob es vielleicht eine elegantere Variante gibt.
    Den Vorschlag werde ich mal weiter verfolgen...mit Kartenwert und -farbe als Schlüssel für den Wert, der dann die Bilddatei ist, die ich als Ressource eingebunden habe.

    Das bedeutet aber, dass ich bei der Initialisierung des Dictionary 52 Codezeilen brauche...oder die eingebundenen Bilder nach dem Key benenne. Dann gehts wohl auch in einer Schleife...

    LG Uwe



  • Ja, du solltest dafür dann eine Schleife benutzen (wäre ja eigenartig, wenn du die Bilder anders als die Karten benennen würdest).
    Zusätzlich kannst du auch eine String-List (bzw. -Array) für jeweils Farbe und Wert anlegen, welches dann die Bildnamensteile bezeichnet (falls deine Enum-Namen nicht identisch dazu sind):

    List<string> ColorNames = new List<string>() { "Karo", "Herz", "Pik", "Kreuz" };
    List<string> ValueNames = new List<string>() { "7", "8," "9", "10", "B", "D", "K", "A" };
    

    Und aus diesen beiden Listen dann den Bildnamen zusammensetzen.



  • @Th69

    Meine enum für die Farbe ist genauso wie bei Dir, der enum für den Wert habe ich mit den ausgeschriebenen Zahlen/Bezeichnungen gemacht; also "Sieben" oder "Dame".
    Gerade habe ich alle 52 Bilder umbenannt in z.B. Pik_Bube.png oder Karo_Sieben.png.
    Damit werde ich nun das Dictionary problemlos befüllen können 🙂
    Und kann dann mit einem Karten-Objekt mir das Bild aus dem Dictionary besorgen.
    Nochmals vielen Dank an Euch beide!

    LG Uwe



  • Hallo uhomm,

    eine derartige Umsetzung der alten "Cards.dll" aus WIndows nach C# habe ich im Jahr 2010 schon einmal erstellt.

    Den Code habe ich leider nicht mehr zur Hand, aber die Bibliothek kannst du unter https://www.mycsharp.de/wbb2/thread.php?threadid=82049&hilight=cards+dll finden.

    Ich habe auch nichts dagegen, wenn du sie durch einen Decompiler jagst. - Eventuell findest du darin ja noch Anregungen.



  • @uhomm sagte in C#-Klasse kapselt Spielkarte mit einem Bild:

    Die Klasse sollte möglichst so sein, dass man sie ohne Änderungen sowohl in einem Konsolen- als auch in einem GUI Projekt verwenden kann. In der Konsole kann man dann das Bild nicht nutzen.

    vorschlag zur nächsten version: in der konsole das bild als ascii-art anzeigen. 🙂



  • @inflames2k sagte in C#-Klasse kapselt Spielkarte mit einem Bild:

    eine derartige Umsetzung der alten "Cards.dll" aus WIndows nach C# habe ich im Jahr 2010 schon einmal erstellt.

    ich habe zwar keine ahnung von c#, aber ich wette, die cards.dll lässt sich auch von c# aus nutzen.



  • Clever, und das zeigst du mir ab WIndows 7. 😉



  • @inflames2k sagte in C#-Klasse kapselt Spielkarte mit einem Bild:

    Clever, und das zeigst du mir ab WIndows 7. 😉

    die dll aus dem netz saugen: https://fix4dll.com/cards_dll
    🙂



  • Egal, kommen wir zum Eingangsthema zurück.

    @uhomm
    Da du ja selbst schon schreibst, dass die Klassen unabhängig von der GUI sein sollen würde ich davon, wie andere vor mich auch schon, abraten die Grafiken mit in die Klasse aufzunehmen.

    Das wäre dann übergeordnete Logik, wie die Darstellung zu erfolgen hat und hat dann in der Klasse nichts zu suchen.


Anmelden zum Antworten