How can I improve my gamer gaming code?

0

What tips would you give to improve this gaming code in Python? In the "course" I'm doing in Python I have not yet learned how to use string methods yet. It's a very simple game, with no graphical interface because I do not know how to do it and with 5 words that I used to test. What do you guys think of to improve the code and make it more compact? Thanks

from random import choice

def imprime(letra, pl):
    #imprime como está o resultado do jogo. Exemplo: c _ _ c l e _ _
    impressao = ''
    for i in range(len(palavra)):
        if palavra[i] not in pl:
            impressao += "%s "%palavra[i]
        else:
            impressao += '_ '
    return impressao

#palavras pré-definidas
palavras = ['chiclete', 'arroz', 'banana', 'feijao', 'nutella']

#escolhe a palavra do jogo
palavra = choice(palavras)

erros = 0
pl = []
#adiciona todas as letras da palavra a uma lista 'pl'
for i in range(len(palavra)):
    pl.append(palavra[i])

#imprime a quantidade de letras da palavra
print("A palavra é: %s"%('_ '*len(palavra)))
print("")
jogo = True
tentativas = []

while jogo:

    letra = input("Digite uma letra ou palavra: ")
    #o usuario digita uma letra ou palavra
    if letra == palavra:
        #verifica se o jogador acertou a palavra, caso sim encerra o programa
        print("Você ganhou. A palavra era %s"%palavra)
        break

    #verifica se a letra escolhida ainda não havia sido escolhida pelo usuario
    while letra in tentativas:
        letra = input("Você já tentou essa letra ou palavra. Digite novamente: ")
    tentativas.append(letra)

    if letra in palavra:
        #se o usuario acertou uma letra, ela é removida da lista 'pl'.
        for i in range(palavra.count(letra)):
            pl.remove(letra)
    else:
        erros += 1
        #se o usuario errar a letra ou palavra, é contabilizado um erro. Com 6 erros o usuario é derrotado.
        if erros == 6:
            print("Você errou pela 6ª vez. Fim de jogo")
            print("Você perdeu")
            break

        print("Você errou pela %iª vez. Tente de novo!"%erros)
    print("A palavra é: ",imprime(letra, pl))
    print("")

    if len(pl) == 0:
        #se a lista 'pl' possuir 0 elementos, então o usuario ganhou
        print("Você ganhou!")
        break
    
asked by anonymous 12.09.2018 / 21:40

1 answer

2

Displaying the word on the screen

First, let's do the function that displays the word on the screen, along with the underscores in the letters that should not be displayed. For this, we can do:

def exibir(palavra, tentativas):
    caracteres = (letra if letra in tentativas else '_' for letra in palavra)
    return ' '.join(caracteres)

This will display the word, except for non characters that are in tentativas , which will be replaced with an underscore, _ .

exibir('woss', [])  # _ _ _ _
exibir('woss', ['s'])  # _ _ s s
exibir('woss', ['s', 'w'])  # w _ s s
exibir('woss', ['s', 'w', 'o'])  # w o s s

Sorting the word

The part of drawing the word you did well and has nothing to change:

from random import choice

palavras = ['chiclete', 'arroz', 'banana', 'feijao', 'nutella']
palavra = choice(palavras)

Game logic

We started by defining the amount of user errors and the attempts he made:

tentativas = set()
erros = 0

At this point, I used tentativas as a set, since it will not make sense to have duplicate attempts and the set has optimizations in its access and search in relation to the list. At this point it's almost like a micro-optimization, but it's the tip for you to study.

For the loop, you do not need to create a variable just to be true at all, you can use direct True . As well as you do not need to print the "word" out of the loop, just do it inside it and do it only once.

while True:
    print('A palavra atual é:', exibir(palavra, tentativas))

    while True:
        tentativa = input('Digite uma letra ou palavra: ').lower()
        if tentativa not in tentativas:
            tentativas.add(tentativa)
            break
        print('Você já fez essa tentativa.')

See that I have used the lower string method to convert user input to lowercase every so that we do not have to worry about it and used another infinite loop to check user input, this prevents you from having to do the same input twice in the code.

At this point, we can already check whether the user has won or not. This will happen when the word no longer has the character _ or when the user enters the whole word correctly:

if '_' not in exibir(palavra, tentativas) or tentativa == palavra:
    print('Você venceu')
    break

But if the user did not win, we should check if he at least hit a letter or made a mistake, then count the errors.

if tentativa not in palavra:
    print(f'Você errou! Só te restam {5-erros} tentativas')
    erros += 1

And, finally, end the game when the user hits all six unsuccessful attempts.

if erros == 6:
    print('Você perdeu!')
    break

It would look something like this ...

from random import choice

def exibir(palavra, tentativas):
    caracteres = (letra if letra in tentativas else '_' for letra in palavra)
    return ' '.join(caracteres)

palavras = ['chiclete', 'arroz', 'banana', 'feijao', 'nutella']
palavra = choice(palavras)

tentativas = set()
erros = 0

while True:
    print('A palavra atual é:', exibir(palavra, tentativas))

    while True:
        tentativa = input('Digite uma letra ou palavra: ').lower()
        if tentativa not in tentativas:
            tentativas.add(tentativa)
            break
        print('Você já fez essa tentativa.')

    if '_' not in exibir(palavra, tentativas) or tentativa == palavra:
        print('Você venceu')
        break

    if tentativa not in palavra:
        print(f'Você errou! Só te restam {5-erros} tentativas')
        erros += 1

    if erros == 6:
        print('Você perdeu!')
        break

See working at Repl.it

Not as small as its version, but considerably simpler and more readable.

When using f-string to format a string instead of the % operator, read:

12.09.2018 / 22:37