Mein erstes Würfelspiel - was ist alles unpythonisch?

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Das mit den Adressbüchern macht ja jeder :lol:
Habe mal versucht ein Wuerfelspiel zu schreiben - es funktioniert mal soweit, doch ein Computergegner wäre nett und eine Funktion zum Auswerten der Gesamtspielzüge. Was ist alles nicht so pythonisch und was soll ich ändern ?

Code: Alles auswählen

############################################################

# Wuerfelspiel                                             #
# Der Sinn des Spieles ist es die 4 und die 2 zu bekommen  #
# Alle weiteren Wuerfelaugen werden gezaehlt               #  
# Gewinner ist der mit den meisten Augen                   #
############################################################
#! /usr/bin/python

# -*- coding: iso-8859-1 -*- 
import random
def erzeuge_wurf(anzahl_wuerfel):
    wurf = list()
    for wuerfel in range (anzahl_wuerfel):
        wurf.append(random.randint(1,6))
    return wurf


def werfen(name, spieler_zug):
    anzahl_wuerfel = 5
    wurf = 1
    while anzahl_wuerfel > 0:
        test = 0
        prompt = name + ' mache den ' + str(wurf) + ' Wurf'
        print '=' * 30
        raw_input(prompt)
        spieler_wurf = erzeuge_wurf(anzahl_wuerfel)
        print '=' * 30
        print wurf, ' Wurf ', '|'.join(str(i) for i in spieler_wurf)
        print '=' * 30
        while test == 0:
            prompt = 'uebernehmen? ' + '|'.join(str(i) for i in spieler_zug) + '| '
            auswahl = raw_input(prompt)
            if auswahl != '':
                wahl = auswahl.split('.')
                for wuerfel in wahl:
                    try:
                        if int(wuerfel) in spieler_wurf:
                            spieler_zug.append(wuerfel)
                            anzahl_wuerfel -= 1
                            test += 1
                        elif int(wuerfel) not in spieler_zug:
                            print 'Wuerfel', wuerfel, 'nicht vorhanden'
                    except ValueError:
                        continue
        wurf += 1
    
                
def auswertung(spieler, spiel_zuege):
    for zug, name in zip(spiel_zuege, spieler):
        ergebnis = ''
        if '4' in zug and '2' in zug:
            zug.remove('2')
            zug.remove('4')
            for augen in zug:
                ergebnis += '+' + augen
            print name, 'hat', eval(ergebnis), 'Punkte'
        if len(zug) > 3:
            print name, 'hat 0 Punkte'


def spielen():
    spieler = list()
    spiel_zuege = list()
    spieler_zug = list()
    while True:
        try:
            anzahl = int( raw_input('Wieviele Spieler ?'))
            break
        except ValueError:
            continue
    for zaehler in range(anzahl):
        prompt = 'Name des ' + str(zaehler + 1) + ' Spielers:' 
        name = raw_input(prompt)
        spieler.append(name)
    while True:   
        for name in spieler:
            werfen(name, spieler_zug)
            spiel_zuege.append(spieler_zug)
            spieler_zug = list()
        auswertung(spieler, spiel_zuege)
        spiel_zuege = list()
        spieler.reverse()
        auswahl = raw_input('Noch eine Runde ? (b)eenden').upper()
        if auswahl == 'B':
            break
             
        
def main():
    while True:
        print 
        print '____(S)tart von 42 + 18______'
        print '____(B)eenden des Spieles____'
        print 
        
        auswahl = raw_input('Auswahl:').upper()
        if auswahl == 'S':
           spielen()
                
        if auswahl == 'B':
            break


if __name__ == '__main__':
    main()
gruss und dank frank
Zuletzt geändert von kaytec am Mittwoch 13. Juni 2007, 19:38, insgesamt 1-mal geändert.
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Naja was Pythonic ist und was nicht kann ich vermutlich selbst noch nicht richtig beurteilen.
Was ich dir aber sagen kann ist das der Shebang in die erste Zeile gehört ;)

Anstelle der Kommentare könntest du Docstrings verwenden.
Zuletzt geändert von veers am Dienstag 12. Juni 2007, 23:44, insgesamt 1-mal geändert.
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Aha Shebang ? Was ist das ?

gruss frank
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

kaytec hat geschrieben:Aha Shebang ? Was ist das ?

gruss frank
http://en.wikipedia.org/wiki/Shebang_%28Unix%29

Variablen etc. am besten in englisch benennen.
Zuletzt geändert von veers am Dienstag 12. Juni 2007, 23:50, insgesamt 1-mal geändert.
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Ach so ! Das hat DrPython gemacht und ich habe die Beschreibung später eingefügt. Was bringt dieser Shebang eigentlich ?

gruss und dank an veers
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

kaytec hat geschrieben:Ach so ! Das hat DrPython gemacht und ich habe die Beschreibung später eingefügt. Was bringt dieser Shebang eigentlich ?

gruss und dank an veers
Steht doch in der Wikipedia:
Wikipedia Zeile 1 hat geschrieben:In computing, a shebang (also called a hashbang or hashpling) refers to a pair of characters "#!" that, when used as the first two characters on the first line of a script, causes Unix-like operating systems to execute that script using the interpreter specified by the rest of that line.

Code: Alles auswählen

if auswahl == 'B':
Daraus könntest du auch

Code: Alles auswählen

elif auswahl == 'B':
machen.
Dann wird nur verglichen wenn es nicht A war.
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Das mit den Bezeichnern ist so eine Sache - in Englisch wuerde sie keiner verstehen, da ich der englischen Sprache nicht wirklich mächtig bin und welcher User dieses Forums hat Interesse an meinem code ?!

gruss und dank frank
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Die Wahl der Würfel geht über '.' - so kann man es auch ausprobieren.
BlackJack

Sieht im grossen und ganzen gut aus. Ich muss natürlich trotzdem meckern. Liegt wohl in meinen Genen. :-)

Warum ist `spieler_zug` ein Argument von `werfen()`? So ist man darauf angewiesen, dass immer eine leere Liste von aussen übergeben wird, damit die Funktion korrekt läuft. Besser wäre es das zu entkoppeln und `spieler_zug` als Rückgabewert von `werfen()` zu benutzen. Man könnte die äussere ``while``-Schleife dann zum Beispiel auch mit der Länge des Ergebnisses verknüpfen.

Code: Alles auswählen

while len(spieler_zug) < anzahl_wuerfel:
    # ...
    spieler_wurf = erzeuge_wurf(anzahl_wuerfel - len(spieler_zug))
    # ...
Dann braucht man `anzahl_wuerfel` in der Funktion auch nicht mehr verändern.

`test` ist ein relativ nichtssagender Name. Mir fällt allerdings so auf die Schnelle auch kein besserer ein. Dann sollte man aber wenigstens Kommentieren was die Variable macht. Eigentlich ist es ja ein Flag, also wären `True` und `False` besser geeignet als Zahlen. Oder man könnte das Flag durch die alte Anzahl der bereits gewählten Würfel ersetzen. Also ungefähr so:

Code: Alles auswählen

        alte_anzahl = len(spieler_zug)
        while len(spieler_zug) == alte_anzahl:
            # ...
Dann wird aus der Bedingung schon klar: Aha, die Schleife wird erst verlassen, wenn sich die Anzahl der ausgewählten Würfel verändert. Auch hier hätte man in der Schleife wieder eine explizite Variablenänderung gespart.

Bis zu `auswertung()` war das Programm ja recht schön, aber `eval()` zu benutzen um eine einfache Summe zu bilden!? Statt in der Schleife die Augenzahlen mit '+' zu einer Zeichenkette für `eval()` zu verbinden, hätte man auch die Zahlen in der Schleife aufaddieren können. Oder gleich ohne Schleife mit der `sum()`-Funktion.

Das ``if len(zug) > 3:`` ist überflüssig, weil die Bedingung an dieser Stelle eigentlich nie wahr sein kann. Das ist einfach der ``else``-Zweig zum vorherigen ``if``.

Die Trennlinien könnte man anders gestalten. Die Würfe könnte man weiterhin mit '=' trennen, aber innerhalb eines Wurfs (Aufforderung, Wurfergebnis, Übernahme) könnte man '-' nehmen. Das würde mehr übersicht schaffen.

Das man den Wurf selbst erst mit einer Leereingabe anstossen muss, ist ein IMHO überflüssiger Tastendruck pro Wurf. Und wenn nur noch ein Würfel da ist, könnte man sich auch die Auswahl vom Spieler ersparen.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

kaytec hat geschrieben:Das mit den Bezeichnern ist so eine Sache - in Englisch wuerde sie keiner verstehen, da ich der englischen Sprache nicht wirklich mächtig bin
Wäre also eine super Gelegenheit zum üben.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Das letzte mal Englisch hatte ich vor 21 Jahren :oops:

Hast schon recht - man sollte das ganze Leben lernen !

Für die alltägliche Konversation reicht mein Englisch schon - hoffe ich mal - musste es schon lang nicht mehr gebrauchen, doch eindeutige Bezeichner - naja!

gruss frank
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

So habe es mal nach den Tips von BlackJack geändert und hoffe mal so war es auch gemeint. :?

http://www.ubuntuusers.de/paste/11707/

OH - es fehlt in der Funktion werfen() --> wurf += 1

gruss und dank frank
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

So - nun habe ich einen Computergegner eingebaut !

http://www.ubuntuusers.de/paste/11735/

gruss frank
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Habe irgendwie ein Fehler drin ?!
if anzahl == 0:
spieler.append(random.choice(computer_gegner_namen))
spieler.append(random.choice(computer_gegner_namen))
Habe mal 2 Computergegner spielen lassen und der eine hatte einmal 20 Punkte ?

Es sollte nach if doch elif kommen oder ?

Beim code des Computergegners enstehen dadurch aber verschiedene Ergebnisse ?

gruss frank
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Habe den Computergegner verändert !

Code: Alles auswählen

def computer_gegner():
    anzahl_wuerfel = 5
    spiel_zug = []
    while len(spiel_zug) < anzahl_wuerfel:
        spiel_wurf = erzeuge_wurf(anzahl_wuerfel - len(spiel_zug))
        while True:
            test_spiel_zug = len(spiel_zug)
            if 2 in spiel_wurf and 2 not in spiel_zug:
                spiel_zug.append(2)
                if 5 in spiel_wurf or 6 in spiel_wurf:
                    spiel_zug.append(max(set(spiel_wurf)))
            if 4 in spiel_wurf and 4 not in spiel_zug:
                spiel_zug.append(4)
                if 5 in spiel_wurf or 6 in spiel_wurf:
                    spiel_zug.append(max(set(spiel_wurf)))
            if test_spiel_zug != len(spiel_zug):
                break
            spiel_zug.append(max(set(spiel_wurf)))
            break     
    spiel_ergebnis = auswertung (spiel_zug)
    return spiel_ergebnis
gruss frank
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Habe die Auswertung der Spielzüge verändert !

http://www.ubuntuusers.de/paste/11941/

gruss frank
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Doppelnamen sind jetzt nicht mehr möglich und ich habe eine Gesamtauswertung eingefügt . Die Gesamtauswertung stammt nicht von mir, die hat Michael Schneider hier im Forum gebastelt

http://www.ubuntuusers.de/paste/12061/

gruss frank
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Nun eine Version mit eigener Gesamtwertung !

http://www.ubuntuusers.de/paste/12098/

gruss frank
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Habe den code nach BlackJack noch verändert!

http://www.ubuntuusers.de/paste/12253/

gruss frank
Antworten