0
from graphics import *
import random 

def hangman(word):
    returnStuff = {'again':0, '1st':1}

    alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
                'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

    win = GraphWin("Hangman", 800, 550)
    win.setBackground("yellow")

    titleText = Text(Point(400,50), 'HANGMAN')
    titleText.setSize(24)
    titleText.setStyle('bold')
    titleText.draw(win)

    #Building the hangman base
    base = Line(Point(120,350),Point(230,350))
    base.draw(win)
    stand = Line(Point(175,350),Point(175,150))
    stand.draw(win)
    stand2 = Line(Point(175,150),Point(250,150))
    stand2.draw(win)
    stand3 = Line(Point(250,150),Point(250,180))
    stand3.draw(win)

    #drawing the empty lines for the word
    x1 = 150
    x2 = 180
    l = 0
    print(word)
    while l< len(word):
        wordLine = Line(Point(x1, 420),Point(x2,420))
        wordLine.draw(win)
        l+=1
        x1+=40
        x2+=40

    guessCounter = 0
    textCheck = 0
    invalidText = Text(Point(600,100), 'You did not enter a valid letter.')
    invalidText.setTextColor('red')
    indexes = []
    while guessCounter < 6:
        #text entry box
        textEntry = Entry(Point(600,180),10)
        textEntry.draw(win)
        guessText = Text(Point(600,150), 'Guess a letter:')
        guessText.draw(win)
        #user has to click this box to confirm the letter
        enterBox = Rectangle(Point(580,200), Point(620,220))
        enterBox.setFill('white')
        enterBox.draw(win)
        clickText = Text(Point(600,210), 'Enter')
        clickText.draw(win)

        click = win.getMouse()
        x = click.getX()
        y = click.getY()

        if 580 < x < 620 and 200 < y < 220:
            guess = textEntry.getText().lower().strip()
            if guess not in alphabet:
                if textCheck == 0:
                    invalidText.draw(win)
                    textCheck = 1

            else:
                if textCheck == 1:
                    invalidText.undraw()
                    textCheck = 0
                for letter in word:
                    if letter == guess:
                        indexes.append(word.index(guess))
                        print(indexes)


    win.getMouse()

    win.close()

    return returnStuff 

#list with various words pertaining to nanotechnology
words = ['nanotechnology', 'science', 'nanometre' , 'strength', 'chemistry',
         'small', 'molecule', 'light' , 'weight', 'technology', 'materials',
         'property', 'physics', 'engineering', 'matter', 'waterloo', 'nanobot',
         'reaction', 'structure', 'cells']

#picks a random word from the list
word = random.choice(words)

#this variable ensures it opens the game the first time
initialCall = 1
#stores the returnValue for the first call
returnValue = hangman(word)

#sets the initialCall to 0 after first call 
if returnValue['1st']==1:
    initialCall=0

#Calls the game function again if user wishes
while initialCall == 1 or returnStuff['again'] == 1:
    returnValue = hangman(word)

我正在用 Python 图形制作 Hangman。我为巨大的代码块道歉,一切正常,我只是认为它一定很有用。我关心的代码部分是这样的:

            else:
                if textCheck == 1:
                    invalidText.undraw()
                    textCheck = 0
                for letter in word:
                    if letter == guess:
                        indexes.append(word.index(guess))
                        print(indexes)

当用户的字母猜测在字母表中时,将执行此代码块,然后我遍历所选单词中的每个字母,如果在任何时候单词中的字母与猜测字母相同,我存储索引那个字母在一个空列表中,所以我可以用它来告诉计算机在哪里绘制空行上的字母。

它工作正常,除了单词中有重复的字母。例如,工程有 3 个 es。不幸的是, .index() 仅记录字母第一次出现时的索引,而忽略其他字母。解决这个问题的方法是什么,所以我可以获得该单词中所有 3 个 es 的索引,而不是仅第一个 e 的 3 个索引。出于测试目的,我在控制台上打印了选择的单词和索引列表,这样我就可以看到发生了什么,所以我实际上不必猜测一个字母。

4

1 回答 1

0

你可以做这样的事情

def indexes(word,letter):
    for i,x in enumerate(word):
        if x == letter:
            yield i

测试

>>> list( indexes("engineering","e") )
[0, 5, 6]
>>> 

这个函数是一个生成器,这是一个惰性函数,它只在被要求时才给出结果,为了获得你使用的单个结果next,函数会执行到第一个yield结果,然后返回结果并停止执行并记住它的位置,直到另一个对 next 的调用在女巫点恢复执行中从前一点执行直到下一个产量,如果不再引发 StopIteration,例如:

>>> word="engineering"
>>> index_e = indexes(word,"e")
>>> next(index_e)
0
>>> print(word)
engineering
>>> next(index_e)
5
>>> next(index_e)
6
>>> next(index_e)
Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    next(index_e)
StopIteration
>>> 

要使用此函数的结果更新列表,可以使用 extend 方法

>>> my_list=list()
>>> index_e = indexes(word,"e")
>>> my_list.extend( index_e )
>>> my_list
[0, 5, 6]
>>> 

生成器用于它们的结果只是其他东西的中间步骤的情况,因为它们使用的内存量最少,但在这种情况下,您可能想要整个东西,所以将它用作第一个示例或重新制作函数以返回列表首先像这样

def indexes(word,letter):
    result = list()
    for i,x in enumerate(word):
        if x == letter:
            result.append(i)
    return result

对不起,如果我把你和收益的事情混淆了。

于 2016-01-10T21:34:36.977 回答