Pokerspiel und Zahlenraten

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.
chris27
User
Beiträge: 33
Registriert: Montag 15. Dezember 2008, 11:01
Kontaktdaten:

So hab den K.I. nicht ganz so schlau gemacht, wie Hyperion empfohlen hatte, weil ichs irgendwie nicht hinbekam, aber so klappts jetzt auch ganz gut, werde mal posten wie es inzwischen aussieht. Habe versucht alle Hinweise von euch umzusetzen.

Code: Alles auswählen

import random
import time
 
def zahlenraten1():
    secret = random.randint(1,1000)
    print
    print "Die gesuchte Zahl ist: ", secret
    print "_" * 35
    print
    guess1 = random.randint(1,1000)
    guess2 = random.randint(1,1000)
    guess3 = random.randint(1,1000)
    guess4 =  random.randint(1,1000)
    i = 1
    startzeit = time.time() #Zeit startet
    print """Das Programm versucht nun die Zahl zu erraten
            Bitte um einen Augenblick Geduld"""
    print "-" * 55
    while guess1 != secret and guess2 != secret and guess3 != secret and guess4 != secret:   
        zeit = int(time.time() - startzeit)  #Zeitzaehler       
    #-K.I.1-----------------------------------------------------------------------
        if guess1 > secret:
            guess1 = guess1 - 1
        if guess1 < secret:
            guess1 = guess1 + 1
    #-K.I.2-----------------------------------------------------------------------       
        if guess2 > secret:
            guess2 = guess2 -1
        if guess2 < secret:
            guess2 = guess2 +1   
    #-K.I.3-----------------------------------------------------------------------
        if guess3 > secret:
            guess3 = guess3 -1
        if guess3 < secret:
            guess3 = guess3 +1
    #-K.I.4-----------------------------------------------------------------------
        if guess4 > secret:
            guess4 = guess3 -1
        if guess4 < secret:
            guess4 = guess3 +1
    #-------------------------------------------------------------------------------        
        print "Versuch ", i, ":", "guess1\t-\t", guess1
        print "Versuch ", i, ":", "guess2\t-\t", guess2
        print "Versuch ", i, ":", "guess3\t-\t", guess3
        print "Versuch ", i, ":", "guess4\t-\t", guess4
        print "-" *30
        i += 1    
        if guess1 == secret:
            print "K.I.-1 hat die Zahl zuerst erraten"
        if guess2 == secret:
            print "K.I.-2 hat die Zahl zuerst erraten" 
        if guess3 == secret:
            print "K.I.-3 hat die Zahl zuerst erraten"
        if guess4 == secret:
            print "K.I.-4 hat die Zahl zuerst erraten"        
        
    print """Das Programm hat ", i, " Versuche gebraucht, in", zeit,   Sekunden.
   Die gesuchte Zahl war , secret"""

#-------------------------------------------------------------------------------
def zahlenraten2():
    print "Zahlenraten!"
    print "_"*10
    print
    print "Versuchen Sie die vom Programm zufaellig ausgesuchte Zahl zu erraten"
    print "-"*80
    secret = random.randint(1, 100)
    nachname = raw_input("Gib deinen Vornamen ein:")
    vorname = raw_input("Nun gib bitte deinen Nachnamen ein:")
    name = vorname + " " + nachname

    print "Hallo %s %s, schoen, dass Du hier spielen willst" % (vorname, nachname)
    startzeit = time.time() #Zeit startet
    while True:     
        try:
            guess = int(raw_input("Bitte geben Sie eine Zahl ein: "))
        except ValueError, exception:
            print exception.message
            continue       
        zeit = int(time.time() - startzeit)  #Zeitzaehler
        if guess < secret:
            print "zu tief"
        elif guess > secret:
            print "zu hoch"    
        else:
            print "Richtig, Sie haben das Spiel gewonnen"
            break             
    print u"Fuer die Aufgabe haben sie ", zeit, "Sekunden benoetigt"
    print "Danke fuers spielen %s %s" % (vorname, nachname)
print """Willkommen im Menue
Wenn sie sehen wollen wie der Computer eine Zahl erraet druecken Sie bitte die 1
Wenn Sie Zahlenraten spielen wollen druecken Sie bitte die 2 """
eingabe = int(raw_input("Geben sie eine Zahl ein: "))
if eingabe == 1:
    zahlenraten1()
if eingabe == 2:
    zahlenraten2()
werde die K.I. noch mal bearbeiten.
@Hyperion
Achja was meinst du mit Code auf modulebene, hab auch unter wiki gesucht, versteh nicht was das eigentlich ist.

Ich programmiere übrigens jetzt erst seit 3 Wochen, hab vorher nie etwas in der Richtung gemacht. Ist das Script dafür ok, oder sollte das schon wesentlich besser aussehn?
Zuletzt geändert von chris27 am Mittwoch 17. Dezember 2008, 09:00, insgesamt 1-mal geändert.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Also Du bekommst ja nicht geschimpft - manchmal mutet Kritik einfach negativ an, dabei ist das ganz normal im Lernprozess, dass man Dinge auch mal "falsch" oder wenig elegant umsetzt. Wenn man darauf reagiert will man Dir ja nur helfen :-)

Also Code auf Modul-Ebene ist folgendes:

Code: Alles auswählen

print "Hallo"
# usw.
Wenn nun jemand Deine Datei als Modul importiert, dann wird die print Anweisung ausgeführt - und das will man dann ja nicht wirklich. Oder fändest Du es gut, wenn das random-Modul erst einmal zig Sachen printen würde, bevor Du Deine Zufallszahl hast?
BlackJack

@chris27: Ich war mal so frei die eine "Trennlinie" in Deinem Quelltext auf normale Länge zu kürzen. Bei so langen Zeilen bekommen einige Leute einen vertikalen Scrollbalken im Browser für die gesamte Seite und es ist echt mühsam Beiträge zu lesen, wenn man dauernd hin und her scrollen muss.

Wenn man anfängt Namen zu nummerieren, will man meistens eine Liste benutzen. Das wäre hier bei `guess1` bis `guess4` der Fall. Damit würde der Quelltext kürzer weil man die dann "guesses" dann in einer Schleife verarbeiten kann und man auch mehr als vier verwenden in dem man einfach an der Stelle wo die Liste erstellt wird, mehr Elemenete erzeugt.

Die Bedingung in der ``while``-Schleife (Zeile 19) kann man kürzer ausdrücken: ``while secret not in (guess1, guess2, guess3, guess4):`` oder wenn man mit einer Liste arbeitet ``while secret not in guesses:``.

Es wird bei jedem Schleifendurchlauf die Zeit ermittelt, aber nur das letzte Ergebnis davon *nach* der Schleife ausgegeben.

ie KI ist ineffizient, weil nur einer der "guesses" sein Ziel erreichen kann und man kann nach dem ersten Schritt die beiden einzigen möglichen Kandidaten dafür bestimmen.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Nochmal zu deiner KI:

Hyperion meint folgendes: Eine effiziente Suchstrategie kann so aussehen, dass man als Startwert den Mittelwert des in Frage kommenden Intervalls nimmt. Nachdem man die Rückmeldung erhalten hat, ob die Zahl zu groß oder zu klein war, weiß man, in welcher der beiden Hälften des Intervalls sie liegen muss.
Dann nimmt man wieder den Mittelwert diese neuen (halb so großen) Intervalls und das Ganze wiederholt sich, bis man die gesuchte Zahl so weit eingeschachtelt hat, dass keine andere mehr übrig bleibt.

Mit dieser Methode findet man z.B. mit max. 30 Rateversuchen jede beliebige Zahl bis 1 Mrd.

(Falls der Mittelwert keine natürliche Zahl ist, muss man entsprechend runden oder abschneiden.)
chris27
User
Beiträge: 33
Registriert: Montag 15. Dezember 2008, 11:01
Kontaktdaten:

Hab den ganzen Nachmittag ander KI gesessen, aber bekomm es einfach nicht so hin wie ihr es beschrieben habt.
chris27
User
Beiträge: 33
Registriert: Montag 15. Dezember 2008, 11:01
Kontaktdaten:

Ihr werdet jetzt wahrscheinlich den Kopf schütteln, aber ich versuch grad ein Programm zu schreiben, ähnlich wie das zahlenraten nur das es ein wort raten soll :), womit man eventuell auch passwörter knacken könnte.
hab jetzt nur das Problem das mein Prog nur einzelne Buchstaben rät.
Wäre das überhaupt umsetzbar was ich wieder vorhabe, was mach ich falsch.

Code: Alles auswählen

import random



def zufallsbuchstabe():
    
    secret = "chris"
    guess = 0
    
    
    buchstaben = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"   
 

    while guess != secret:
        guess = buchstaben[random.randint(0,25)]
        print guess
    
    
    
zufallsbuchstabe()
chris27
User
Beiträge: 33
Registriert: Montag 15. Dezember 2008, 11:01
Kontaktdaten:

Ah mom so bin ich der Sache schon näher.

Code: Alles auswählen

import random



def zufallsbuchstabe():
    
    secret = "CHR"
    guess = 0
    
    
    buchstaben = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"   
 

    while guess != secret:
        guess = buchstaben[random.randint(0,25)] + buchstaben[random.randint(0,25)] + buchstaben[random.randint(0,25)] 
        print guess
    
    
    
zufallsbuchstabe()

ich müsste die K.I. so entwickeln das er ein buchstabe nach dem anderem rät.mal schauen. Bis 4 Buchstaben klappt es noch, aber das wars dann, wenn ich nicht Jahre warten will
Zuletzt geändert von chris27 am Donnerstag 18. Dezember 2008, 17:44, insgesamt 1-mal geändert.
BlackJack

Wie wär's wenn Du mal eine Sache zuende führst und nicht ständig Neues anfängst und vor allem endlich mal anfängst diese "copy'n'paste"-Programmierung durch ordentliche Schleifen zu ersetzen!?

Wenn man x mal (fast) das gleiche machen muss, dann kopiert man den Quelltext dafür nicht x mal, sondern schreibt eine Schleife.
chris27
User
Beiträge: 33
Registriert: Montag 15. Dezember 2008, 11:01
Kontaktdaten:

ja ok ok. werd das andere noch beenden, brauchte etwas abwechslung
Nergal
User
Beiträge: 72
Registriert: Montag 6. Oktober 2008, 14:02

Ich an deiner Stelle würde mir erstmal Gedanken machen wie man schnell und effektiv die Zahl (den Weg von Hyperion) / den Buchstaben findet und nicht sofort immer blind drauf lostippen.

In deinem Buchstabenfinder steckt z.B. nicht ein Hauch von Logik.
Konrad Wenzel
User
Beiträge: 15
Registriert: Freitag 3. Oktober 2008, 17:19

Als Beispiel zur dualen Suche habe ich was in hpl (Hewlett Packard) ausgegraben
und umgeschrieben:
so ein Sprung per return aus der Schleife ist nicht gerade fein, aber kurz
(hpl hat keine Schleifen, nur jmp (jump) und goto

Code: Alles auswählen

# binaere, ( oder duale) Suche
# fuer sortierte Sequenzen

def binsuch(suchW):
    global geordnetS
    hinten=len(geordnetS)   # Grenzen, aufpassen !
    mitte=hinten/2
    vorn= -1
    while(hinten - vorn) > 1:
         if suchW > geordnetS[mitte]:
            vorn=mitte
         elif suchW < geordnetS[mitte]:
            hinten=mitte
         else:
            return mitte            # Position gefunden
         mitte = (hinten + vorn)/2
    return -1                       # nicht gefunden

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

geordnetS = ('Apfel','Birne','Cocos','Dattel','Esche','Fallobst','Gurke',
      'Ha','Ih','Jot','Ka','Lehm','Moehre','Nase','Oh','Pe','Qu','Rot','Suse',
      'Te','Uuh','Vau','We','Xi','Yp','Zet')


for i in('A','Apfel','Ka','Karton','Oh','Z','Zet'):
    k= binsuch(i)
    if k != -1:
       print k, geordnetS[k]
    else:
       print i, ' nicht in g.S'

-- wn --
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ihgitt, ``global``. Alles andere als ein gutes Beispiel.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
chris27
User
Beiträge: 33
Registriert: Montag 15. Dezember 2008, 11:01
Kontaktdaten:

Kann mir bitte jemand für die K.I. die Hyperion beschrieben hat helfen. Häng schon ewig dran und komm net weiter. Bestimmt ist es noch ziemlich simple nur ich komm nicht drauf. Kleinen Tipp please :)
chris27
User
Beiträge: 33
Registriert: Montag 15. Dezember 2008, 11:01
Kontaktdaten:

BlackJack hat geschrieben:und vor allem endlich mal anfängst diese "copy'n'paste"-Programmierung durch ordentliche Schleifen zu ersetzen!?

Was meinst du mit diesem copy and paste programmierung, was ist das?
hier das?

Code: Alles auswählen

guess = buchstaben[random.randint(0,25)] + buchstaben[random.randint(0,25)] + buchstaben[random.randint(0,25)] + ...
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

chris27 hat geschrieben:Was meinst du mit diesem copy and paste programmierung, was ist das?
Wenn sich in einem Code bestimmte Teile (fast) bis aufs Haar gleichen ... :wink:

Das ist fast immer ein Zeichen schlechten Codes und lässt sich häufig durch eine Funktion oder eine geeignete Datenstruktur (Liste, Dictionary) beheben.

Das mit dem binären Suchen könnte so aussehen:

Code: Alles auswählen

from random import randrange

maximum = 1000000000
geheimzahl = randrange(maximum)

def findezahl(intervall):
    versuche = 0
    while True:
        versuche += 1
        mitte = (intervall[0]+intervall[1]) // 2
        if mitte == geheimzahl:
            return mitte, versuche
        elif mitte < geheimzahl:
            intervall[0] = mitte
        else:
            intervall[1] = mitte

zahl, versuche = findezahl([0,maximum])
print geheimzahl, zahl, versuche
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Ihgitt, ``global``. Alles andere als ein gutes Beispiel.
geordnetS wird doch gar nicht geändert. Global wird überflüssigerweise gebraucht -> Insofern ist das eine Konstante.
so ein Sprung per return aus der Schleife ist nicht gerade fein
Warum? Du suchst solange bis du die Position gefunden hast, dann springst du mit return raus. Sofern man sowas nicht exzessiv verwendet, warum nicht? Die Schleife dann auslaufen zu lassen würde doch nur mehr Ballast hinzufügen. Und mit return kann man keinen Goto Nudel Code erzeugen.
hier das?
Ja.

Code: Alles auswählen

import string
from itertools import repeat
from random import randint

def main():
    secret = "SE"
    buchstaben = string.lowercase
    tries = 0

    while True:
        guess = [buchstaben[thunk_int()] for thunk_int in repeat(lambda: randint(0, 25), len(secret))]
        tries += 1
        print guess 

        if "".join(guess) == secret.lower():
            print "Got: %s" % guess
            print "Tries: %s" % tries
            break

if __name__ == "__main__":
    main()
Wäre zum Beispiel möglich. Nur sollte man wenns schnell werden soll gleich mit Strings arbeiten, aber ich fand die LC so schön. Außerdem ist "raten" natürlich keine gute Suchmethode.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

str1442 hat geschrieben:geordnetS wird doch gar nicht geändert. Global wird überflüssigerweise gebraucht -> Insofern ist das eine Konstante.
Also schlecht und unnötig.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Dann schreibst du also entweder jede Konstante im Programm direkt in die Zeilen oder übergibst jeder Funktion jeden noch so unnötigen Parameter? Zb auch math.pi?
chris27
User
Beiträge: 33
Registriert: Montag 15. Dezember 2008, 11:01
Kontaktdaten:

Kann mir bitte jemand diesen Satz versuchen verständlich zu übersetzen:

[buchstaben[thunk_int()] for thunk_int in repeat(lambda: randint(0, 25), len(secret))]

hab sowas noch nie gesehn


und hat jemand vielleicht noch ein Tip bitte für Python challenge seite 3.
Da ist so ein Buch, weiss net was das soll. Will jetzt nicht das ihr mir laufend irgendwelche lösungen sagt, vielleicht nur kleinen Tip :), wenn jemand das Rätsel kennt
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

chris27 hat geschrieben:und hat jemand vielleicht noch ein Tip bitte für Python challenge seite 3.
Da ist so ein Buch, weiss net was das soll. Will jetzt nicht das ihr mir laufend irgendwelche lösungen sagt, vielleicht nur kleinen Tip :), wenn jemand das Rätsel kennt
Jetzt fang doch nicht noch eine Baustelle an! Was ist mit deinem Zahlenraten? Eine anständige finale Fassung hast du noch nicht gezeigt. Daran könnte man eine ganze Menge lernen, indem man es entsprechend ausbaut. Konkretes dazu wurde schon gepostet.

Wenn du das Zahlenraten nicht hinbekommst, kannst du PythonChallenge knicken! Das ist eine andere Preisklasse. Es hat auch relativ wenig damit zu tun, anständige Python Programme schreiben zu lernen. Weitaus ergiebiger ist das Project Euler.
Antworten