Python :: Aufgabe #175

3 Lösungen Lösungen öffentlich

Mischen von Spielkarten

Anfänger - Python von hollst - 14.01.2018 um 16:42 Uhr
Man schreibe eine GUI-Anwendung, die einen 52er Kartensatz mischt und die entstandene Reihenfolge anzeigt (BILD 2).
Die Anwendung soll zwei Befehlsknöpfe haben: MISCHEN und RESET. Mit RESET soll die Default-Reihenfolge angezeigt werden (BILD 1).

Einen Satz von Image-Dateien der Spielkarten könnt ihr z. B. unter http://www.nongnu.org/cardpics/cardpics.en.html herunterladen und darüber frei verfügen, sofern ihr eure Lösung nicht für kommerzielle Zwecke vermarkten wollt.

Lösungen:

vote_ok
von Mot_Sonne (910 Punkte) - 18.02.2018 um 17:49 Uhr
Quellcode ausblenden Python-Code
#if not installed PIL:
#python-m pip install PIL 

#!!!
#card_mix.py for #175 trainyourprogrammer!!! thanks hollst!
#!!!

#dir with Cards in the directory of card_mix.py
CARD_DIR="cards"
WIDTH,HEIGHT=50,100#size of the cards-adjustable!


from os import getcwd,listdir,chdir,path
from tkinter import *
from PIL import Image, ImageTk
from random import shuffle
class Cards():
    def __init__(self):
        self.fenster=Tk()
        self.fenster.title("Cards")
        Button(self.fenster,command=self.mix,text="Mix").pack(side=LEFT,expand=1)
        Button(self.fenster,command=self.reset,text="Reset").pack(side=LEFT,expand=1)
        self.frame=Frame(self.fenster)
        self.neu()
        self.reset()
        self.fenster.mainloop()
    def neu(self):
        dir=getcwd()
        
        card_dir=path.join(dir,CARD_DIR)
        
        cards=listdir(card_dir)
        self.anz=len(cards)-1
        chdir(card_dir)
        self.image_list=[]
        for card in cards:
            img=Image.open(card)
            img=img.resize(size=(WIDTH,HEIGHT))
            img=ImageTk.PhotoImage(img)
            self.image_list.append(img)
    def reset(self):
        self.make_labels(self.image_list)
    def make_labels(self,list):
        self.frame.destroy()
        self.frame=Frame(self.fenster)
        x,y=0,0
        x_max=self.anz//4
        for card in list:
            Label(self.frame,image=card).grid(column=x,row=y)
            x+=1
            if x==x_max:
                y+=1
                x=0
        
        self.frame.pack(side=BOTTOM)
    def mix(self):
        labels=[]
        for image in self.image_list:
            labels.append(image)
        
        shuffle(labels)
        self.make_labels(labels)
            
Cards()
        
vote_ok
von GateCore (50 Punkte) - 04.04.2018 um 15:20 Uhr
ich habe wxPython verwendet. Um den Code zum laufen zu bringen imagepath durch den richtigen Pfad ersetzen, möglicherweise die Fenster noch besser anpassen an Größe etc.

Ich nehme sehr gerne konstruktive Kritik und Verbesserungsvorschläge an

Quellcode ausblenden Python-Code
import wx, random, os


class Deck52(list):
    WERTE = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "Bube", "Dame", "König", "Ass"]
    FARBEN = ["Kreuz", "Pik", "Herz", "Karo"]
    images = [r"imagepath" + "\\" + d for d in
              os.listdir(r"imagepath")]

    def __init__(self):
        self.karten = [Karte(farbe, wert) for farbe in self.FARBEN for wert in self.WERTE]
        for i, karte in enumerate(self.karten):
            karte.image = self.images[i]
        list.__init__(self, self.karten)


class Karte(object):
    def __init__(self, farbe, wert, image="default"):
        self.farbe = farbe
        self.wert = wert
        self.image = image


class MyFrame(wx.Frame):
    def __init__(self, parent, title, size):
        super().__init__(parent, title=title, size=size)
        self.talon = Deck52()
        pnl2 = wx.Panel(self, pos=(0, 0), size=(1200, 60))
        shuffleButton = wx.Button(pnl2, id=wx.ID_ANY, label="Shuffle", pos=(5, 10), size=(80, 40))
        resetButton = wx.Button(pnl2, id=wx.ID_ANY, label="Reset", pos=(85, 10), size=(80, 40))
        self.Bind(wx.EVT_BUTTON, self.onReset, resetButton)
        self.Bind(wx.EVT_BUTTON, self.onShuffle, shuffleButton)
        self.panel1()
        self.Show(True)

    def panel1(self):
        self.pnl = wx.Window(self, pos=(0, 60), size=(1400, 540), style=wx.BORDER_SIMPLE)
        self.pnl.SetBackgroundColour((20, 200, 20))

        xpos = lambda x: (x * 80) % 1040
        for i, karte in enumerate(self.talon):
            ypos = 0
            if 12 < i < 26:
                ypos = 125
            elif 25 < i < 39:
                ypos = 250
            elif 38 < i:
                ypos = 375
            picture = wx.Image(karte.image, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
            wx.StaticBitmap(self.pnl, -1, picture, (xpos(i), ypos), (picture.GetWidth(), picture.GetHeight()))
        self.Refresh()

    def onReset(self, e):
        self.talon = Deck52()
        self.panel1()

    def onShuffle(self, event):
        random.shuffle(self.talon)
        self.panel1()


if __name__ == '__main__':
    app = wx.App(False)
    frame = MyFrame(None, "Shufflethis", size=(1200, 700))
    app.MainLoop()

vote_ok
von Gisbert5020 (830 Punkte) - 11.06.2018 um 09:50 Uhr
Quellcode ausblenden Python-Code
import sys
import random
from PyQt5.QtWidgets import QApplication, QPushButton, QWidget, QLabel, QSpacerItem,\
                            QGridLayout, QHBoxLayout, QVBoxLayout, QSizePolicy
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import Qt
LISTE = []
SORTLISTE=[]

 
class Fenster(QWidget):
    
    def __init__(self, parent=None):
        super(Fenster, self).__init__(parent)
        self.kartenLaden()
        self.initUI()         

    def initUI(self):
        self.hlayout = QHBoxLayout()
        self.glayout = QGridLayout()
        self.glayout.setContentsMargins(5, 5, 5, 5)
        self.glayout.setSpacing(3)
        self.vlayout = QVBoxLayout()
        self.label =[] 
        
        for i in range(52):
                self.label.append(QLabel(self))
                self.label[i].setObjectName('label'+str(i))
                myPixmap = QPixmap(SORTLISTE[i])
                self.label[i].setPixmap(myPixmap)
                self.label[i].setScaledContents(True)
                self.label[i].setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
                j = i//13
                k = i%13
                self.glayout.addWidget(self.label[i],j,k)

        self.sortieren = QPushButton("Karten sortieren")
        self.sortieren.setFixedWidth(100)
        self.vlayout.addWidget(self.sortieren)
        self.mischen = QPushButton(" Karten mischen ")      
        self.mischen.setFixedWidth(100)
        self.vlayout.addWidget(self.mischen)
        self.spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
        self.vlayout.addItem(self.spacerItem)
        self.hlayout.addLayout(self.glayout)
        self.hlayout.addLayout(self.vlayout)
        self.setLayout(self.hlayout)

        self.sortieren.clicked.connect(self.kartenSortieren)
        self.mischen.clicked.connect(self.kartenMischen)
               
    def kartenLaden(self):
        for i in range(56):
            if i == 10 or i==24 or i==38 or i==52:
                continue
            if i < 10:
                LISTE.append('cardpics/' + '0' + str(i) + '.png')
            else:
                LISTE.append('cardpics/' + str(i) + '.png')
        SORTLISTE.extend(LISTE[0:26])
        SORTLISTE.extend(LISTE[39:52]) 
        SORTLISTE.extend(LISTE[26:39])

    def kartenSortieren(self):
        for i in range(52):
            myPixmap = QPixmap(SORTLISTE[i])                                      
            self.label[i].setPixmap(myPixmap)
            
    def kartenMischen(self):
        random.shuffle(LISTE)
        for i in range(52):
            myPixmap = QPixmap(LISTE[i])                                       
            self.label[i].setPixmap(myPixmap)
        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    fenster=Fenster()
    fenster.show()
    app.exec_()