Anmerkungen zu Code

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Joe Silencio
User
Beiträge: 2
Registriert: Donnerstag 28. Juni 2007, 18:24

Donnerstag 28. Juni 2007, 19:11

Hallo allerseits
Ich habe vor ein paar Stunden begonnen Python zu lernen und dachte mir da schreib ich doch mal was. Nur bin ich mir überhaupt nicht sicher ob ich das auch richtig mache.

Ein kleines PokerSpiel:
es enthält Karten (Card), welche eine Farbe und Höhe haben (Suit,Rank)
Es gibt ein Deck von Karten

Folgendes:
Mache ich die Sache richtig. Damit meine ich kann man das besser machen. zb von wegen Typsicherheit usw,

Bin für alle Anregungen und Bemerkungen froh

thx

Code: Alles auswählen

class Rank:
    rank = ["one","two","three","four"]

class Suit:
    suit = ["HEART", "DIAMOND", "CLUB", "SPADE"]

class Card:
    
    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit
    
    def __string__(self):
        return self.suit +" "+ self.rank

Code: Alles auswählen

from card import Rank
from card import Suit
from card import Card

class Deck:
    def __init__(self):
        self.deck = []
        for s in Suit.suit:
            for r in Rank.rank:
                self.deck.append(Card(r,s))

    def shuffle(self):
        pass

    def deal(self):
        return self.deck.pop()
        
    def burn(self):
        self.deck.pop()
    
    def __string__(self):
       for c in self.deck:
           print c.__string__()


class HandRank:
    handRank = ["HIGH", "PAIR", "TWOPAIR", "THREEOFAKIND", "STRAIGHT", "FLUSH", "FULLHOUSE", "FOUROFAKIND", "STRAIGHTFLUSH"]
    

class EvaluateHand:
    
    def isFlush(self, hand):
        test = [0,0,0,0]
        
        for card in hand:
            if(card.rank == "HEART"):
                test[0] += 1
            elif(card.rank == "DIAMOND"):
                test[1] += 1
            elif(card.rank == "CLUB"):
                test[2] += 1
            elif(card.rank == "SPADE"):
                test[3] += 1
            else:
                print "Suit error"
        
        for i in test:
            if(i >= 5):
                return True
        
        return False
Test Code:

Code: Alles auswählen

from Deck import EvaluateHand
from Deck import Deck
from card import Card
temp = [Card("HEART", "one"),Card("SPADE", "one"),Card("SPADE", "one"),Card("SPADE", "one"),Card("SPADE", "one")]
e = EvaluateHand()
print e.isFlush(temp)
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Donnerstag 28. Juni 2007, 20:08

Joe Silencio hat geschrieben:Ich habe vor ein paar Stunden begonnen Python zu lernen und dachte mir da schreib ich doch mal was. Nur bin ich mir überhaupt nicht sicher ob ich das auch richtig mache. Ein kleines PokerSpiel
Hallo Joe Silencio!

Willkommen im Python-Forum!

Erst begonnen und schon mitten in der Objektorientierten Programmierung drinnen. -- Auch nicht schlecht. 8)

Wie auch immer. Es gibt natürlich ein paar Punkte die mir aufgefallen sind.

Wenn du die Methode statt ``__string__`` ``__str__`` nennst, dann brauchst du sie nicht mehr explizit aufrufen. Immer dann, wenn versucht wird, aus der Klasseninstanz einen String zu machen, wird im Hintergrund ``__str__`` aufgerufen.
Z.B. bei ``str(card)`` oder bei ``print card``.

Das Verteilen der Klassen auf so viele Dateien ist für Python untypisch. Es macht den Code unnötig komplizierter. Wenn eine Klasse direkt zum Hauptprogramm gehört und eigentlich von anderen Programmen nicht eigenständig genutzt werden soll, dann gibt es keinen Grund, die Klasse außerhalb des Hauptmoduls unterzubringen.

Die Klassen "Rank" und "Suite" enthalten (im Moment) nur jeweils eine Liste. Du könntest diese Klassen entweder komplett entsorgen und nur Listen verwenden oder (um weiter im streng objektorientierten Stil zu bleiben) z.B. von ``list`` erben lassen.

Code: Alles auswählen

# Extremst objektorientiert
class Ranks(list):
    def __init__(self, ranks = ["one", "two", "three", "four"]):
        list.__init__(self, ranks)

ranks = Ranks()

class Suits(list):
    def __init__(self, suits = ["HEART", "DIAMOND", "CLUB", "SPADE"]):
        list.__init__(self, suits)

suits = Suits()

print ranks
for rank in ranks:
    print rank

#--------------------------

# Oder einfach nur als Konstanten
RANKS = ["one", "two", "three", "four"]
SUITS = ["HEART", "DIAMOND", "CLUB", "SPADE"]

print SUITS
for suit in SUITS:
    print suit
Python ist sehr flexibel und passt sich ganz deiner Denkweise an.

Das hier

Code: Alles auswählen

        test = [0,0,0,0]
       
        for card in hand:
            if(card.rank == "HEART"):
                test[0] += 1
            elif(card.rank == "DIAMOND"):
                test[1] += 1
            elif(card.rank == "CLUB"):
                test[2] += 1
            elif(card.rank == "SPADE"):
                test[3] += 1
            else:
                print "Suit error"
könnte man auch so schreiben:

Code: Alles auswählen

test = [0,0,0,0]
key = {"HEART": 0, "DIAMOND": 1, "CLUB": 2, "SPADE": 3}
for card in hand:
    test[key[card.rank]] += 1
Oder so:

Code: Alles auswählen

test = {"HEART": 0, "DIAMOND": 0, "CLUB": 0, "SPADE": 0}
for card in hand:
    test[card.rank] += 1
Du verwendest in deinem Code immer wieder die gleichen Strings. Verwende Konstanten, dann kannst du dich nicht mehr verschreiben, ohne dass du es sofort bemerkst.
Z.B.:

Code: Alles auswählen

# RANKS
ONE = "one"
TWO = "two"
THREE = "three"
FOUR = "four"

RANKS = [ONE, TWO, THREE, FOUR]

# SUITS
HEART = "HEART"
DIAMOND = "DIAMOND"
CLUB = "CLUB"
SPADE = "SPADE"

SUITS = [HEART, DIAMOND, CLUB, SPADE]

test = {HEART: 0, DIAMOND: 0, CLUB: 0, SPADE: 0}
for card in hand:
    test[card.rank] += 1
Vielleicht fällt mir später noch etwas ein.

mfg
Gerold
:-)
[url]http://halvar.at[/url] | [url=http://halvar.at/elektronik/kleiner_bascom_avr_kurs/]Kleiner Bascom AVR Kurs[/url]
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
BlackJack

Donnerstag 28. Juni 2007, 21:10

Das `test`-Dictionary kann man auch mit der `dict.fromkeys()`-Methode erstellen:

Code: Alles auswählen

In [34]: SUITS = ['HEART', 'DIAMOND', 'CLUB', 'SPADE']

In [35]: dict.fromkeys(SUITS, 0)
Out[35]: {'CLUB': 0, 'HEART': 0, 'DIAMOND': 0, 'SPADE': 0}
Für Farbe und Rang könnte man eine "Enum"-Klasse verwenden. Es gibt zum Beispiel diese hier: http://www.python.org/pypi/enum/
Joe Silencio
User
Beiträge: 2
Registriert: Donnerstag 28. Juni 2007, 18:24

Freitag 29. Juni 2007, 00:48

Erst begonnen und schon mitten in der Objektorientierten Programmierung drinnen. -- Auch nicht schlecht. Cool
Thx. Bin schwer vorbelastet von anderen Sprachen...
Für Farbe und Rang könnte man eine "Enum"-Klasse verwenden.
Daran hatte ich eigentlich gedach. Leider nix in der Library gefunden. Dann hab ich mal für den Moment gelassen.

Danke allerseits. Werde bei nächster gelgenheit weiterbasteln.
MfG
Antworten