7.11 Exercício - Refatorando O Jogo Da Forca
- Crie a função imprime_mensagem_abertura que vai isolar a mensagem de abertura do jogo:
import random def jogar():imprime_mensagem_abertura() código omitido
def imprime_mensagem_abertura():
java
print('\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*') print('\*\*\*Bem vindo ao jogo da Forca!\*\*\*') print('\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*')- Agora, vamos separar o código que realiza a leitura do arquivo e inicializa a palavra secreta na função carrega_palavra_secreta() :
def carrega_palavra_secreta():
arquivo = open('palavras.txt', 'r') palavras = []
for linha in arquivo: linha = linha.strip() palavras.append(linha)
arquivo.close()
numero = random.randrange(0, len(palavras)) palavra_secreta = palavras[numero].upper()
Só que a função jogar() irá reclamar que a palavra_secreta não existe. O que queremos é que, ao executar a função carrega_palavra_secreta() , que ela retorne a palavra secreta para nós, assim poderemos guardá-la em uma variável:
python
import random def jogar():imprime_mensagem_abertura() palavra_secreta = carrega_palavra_secreta()
letras_acertadas = [”_” for letra in palavra_secreta] # restante do código omitido
Só que como faremos a função carrega_palavra_secreta() retornar um valor, no caso a
palavra_secreta ? A palavra_secreta já existe, mas só dentro da função
carrega_palavra_secreta() . Para que ela seja retornada, utilizamos a palavra-chave return:
def carrega_palavra_secreta():
arquivo = open('palavras.txt', 'r') palavras = []
for linha in arquivo: linha = linha.strip() palavras.append(linha)
arquivo.close()
numero = random.randrange(0, len(palavras)) palavra_secreta = palavras[numero].upper()
return palavra_secreta
3. Agora, vamos criar uma função que inicializa a lista de letras acertadas com o caractere '_'. Criaremos a função inicializa_letras_acertadas() :
python
import random def jogar():imprime_mensagem_abertura() palavra_secreta = carrega_palavra_secreta()
letras_acertadas = inicializa_letras_acertadas() # código omitido
def inicializa_letras_acertadas():
return ['_' for letra in palavra_secreta]
4. Mas a função inicializa_letras_acertadas() precisa ter acesso à palavra_secreta, pois ela não existe dentro da função, já que uma função define um escopo, e as variáveis declaradas dentro de uma função só estão disponíveis dentro dela. Então, ao chamar a função inicializa_letras_acertadas() , vamos passar palavra_secreta para ela por parâmetro:
python
import random def jogar():imprime_mensagem_abertura() palavra_secreta = carrega_palavra_secreta()
letras_acertadas = inicializa_letras_acertadas(palavra_secreta) # restante do código omitido
def inicializa_letras_acertadas(palavra): return ["_" for letra in palavra]
5. Vamos continuar refatorando nosso código. Criaremos a função pede_chute() , que ficará com o código que pede o chute do usuário, remove os espaços antes e depois, e o coloca em caixa alta. Não podemos nos esquecer de retornar o chute:
python
def jogar():código omitido
while (not acertou and not enforcou): chute = pede_chute()
def pede_chute():
chute = input('Qual letra? ') chute = chute.strip().upper() return chute
6. Ainda temos o código que coloca o chute na posição correta, dentro da lista. Vamos colocá-lo dentro da função marca_chute_correto() :
while (not acertou and not enforcou):
chute = pede_chute()
if (chute in palavra_secreta): marca_chute_correto()
else:
erros += 1
enforcou = erros == 6
acertou = '_' not in letras_acertadas print(letras_acertadas)
#código omitido
def marca_chute_correto(): posicao = 0
for letra in palavra_secreta: if (chute == letra):
letras_acertadas[posicao] = letra posicao += 1
Mas a função marca_chute_correto() precisa ter acesso a três valores: palavra_secreta ,
chute e letras_acertadas . Assim, vamos passar esses valores por parâmetro:
if (chute in palavra_secreta):marca_chute_correto(chute, letras_acertadas, palavra_secreta)
E modificamos nossa função para receber esses parâmetros:
def marca_chute_correto(chute, letras_acertadas, palavra_secreta): posicao = 0
for letra in palavra_secreta: if (chute == letra):
letras_acertadas[posicao] = letra posicao += 1
- Por fim, vamos remover a mensagem de fim de jogo e exportar os códigos que imprimem as mensagens de vencedor e perdedor do jogo:
if (acertou):imprime_mensagem_vencedor() else:
imprime_mensagem_perdedor()
E criar as funções:
def imprime_mensagem_vencedor(): print('Você ganhou!')
def imprime_mensagem_perdedor(): print('Você perdeu!')
Agora o nosso código está muito mais organizado e legível. Ao chamar todas as funções dentro da função jogar() , nosso código ficará assim:
python
def jogar(): imprime_mensagem_abertura()palavra_secreta = carrega_palavra_secreta()
letras_acertadas = inicializa_letras_acertadas(palavra_secreta)
print(letras_acertadas)enforcou = False acertou = False erros =
while(not enforcou and not acertou): chute = pede_chute()
if(chute in palavra_secreta):
marca_chute_correto(chute, letras_acertadas, palavra_secreta) else:
erros +=
enforcou = erros ==
acertou = ”_” not in letras_acertadas print(letras_acertadas)
if(acertou):
imprime_mensagem_vencedor() else:
imprime_mensagem_perdedor()
Por fim, podemos executar o nosso código, para verificar que o mesmo continua funcionando normalmente.
*********************************
***Bem vindo ao jogo da Forca!***
********************************* ['', '', '', '', '', '']
Qual letra?
- (opcional) Com a melhor organização do nosso código, vamos melhorar a exibição, a apresentação da forca, deixando o jogo mais amigável. Vamos começar com a mensagem de perdedor, alterando a função imprime_mensagem_perdedor . Ela ficará assim:
def imprime_mensagem_perdedor(palavra_secreta):
java
print('Puxa, você foi enforcado!')
python
print(f'A palavra era {} {palavra_secreta}')| print(” print(” / print(” / print(”// | \ \ /\ | ”) ”) ”) “) | |||
| print(”| XXXX XXXX | / | ||||
| print(“ | XXXX XXXX | ||||
| print(“ | XXX XXX | ||||
| print(" | |||||
| print(” \ print(“ | \ | XXX XXX | / / | ||
| print(" | |||||
| print(“ | I I I I I I I | ||||
| print(“ | I I I I I I | ||||
| print(” | _ _/ | “) | |||
| print(” | _ _/ | “) | |||
| print(” | \ / | ”) |
Precisamos passar a palavra_secreta para função imprime_mensagem_perdedor() :
if(acertou):
imprime_mensagem_vencedor() else:
imprime_mensagem_perdedor(palavra_secreta)
E modificamos o código de imprime_mensagem_vencedor() para:
def imprime_mensagem_vencedor():
java
print('Parabéns, você ganhou!')| print(” print(” | ’.=====.’ | “) “) |
| print(” | .-\: /-. | “) |
| print(” | ( | |
| print(” | ’- | :. |
| print(” | \::. / | “) |
| print(” | ’::. .’ | “) |
| print(” | ) ( | “) |
| print(” | .’ ’. | “) |
| print(” | ’-------’ | ”) |
Vá até a pasta do curso e copie o código destas funções que estão em um arquivo chamado
funcoes_forca.py.
- (opcional) Por fim, crie a função desenha_forca() , que irá desenhar uma parte da forca, baseado nos erros do usuário. Como ela precisa acessar os erros, passe-o por parâmetro para a função:
def desenha_forca(erros): pass
E copie o conteúdo do código da função desenha_forca() do arquivo funcoes *forca.py* na pasta do curso para sua função.
- Para finalizar, chame a função desenha_forca quando o jogador errar e aumente o limite de erros para 7.
if(chute in palavra_secreta):
marca_chute_correto(chute, letras_acertadas, palavra_secreta) else:
erros += 1 desenha_forca(erros)
enforcou = erros ==
acertou = ”_” not in letras_acertadas
- Tente fazer o mesmo com o jogo da adivinhação, refatore partes do código e isole em funções. Além disso, use sua criatividade para customizar mensagens para o usuário do seu jogo.
Neste exercício, praticamos bastante do que aprendemos no capítulo de função e finalizamos o jogo da forca.
Você pode estar se perguntando por que encapsulamos uma simples linha de código em uma função. Fizemos isso somente para deixar claro o que estamos fazendo, melhorando a legibilidade do código. Mas precisamos tomar cuidado com a criação de funções, pois criar funções desnecessariamente pode
aumentar a complexidade do código.
CAPÍTULO 8