Hangman

Code-Stücke können hier veröffentlicht werden.
Antworten
Benutzeravatar
martin101986
User
Beiträge: 85
Registriert: Montag 3. Dezember 2007, 19:15
Wohnort: Steiermark, Österreich

Hallo,

da vor kurzem hier im Forum jemand an einer Hangman Umsetzung in Python versuch hat, hab ich auch mal eine geschrieben.

Das ist dabei rausgekommen:
http://paste.pocoo.org/show/96029/

Verbesserungsvorschläge, Kritiken, Anregungen sind willkommen.

Martin
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ein paar Dinge, die mir aufgefallen sind:

Es gibt `random.choice`, um ein Wort aus einer Liste von Wörtern auszuwählen. Suchst du `random.shuffle` statt des recht kompliziert aussehenden Verfahrens, 80% der Buchstaben zufällig durch _ zu ersetzen? Und `findword` ist eher `found_letters`, oder?

Statt die _ zu zählen, kannst du auch `count('_')` auf die Liste anwenden. Du willst aber eigentlich nur wissen, ob es noch welche gibt und da reicht dann ein `'_' in found_letters`. Würde ich dann auch nicht in `insertletters`machen.

Statt `end = False` würde ich `while True` und dann ein `break` benutzen. Das spart eine unnötige Variable ein. Wozu 1/2 statt J/N in der Abfrage? Das wäre doch auch nicht schwerer? Trials sind eher Gerichtsverhandlungen als Versuche. Nimm attempts. Wer `used_letters`schreibt, sollte auch `missed_letters` und nicht `missedletters` schreiben - oder umgekehrt.

Stefan
Benutzeravatar
martin101986
User
Beiträge: 85
Registriert: Montag 3. Dezember 2007, 19:15
Wohnort: Steiermark, Österreich

Hallo Stefan,

danke für dein Anregungen.

Soweit ist alles klar. Nur bei random.shuffle hat sich eine Frage aufgetan.
random.shuffle mischt mir meine Liste zufällig. Da muss ich aber ja auch erst die Liste kürzen. Kannst du mir einen kurzen in einen Beispiel zeigen wie du dir das vorgestellt hast?

Mit random.sample gibt mir von einer Liste eine bestimmte Anzahl von Elementen aus dieser Liste zurück. Ist diese Funktion nicht für so einen Zweck gedacht?

Grüße Martin
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ich dachte an sowas. Richtig elegant ist das aber auch nicht:

Code: Alles auswählen

word = "Pythonforum"
indices = range(len(word))
random.shuffle(indices)
indices = indices[:int(len(word) * .8)]
['_' if i in indices else w for i, w in enumerate(word)]
Stefan
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Hallo Martin,
bei der gegenwärtigen Hangman-Schwemme
hab ich's auch nicht länger ausgehalten.
:wink:

Etwas Geniales ist mir zu Deinem 'Prozent-Verfahren'
zwar auch nicht eingefallen, aber trotzdem
hier mal meine etwas minimalistische Version:

Code: Alles auswählen

#!usr/bin/env python

####

import random as rand

####

def hangman(answer, percent=0, placeholder='_', text='? '):

  current = get_current(answer, percent, placeholder)
  
  while placeholder in current:

    print ''.join(current)
    the_str = raw_input(text)
    if not the_str:
      continue

    the_char = the_str[0]
    current = [the_char if the_char == ans else cur \
               for cur, ans in zip(current, answer)]
  else:
    print ''.join(current)

####

def get_current(word, percent, placeholder):

  n = len(word)
  p = int(n * percent / 100.0)
  ls = [1] * p + [0] * (n - p)
  rand.shuffle(ls)
  return [w if i else placeholder for w, i in zip(word, ls)]

####
    
def main_hangman():

  opts = {'percent': 34,
          'placeholder': '_',
          'text': 'Lowercase letter? '}
  
  words = [s.lower() for s in __builtins__.__dict__ \
           if not opts['placeholder'] in s]
 
  while words:
    answer = rand.choice(words)
    hangman(answer, **opts)
    print 'You got it!'
    words.remove(answer)
   
    if not raw_input('Again? [y|n] ') == 'y':
      break
  else:
    print 'Nothing left.'
  
####
   
if __name__ == '__main__':

  main_hangman()

:wink:
yipyip
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Zu den Shebangs: Die sind alle falsch.

Eine Shebang Zeile nützt nur unter unixoiden Systemen etwas. Deswegen sollte man dort auch nur Unix Pfade reinschreiben (oder zumindest sich an Unix Notation halten wenn man schon unbedingt Windows Pfade reinschreibt, zb "c:/bla/blub" statt "C:\bla\blub", C klein.). Desweiteren müssen die Pfade absolut sein, dürfen keine Leerstellen enthalten und die Shebang Zeile muss die Erste der Datei an der ersten Stelle sein:

Code: Alles auswählen

#!/usr/bin/env python
Latin 1 gibt es afaik nur unter Unix. Unter Windows sucht ihr entweder cp1252 (Die Windows Do It Yourself and Not Invented Here Lösung) oder iso-8859-1. Und ob "latin_1" richtig geschrieben wäre weiß ich als utf8 Nutzer nicht genau, meine aber es müsste latin1 gewesen sein.
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Ja, ich hab's auch grad gesehen, da habe ich
ein '/' verschluckt, also

#!/usr/bin/env python

Kommt davon, wenn man's zwar hinschreibt,
das Programm aber trotzdem immer mit

python hangman.py

testet.

:wink:
yipyip
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

@str1442:
Zwar meintest Du wohl Martins's Code,
aber wie der Zufall so spielt...

:wink:
yipyip
Benutzeravatar
martin101986
User
Beiträge: 85
Registriert: Montag 3. Dezember 2007, 19:15
Wohnort: Steiermark, Österreich

Hallo,

@str1142:

Danke für das Info mit der shebang Zeile. Steht eindeutig in der Doku, werde ich in der Zukunft unter Windows nicht mehr verwenden.

@yipyip:

Deine Version ist finde ich etwas eleganter als meine. Hab ein paar Sachen die du finde ich besser gelöst hast in meine Variante übernommen.

Martin
Antworten