Ciao e benvenuto, Uno degli esempi di programmi python più diffusi per fare pratica è quello dell'impiccato. in questo progetto andremo quindi a scrivere il gioco dell'impiccato con il linguaggio di programmazione python.

Iniziamo subito ad analizzare il problema che dobbiamo risolvere.

Come ben sai nell'impiccato una persona deve indovinare una parola che l'avversario ha scelto(nel nostro caso sarà il computer), per farlo dovrà proporre ad ogni turno una lettera, se è presente nella parola allora verrà essa visualizzata, altrimenti il giocatore perderà una vita.

Possiamo suddividere quindi questo esercizio in 3 macro funzioni:

  • Generare una parola, ovvero quella che il giocatore dovrà indovinare;
  • Gestire la mossa del giocatore;
  • Gestire i tentativi a disposizione del giocatore e determinare se la partita è persa o vinta.

Ottenere una parola casuale

Andiamo quindi subito a far scegliere al computer la parola che in seguito dovremo indovinare.

Per farlo potremmo banalmente assegnare una stringa ad una variabile ed utilizzarla per il nostro gioco in questo modo: parola_da_indovinare = "pluto".

Tuttavia così facendo, la parola sarà sempre la stessa e ne saremo a conoscenza rendendo privo di senso il gioco.

Come possiamo quindi, fare in modo che ad ogni esecuzione del programma, venga assegnata automaticamente alla nostra variabile una stringa diversa?

Beh potremmo creare una lista, ovvero una sequenza di elementi, che conterrà tutte le parole che vogliamo, e come vedremo tra poco, ottenere una parola casuale da esso ogni volta che il nostro programma verrà avviato.

Prendiamo per esempio questa lista: lista_di_parole = ["pythonpertutti", "casa", "sole", "ananas"] , potremmo fare in modo che ad ogni avvio del nostro script, verrà assegnata una parola casuale tra quelle presenti nella lista alla nostra variabile.

NOTA BENE: questo progetto presuppone che tu abbia delle basi minime sulla programmazione, nel caso tu non ne abbia o non ti sembreranno chiari i concetti che tratteremo in seguito, ma hai voglia di imparare, ti consiglio di iniziare da qui.

La libreria random

Devi sapere che è possibile ottenere gli elementi di una lista tramite un indice che parte da 0 fino alla lunghezza della lista - 1. Quindi se per esempio volessi ottenere il secondo elemento di una lista dovrei procedere in questo modo:

lista_di_parole = ["pythonpertutti", "casa", "sole", "ananas"]
secondo_elemento = lista_di_parole[1]

print(secondo_elemento)

Ora se trovassimo il modo di poter generare in modo casuale un numero intero, compreso tra 0 e la lunghezza della nostra lista(-1), otterremo un numero che potremmo utilizzare come indice per la nostra lista e di conseguenza otterremo un elemento a caso dalla lista.

In questo caso ci viene in aiuto una libreria di Python, ovvero un insieme di funzioni già scritte e pronte all'uso. La libreria in questione si chiama random. Per importarlo scriviamo la seguente istruzione all'inizio del nostro file: import random.

La funzione Randint

Tra le numerose funzionalità che questa libreria ci offre, troviamo la funzione randint(), che ci permette appunto, dato un intervallo, di generare un numero intero casuale.

import random

lista_di_parole = ["pythonpertutti", "casa", "sole", "ananas"]
indice_casuale = random.randint(0, 3)
parola_da_indovinare = lista_di_parole[indice_casuale]

print(parola_da_indovinare)

Ecco quindi che abbiamo la possibilità di ottenere un elemento casuale all'interno di una nostra lista.

Giusto un piccolo accorgimento, come avrai notato, per ottenere il nostro indice casuale, nell'intervallo ho scritto il numero (ovvero la lunghezza della nostra lista - 1); attualmente funziona correttamente, ma se la lunghezza della nostra lista dovesse cambiare, il nostro numero non sarà più affidabile. Possiamo però ottenere la lunghezza della nostra lista con una semplice funzione: len(lista).

Andiamo subito ad applicarlo al nostro programma:

import random

lista_di_parole = ["pythonpertutti", "casa", "sole", "ananas"]
lunghezza = len(lista_di_parole)
indice_casuale = random.randint(0, lunghezza)
parola_da_indovinare = lista_di_parole[indice_casuale]

print(parola_da_indovinare)

La funzione choice

In alternativa alla funzione randint(), la libreria random ci offre la funzione choice(), la quale ci restituisce direttamente un elemento casuale della nostra lista, senza preoccuparci di dover generare un indice casuale.

import random

lista_di_parole = ["pythonpertutti", "casa", "sole", "ananas"]
parola_da_indovinare = random.choice(lista_di_parole)

print(parola_da_indovinare)

Importare le parole da file di testo

Se volessimo rendere più varia e grande la nostra lista di parole da indovinare, potremmo fare in modo di prendere le parole da un file esterno, come potrebbe essere un file di testo contenente numerose parole. Creiamo per esempio un file di testo con estensione .txt e scriviamo una parola per riga(su internet puoi trovare anche direttamente dei file di testo con numerose parole, accertati però che siano una per riga).

Con python fare tutto ciò è molto semplice, inizia quindi spostando il file che hai scaricato nella stessa cartella in cui è presente il tuo progetto.

Torniamo ora al nostro programma, vediamo subito come far aprire il nostro file di testo con il nostro linguaggio di programmazione, e leggerne il contenuto:

lista_di_parole = []
with
open('nome_file.txt', 'r') as f:
for line in f:
parola = line.rstrip('\n')
lista_di_parole.append(parola)

La funzione open() ci consente di aprire un file, come parametri vuole appunto il nome del file da aprire, e la modalità con cui farlo, ovvero se in scrittura/lettura o entrambe. In questo caso ho deciso di aprirlo solamente in modalità lettura 'r'.

La variabile f contiene tutte le parole del nostro file, e per andare a leggere riga per riga ho dovuto effettuare un ciclo for. Per evitare problemi ho utilizzato il metodo rstrip('\n') per rimuovere eventuali caratteri di a capo in modo da ottenere la parola pulita.

Riordiniamo il codice

Ottimo ora che tutto il nostro codice funziona correttamente, andiamo ad organizzarlo meglio, suddividendolo in funzioni.

Per rendere il tutto più chiaro e modulare andrei a creare due funzioni: una che si occupa di caricare la nostra lista, e l'altra si occuperà di generarci la nostra parola casuale:


import random

def carica_parole():
    lista_di_parole = []
    with open('nome_file.txt', 'r') as f:
        for line in f:
            parola = line.rstrip('\n')
            lista_di_parole.append(parola)
    return lista_di_parole

def parola_random(lista_di_parole):
    return random.choice(lista_di_parole)

lista_di_parole = carica_parole()
parola_da_indovinare = parola_random(lista_di_parole)
lettere_indovinate = ['_' for lettera in parola_da_indovinare]
print(lettere_indovinate)

Tenere traccia di ogni lettera indovinata dall'utente

Per tener traccia di ogni lettera indovinata dall'utente e poterla confrontare con la parola da indovinare in modo da determinare la vittoria o meno della partita, possiamo utilizzare una lista in questo modo:

Potremmo creare una lista di lunghezza uguale alla parola da indovinare, dove ogni elemento corrisponderà ad ogni lettera della parola.

Inizialmente tutte le lettere avranno come valore un trattino '_' che starà ad indicare appunto le lettere ancora non indovinate. Per esempio supponendo che la nostra parola sia casa, la nostra lista avrà inizialmente i seguenti valori ["_", "_", "_", "_"]. In seguito, se, per esempio, l'utente dovesse inserire la lettera a, la nostra lista diventerà così: ["_", "a", "_", "a"].

Ogni volta che l’utente inserirà una lettera presente nella parola, andremo ad ottenere la sua posizione(l’indice) nella parola.

Dato che la lunghezza della parola da indovinare, e la lunghezza della lista che abbiamo creato è uguale, utilizzeremo quell'indice per accedere all'elemento corrispondente della nostra lista e sostituiremo il trattino '_'  con la lettera inserita dall'utente.

Anche se non ti sembrerà chiarissimo questo ragionamento prova a seguirmi e vedrai che passo passo capirai tutto.

Creare la lista delle parole indovinate

Creiamo la nostra lista che inizialmente sarà vuota e andiamo a popolarla tanti trattini quanto è lunga la parola. Per aggiungere un elemento ad una lista basta scrivere il nome della lista.append e l’elemento tra parentesi.

lettere_indovinate = []
for lettera in parola_da_indovinare:
    lettere_indovinate.append('_')
print(lettere_indovinate, parola)

Utilizzando la list comprehension possiamo riscrivere la stessa cosa in un riga:

lettere_indovinate = ['_' for lettera in parola_da_indovinare]

print(lettere_indovinate, parola)

Ottenere le lettere dall'utente

Ora che abbiamo inizializzato la nostra lista dove verranno visualizzate le parole indovinate dal nostro giocatore, andiamo ad ottenere l'input del nostro utente e verificare se la lettera inserita è presente o meno nella parola scelta dal computer!

Riprendiamo inanzitutto il codice completo fino ad ora:

import random

def carica_parole():
lista_di_parole = []
with
open('nome_file.txt', 'r') as f:
for line in f:
parola = line.rstrip('\n')
lista_di_parole.append(parola)
return lista_di_parole

def parola_random(lista_di_parole):
return random.choice(lista_di_parole)

lista_di_parole = carica_parole()
parola_da_indovinare = parola_random(lista_di_parole)
lettere_indovinate = ['_' for lettera in parola_da_indovinare]
print(lettere_indovinate)

Dato che l'impiccato è un gioco a turni, non dovremmo chiedere una sola volta la lettera all'utente, bensì fino a quando il giocatore non indovinerà la parola o perderà tutte le vite a disposizione.

Per farlo dobbiamo creare un ciclo while e al suo interno chiederemo all'utente una lettera.

while True:
scelta = input("Inserisci una lettera -> ")
if scelta in parola_da_indovinare:
for i, lettera in enumerate(parola_da_indovinare):
if lettera == scelta:
lettere_indovinate[i] = lettera
else:
print("lettera non presente")

print(lettere_indovinate)

Come detto in precedenza, una volta che ho l'input dell'utente, verifico se la lettera ottenuta è presente nella parola, se lo è allora ottengo l'indice in cui si trova la lettera e sostituisco il '_' presente nella lista lettere_indovinate con la lettera digitata dal giocatore.

Nel caso la lettera non fosse nella parola allora andremo a togliere una vita al giocatore, momentaneamente stampa semplicemente a schermo una scritta, ma nella prossima parte di questo progetto andremo proprio a gestire tutta la parte che riguarda la vittoria e la sconfitta del giocatore.

Infine andrei a riorganizzare meglio il codice creando un altro paio di funzioni: una che si occuperà di sostiuire i '_' con la lettera dell'utente, l'altra di visualizzare meglio la lista delle lettere indovinate:

import random

def carica_parole():
lista_di_parole = []
with
open('nome_file.txt', 'r') as f:
for line in f:
parola = line.rstrip('\n')
lista_di_parole.append(parola)
return lista_di_parole

def parola_random(lista_di_parole):
return random.choice(lista_di_parole)

def visualizza_parola(lista_lettere):
print(' '.join(lettera for lettera in lista_lettere))

def aggiorna_lettere_indovinate(parola, scelta, lettere_indovinate):
for i, lettera in enumerate(parola):
if lettera == scelta:
lettere_indovinate[i] = lettera
return lettere_indovinate

lista_di_parole = carica_parole()
parola_da_indovinare = parola_random(lista_di_parole)
lettere_indovinate = ['_' for lettera in parola_da_indovinare]

visualizza_parola(lettere_indovinate)

while True:
scelta = input("Inserisci una lettera -> ")
if scelta in parola_da_indovinare:
lettere_indovinate = aggiorna_lettere_indovinate(parola_da_indovinare, scelta, lettere_indovinate)
else:
print("lettera non presente")

visualizza_parola(lettere_indovinate)

Gestire i tentativi disponibili dall'utente

Andiamo ora a vedere come creare un sistema che ci permette di controllare la vita del nostro utente.

Nell'impiccato ad ogni lettera sbagliata viene disegnato un pezzo del patibolo, fino ad arrivare ad avere il disegno completo dell'omino impiccato.

Tutto ciò possiamo farlo anche in python grazie ai generatori!

Ci basta creare un generatore che ogni volta che viene chiamato, restituisce una stringa sempre più completa del nostro patibolo:

def show_player_life():
    life = """
---
"""
    yield life

    life = """
|----
|
|
|
|
---
"""
    yield life
    life = """
|----0
|    |
|    |
|    |
|    |
---
"""
    yield life

    life = """
|----O
|    |
|   /|\
|    |
|    |
---
"""

    yield life

    life = """
|----O
|    |
|   /|\
|    |
|   /|\
---
"""

    yield life
    life = """

|--\
|   \O
|    |
|   /|\
|    |
--- /|\
"""
    yield life

Perfetto! adesso andiamo a chiamare il nostro generatore ogni volta che l'utente sbaglia una lettera.

lista_di_parole = carica_parole()
parola_da_indovinare = parola_random(lista_di_parole)
lettere_indovinate = ['_' for lettera in parola_da_indovinare]
vita_giocatore = show_player_life()

visualizza_parola(lettere_indovinate)

while True:
    scelta = input("Inserisci una lettera -> ")
    if scelta in parola_da_indovinare:
        lettere_indovinate = aggiorna_lettere_indovinate(parola_da_indovinare, scelta, lettere_indovinate)
    else:
        print(next(vita_giocatore))

    visualizza_parola(lettere_indovinate)

Determinare il risultato della partita

Come puoi notare ora quando arriviamo al sesto tentativo errato, il programma solleva un eccezione di tipo StopIteration, il che è normale perché il nostro generatore ha finito elementi da iterare, perciò andiamo a gestire questo errore con un try/catch, visualizzando un messaggio di sconfitta e uscendo dal ciclo while nel caso si verificasse un errore:

try:
print(next(vita_giocatore))
except StopIteration:
print("Hai perso, la parola era: {0}".format(parola_da_indovinare))
break

 

Nel caso invece l'utente dovesse andare a scegliere l'ultima lettera rimanente da indovinare, dobbiamo visualizzare un messaggio di vittoria e uscire dal ciclo while, in questo modo ad esempio:

scelta = input("Inserisci una lettera -> ")
if scelta in parola_da_indovinare:
lettere_indovinate = aggiorna_lettere_indovinate(parola_da_indovinare, scelta, lettere_indovinate)
if parola_da_indovinare == ''.join(lettera for lettera in lettere_indovinate):
print("Hai vinto, complimenti! La parola è: {0}".format(parola_da_indovinare))
break

Ecco quindi il nostro bellissimo gioco dell'impiccato completamente funzionante!

Codice completo

import random

def carica_parole():
    lista_di_parole = []
    with open('nome_file.txt', 'r') as f:
        for line in f:
            parola = line.rstrip('\n')
            lista_di_parole.append(parola)
    return lista_di_parole

def parola_random(lista_di_parole):
    return random.choice(lista_di_parole)

def visualizza_parola(lista_lettere):
    print(' '.join(lettera for lettera in lista_lettere))

def aggiorna_lettere_indovinate(parola, scelta, lettere_indovinate):
    for i, lettera in enumerate(parola):
        if lettera == scelta:
            lettere_indovinate[i] = lettera
    return lettere_indovinate

def show_player_life():
    life = """
---
"""
    yield life

    life = """
|----
|
|
|
|
---
"""
    yield life
    life = """
|----0
|    |
|    |
|    |
|    |
---
"""
    yield life

    life = """
|----O
|    |
|   /|\
|    |
|    |
---
"""

    yield life

    life = """
|----O
|    |
|   /|\
|    |
|   /|\
---
"""

    yield life
    life = """

|--\
|   \O
|    |
|   /|\
|    |
--- /|\
"""
    yield life


lista_di_parole = carica_parole()
parola_da_indovinare = parola_random(lista_di_parole)
lettere_indovinate = ['_' for lettera in parola_da_indovinare]
vita_giocatore = show_player_life() visualizza_parola(lettere_indovinate) while True: scelta = input("Inserisci una lettera -> ") if scelta in parola_da_indovinare: lettere_indovinate = aggiorna_lettere_indovinate(parola_da_indovinare, scelta, lettere_indovinate) if parola_da_indovinare == ''.join(lettera for lettera in lettere_indovinate): print("Hai vinto, complimenti! La parola è: {0}".format(parola_da_indovinare)) break else: try: print(next(vita_giocatore)) except StopIteration: print("Hai perso, la parola era: {0}".format(parola_da_indovinare)) break visualizza_parola(lettere_indovinate)

Funzionalità da aggiungere

Ora tocca a te! ci sono un bel po di modifiche che potresti apportare a questo giochino. Una tra queste potrebbe essere quella di implementare un interfaccia grafica, oppure salvare in un database tutti i risultati delle partite giocate in modo da poter visualizzare statistiche varie.

Insomma, dai sfogo alla tua creatività e buona programmazione!


Condividi sui Social