2014-02-05 66 views
2

我正在編寫一個蟒蛇遊戲作爲大學項目的一部分,我試圖用string.replace(舊的,新的)用空格替換空格(_)。雖然不是使用實際的字符串,但我正在嘗試爲「舊」和「新」使用變量。這是我到目前爲止已經得到了這一點:如何使用迭代和變量替換字符串中的字符? (Python)

if validGuess == 'true': 
    if guess in word: 
     for letter in word: 
      if letter == guess: 
       word.replace(letter, guess) 
      else: 
       missNum = (missNum + 1) 
    else: 
     tryNum = (tryNum - 1) 

但是,它不工作。我沒有得到任何錯誤,它根本不會取代空白。

我在這裏做錯了什麼?有沒有更好的方法來實現我正在做的事情?

- 編輯 -

我試圖執行@Peter西湖的解決方案(這在我看來,最優雅的),但我遇到了一個問題。我有一段代碼將隨機選擇的字轉換爲下劃線:

#converting word to underscores 
wordLength = len(word) 
wordLength = (wordLength - 1) 
print(wordLength) #testing 
for i in range(0,wordLength): 
    wordGuess = (wordGuess + '_') 
print(wordGuess) 

而這似乎工作正常。這裏是字母替代代碼:

if validGuess == 'true': 
    wordGuess = ''.join([letter if guess == letter else wordGuess[pos] 
         for pos, letter in enumerate(word)]) 

    if guess not in word: 
     tryNum = (tryNum - 1) 

    print(wordGuess) 

然而,這裏是輸出:

Guess a letter: a 
test 
Traceback (most recent call last): 
    File "G:\Python\Hangman\hangman.py", line 60, in <module> 
    for pos, letter in enumerate(word)]) 
    File "G:\Python\Hangman\hangman.py", line 60, in <listcomp> 
    for pos, letter in enumerate(word)]) 
IndexError: string index out of range 

字符串索引超出範圍?那是什麼意思?

+0

我不知道你的情況,'如果信==猜'你需要在這裏取代什麼? –

+0

你可以把你的輸入和預期的輸出。 –

+0

「字符串索引超出範圍」意味着您試圖從字符串末尾獲取字母,這是因爲您從wordLength中減去1。 'range(x,y)'給出從x到y-1的所有數字,所以不需要再次減1。更簡單的方法是:'wordGuess ='_'* len(word)'。 –

回答

1

str.replace()回報新的字符串,存儲新值:

word = word.replace(letter, guess) 

Python中的字符串是不可改變的,不能就地改變。

但是,您用同樣的值代替letter; letter == guess只有在兩者都是相同字符時才爲真。

我會保持獨立的一組猜出正確答案的字母來代替,每一次重建顯示下劃線和正確的猜測:

correct_guesses = set() 
incorrect_guesses = set() 

if guess in correct_guesses & incorrect_guesses: 
    print('You already guessed that letter') 

elif guess in word: 
    # correct guess! 
    correct_guesses.add(guess) 
    display_word = ''.join(char if char in correct_guesses else '_' for char in word) 

else: 
    # incorrect guess! 
    incorrect_guesses.add(guess) 
    print('Oops, incorrect guess!') 
    missNum += 1 
+0

只是一個猜測,因爲我不是downvoter,但是:你在OP的代碼中發現了一個小錯誤,但是整個算法也是錯誤的,你的回答沒有解決這個問題。這可能是更好的評論。 –

+0

Hrm,我的意思是回到這篇文章展開。我在多個帖子上收到了多個讚譽,所以我實際上假設了一個連續的downvoter在工作。 –

+0

我有一個黑名單,以前猜到的字母已經在代碼的不同部分,但我喜歡你在這裏所做的,我可能需要考慮單獨存儲猜測的字母...... –

0

更換字母用相同的猜測是不打算做任何事情!我想你想在猜出的字母出現的單詞中找到該位置,並將該位置中的_替換爲該字母。爲此,你需要找到每個字母出現的位置,例如使用index()方法。

例如,更換猜測中第一次出現:

# Illustration of the principle, not the complete answer. 

word = 'faq' 
display = '___' 

# Put in a loop, one iteration for each guess input. 
guess = 'a' 
display = ''.join([letter if guess == letter else display[pos] 
        for pos, letter in enumerate(word)]) 
print display 

,它將打印_a_

+0

我喜歡這個解決方案...但我似乎無法按照我喜歡的方式工作。檢查OP的詳細信息...並非常感謝! –

1

我想我明白你在這裏得到什麼。

我可能會在現場重建這個單詞,而不是持久化字符串,並單獨保留測試的字母。當用戶嘗試新的角色,使兩項檢查:

  1. 若見猜測字符已經已經猜到了:if guess in tried。如果是這樣,不管你喜歡(懲罰還是忽略),但不要將該字符添加到已嘗試的字符列表中。

  2. 如果不是,請查看該字符是否在目標字詞中:elif guess in word。如果不是,則評估一些懲罰並將猜測添加到已嘗試的字符列表中。

  3. 對於任何其他結果:else。將猜測添加到已嘗試的字符列表中。

要顯示用戶的進度,請輸入空白字符串。像你一樣,一次完成目標詞:for char in word。但是不要試圖修改一個現存的字符串,只要將字符添加到空字符串的末尾(如果它位於已嘗試的字符串中),或者如果不是,則添加下劃線:show += char if char in tried else "_"。一旦for循環用盡,顯示你有什麼!

或者,使用.join,其迭代器略有不同:show = "".join(char if char in tried else '_' for char in word)。它會遍歷整個單詞,保存每個字母(如果它在你嘗試過的字符串中),或者如果不是,則用下劃線代替,把任何在""之間的東西(或者沒有,如果你把它保留爲"")。不過,看起來你已經知道了。

在完全重寫代碼的危害,這是它會是什麼樣子:

## init 
word = "mauritius" # the word you're looking for. I chose this one. 
tried = str() # initialize a list of tested characters 
tryNum = 3 # however many wrong guesses the user gets 

    ... 

    ## in your run loop... 
if tryNum: # evaluates 0 as Fasle, if you didn't already know 
    guess = UserInput() # some means to get the guess from the user; a single-character string. 

    if guess in tried: 
     print "Tried that letter already!" 
    elif guess not in word: # the letter hasn't been tested yet, but isn't in the word, either. 
     print "Wrong! %d guesses left!" % tryNum 
     tryNum -= 1 
     tried += guess 
    else: # the guess is new (not tried) and it's valid (in the word) 
     tried += guess 

    show = str() # this is the string you will display. make a blank one each time. 
    for char in word: 
     show += char if char in tried else "_" # if the character has been tried, add it to the output. Otherwise, an underscore. 
    print show # display the word so far 

    if show == word: 
     print "You win!" # Congratulations! You hung a man. 

else: # Out of tries; the convict lives another day. 
    print "Game Over!" # I am not sure how committed to this vocabulary-based execution you really are... 

您可以把if tryNum:while tryNum:,應該由自己所有的工作,初始化後。如果你這樣做,你可以用continue s和break s做些有趣的事情,但這有點超出了你的問題的範圍。

您也可以在下一個示例中將show = str()for char in word:替換爲.join單例。將''.join(..)更改爲' '.join(..)以在字符/下劃線之間添加空格!

這個壓縮版本可能有點少即是Python的:「我在做什麼錯」

# post-init... 
if tryNum: 
    guess = UserInput() 
    if guess in tried: pass 
    elif guess not in word: 
     print "Wrong! %d guesses left!" % tryNum 
     tryNum -= 1 
     tried += guess 
    else: tried += guess 
    show = ''.join(char if char in tried else '_' for char in word) 
    if show == word: print "You win!" 
else: print "Game Over!" 

這不回答你的第一個問題但我認爲這可能是一個更好的方式去實現你的目標?這對您來說可能會更容易維護和擴展。

注意:如果您想自行嘗試此功能,請繼續使用UserInput()代替str(raw_input("Guess a letter!"))[0]

+0

我想我不必太擔心做家庭作業,因爲我遲了十個月纔回答這個問題......我希望這裏的一些想法仍然對你(和未來的觀衆)有用。 .. – Augusta

+0

嘿,謝謝你的迴應。哈哈,是的,這項任務早已過去!但是,在這方面你確實有一些很好的觀點,所以再次感謝 - 我相信未來看到這個的人會找到它的用處。 我設法讓程序在最後工作得很好,如果有人感興趣,我可以在這裏發佈它? –

+0

@ James.D.Wood您可以將它作爲答案張貼,當然!只要確保你將它作爲正確的答案,而不僅僅是一個工作代碼塊! ;) – Augusta