Skillbook Logo
foto profilo

Skill Factory

Lista post > Impariamo Python giocando al "Solitario del Ferroviere" - Lezione 6

Impariamo Python giocando al "Solitario del Ferroviere" - Lezione 6

Gino Visciano | Skill Factory - 19/01/2020 23:16:45 | in Tutorials

In questa lezione completiamo il "Solitario del Ferroviere" implementando i tre livelli previsti: Apprendisti, Principianti ed Esperti.

  

Come abbiamo già visto nelle lezioni precedenti, i primi due livelli del gioco offrono aiuti differenti, quello per Esperti non prevede nessun tipo di aiuto, dipende tutto dalle capacità del giocatore.

Per scegliere uno dei tre livelli previsti, bisogna cliccare su una delle immagini seguenti presenti sul Frame di avvio:

Le immagini cliccabili, sono associate alle funzioni  apprendisti, principainti ed esperti che attivano i Frame con i componenti del livello scelto.

Di seguito i blocchi di codice python delle tre funzioni che permettono di gestire i livelli del solitario:

def apprendista(event):
    global livello
    frame_avvio.pack_forget()
    frame_avvio.quit()
    livello=1
    root.wm_title('Solitario del ferroviere:[Apprendista]')
    crea_primo_livello_solitario(root)

def principiante(event):
    global livello
    frame_avvio.pack_forget()
    frame_avvio.quit()
    livello=2
    root.wm_title('Solitario del ferroviere:[Principiante]')
    crea_altri_livelli_solitario(root)

def esperto(event):
    global livello
    frame_avvio.pack_forget()
    frame_avvio.quit()
    livello=3
    root.wm_title('Solitario del ferroviere:[Esperto]')
    crea_altri_livelli_solitario(root)

 

Come creare il pannello di gioco ed avviare il livello di avvio

Il blocco di codice Python seguente permette di avviare il solitario, vengono prima caricate le librerie richieste e successivamente viene prima creato il pannello di gioco e poi avviato il Frame di avvio. 

import pygame # Libreria usata nel gioco per gestire i suoni
import random # Libreria che serve a gestire valori casuale
import tkinter as tk # Libreria usata per creare, pannelli e finestre
import time # Libreria per gestire il tempo
from PIL import Image, ImageTk  # Libreria per gestire le immagini
from tkinter import messagebox # Libreria per gestire le finestre modali di scelta
 
root = tk.Tk() # Crea il pannello di gioco che contiene i Frame con i componenti di gioco 
root.wm_title('Solitario del ferroviere')
root.geometry("1400x600")
root.resizable(False, False)
root.protocol("WM_DELETE_WINDOW", on_closing)
flag=False 
# flag=True aggiorna tempo e punteggio, flag=False aggiorna solo orologio
crea_avvio_solitario(root) # Questa funzione crea ed avvia il livello di avvio del solitario
root.mainloop()
 

Come creare il livello di avvio del gioco e rendere le immagini cliccabili

Il codice seguente mostra come caricare le immagini dei livelli di gioco ed associarle ad un evento di tipo click per avviare le funzioni: apprendistiprincipainti ed esperti.  

def crea_avvio_solitario(root):
    global frame_avvio
    global livello
    livello=0

    # Creazione Frame del livello di avvio (frame_avvio) ed associazione al pannello di gioco root
    frame_avvio=tk.Frame(root)
    frame_avvio.pack(side="top", fill="both", expand = True)
    immagine_titolo=ImageTk.PhotoImage(Image.open('titolo_solitario_del_ferroviere.png'))
    
# Caricamento immagini
    immagine_apprendisti=ImageTk.PhotoImage(Image.open('apprendisti.png'))
    immagine_principianti=ImageTk.PhotoImage(Image.open('principianti.png'))
    immagine_esperti=ImageTk.PhotoImage(Image.open('esperti.png'))

    immagine_asso=ImageTk.PhotoImage(Image.open('1coppe.png'))
    immagine_retro=ImageTk.PhotoImage(Image.open('Carte_Napoletane_retro.png'))
    label_titolo=tk.Label(frame_avvio, image=immagine_titolo)
    label_titolo.place(x=180,y=5)

   # Posizionamento delle immagini sul Frame del livello di avvio ed attivazione (bind(...)) dell'evento click alle funzioni apprendiata, principiante ed esperto  
    label_apprendisti=tk.Label(frame_avvio, image=immagine_apprendisti)
    label_apprendisti.place(x=100,y=280)
    label_apprendisti.bind("<Button>",apprendista)
    label_principianti=tk.Label(frame_avvio, image=immagine_principianti)
    label_principianti.place(x=355,y=280)
    label_principianti.bind("<Button>",principiante)
    label_esperti=tk.Label(frame_avvio, image=immagine_esperti)
    label_esperti.place(x=600,y=280)
    label_esperti.bind("<Button>",esperto)
    label_asso=tk.Label(frame_avvio, image=immagine_asso)
    label_asso.place(x=870,y=180)
    label_retro=tk.Label(frame_avvio, image=immagine_retro)
    label_retro.place(x=1100,y=180)
    label_messaggio=tk.Label(frame_avvio, text="Scegli il livello per iniziare a giocare ...",font=("times", 18,'italic'))
    label_messaggio.place(x=240,y=210)
    logo=ImageTk.PhotoImage(Image.open('logo_sf.png'))
    label_logo=tk.Label(frame_avvio, image=logo)
    label_powered_sf=tk.Label(frame_avvio, text="2020 - Powered by Skill Factory",font=("times", 14,'italic'))
    label_powered_sf.place(x=550,y=557)
    label_logo.place(x=805,y=545)
    frame_avvio.mainloop()

Come creare il primo livello di gioco

Il codice seguente mostra come creare il primo livello di gioco:

def crea_primo_livello_solitario(root):
    global frame_primo_livello_solitario
    global label_carte_small_si
    global label_carte_small_no
    global immagini_carte
    global immagini_carte_small
    global label_mazzo_di_carte
    global label_carta_girata
    global label_non_indovinate
    global label_indovinate
    global label_girate
    global label_carta_pensata
    global label_clock
    global label_titolo_tempo
    global label_titolo_tentativi
    global label_secondi
    global label_tentativi
    global label_titolo_score
    global label_score
    global pulsante_gira
    global pulsante_mischia
    global pulsante_nuova_partita

    # Creazione Frame del primo livello di gioco (frame_primo) ed associazione al pannello di gioco root
    frame_primo_livello_solitario=tk.Frame(root)
    frame_primo_livello_solitario.pack(side="top", fill="both", expand = True)
    #Orologio
    label_clock = tk.Label(frame_primo_livello_solitario, font=('arial', 14, 'italic'), bg='darkgray',fg='black')
    label_titolo_tempo=tk.Label(frame_primo_livello_solitario, text="TEMPO",font=("times", 12,"italic"),fg="black")
    label_titolo_tentativi=tk.Label(frame_primo_livello_solitario, text="TENTATIVI",font=("times", 12,"italic"),fg="black")
    label_secondi=tk.Label(frame_primo_livello_solitario, font=('arial', 14, 'normal'), bg='blue',fg='white')
    label_tentativi=tk.Label(frame_primo_livello_solitario, font=('arial', 14, 'normal'), bg='orange',fg='white')
    label_titolo_score=tk.Label(frame_primo_livello_solitario, text="SCORE",font=("times", 12,"italic"),fg="black")
    label_score=tk.Label(frame_primo_livello_solitario, font=('arial', 16, 'normal'), bg='palevioletred',fg='white')
    immagine_indovinate=ImageTk.PhotoImage(Image.open('verde.png'))
    immagine_non_indovinate=ImageTk.PhotoImage(Image.open('rosso.png'))
    label_titolo_carta_pensata=tk.Label(frame_primo_livello_solitario, text="CARTA PENSATA",font=("Helvetica", 14))
    label_titolo_mazzo_di_carte=tk.Label(frame_primo_livello_solitario, text="MAZZO DI CARTE",font=("Helvetica", 14))
    #Pulsanti per gestire il  gioco
    pulsante_cambia=tk.Button(frame_primo_livello_solitario,text="CAMBIA", width=10, height=2, bd = 3,command=cambia, bg="seagreen",font=("Helvetica", 12))
    pulsante_gira=tk.Button(frame_primo_livello_solitario,text="GIRA", width=10, height=2, bd = 3,command=gira_primo, bg="teal",font=("Helvetica", 12))
    pulsante_mischia=tk.Button(frame_primo_livello_solitario,text="MISCHIA", width=10, height=2, bd = 3,command=mischia_primo, bg="mediumpurple",font=("Helvetica", 12))
    pulsante_nuova_partita=tk.Button(frame_primo_livello_solitario,text="NUOVA PARTITA", width=15, height=2, bd = 3,command=nuova_partita_primo, bg="darkorange",font=("Helvetica", 12))

    label_girate=tk.Label(frame_primo_livello_solitario, text="   0/10  ",font=("Helvetica", 25),fg="white",bg="tomato")
    label_img_indovinate=tk.Label(frame_primo_livello_solitario, image=immagine_indovinate)
    label_indovinate=tk.Label(frame_primo_livello_solitario, text=str(indovinate),font=("Helvetica", 24))
    label_non_indovinate=tk.Label(frame_primo_livello_solitario, text=str(non_indovinate),font=("Helvetica", 24))
    label_img_non_indovinate=tk.Label(frame_primo_livello_solitario, image=immagine_non_indovinate)
    immagini_carte=carica_immagini_carte()
    label_carta_pensata=tk.Label(frame_primo_livello_solitario, image=immagini_carte[1])
    label_mazzo_di_carte=tk.Label(frame_primo_livello_solitario, image=immagini_carte[0])
    label_carta_girata=tk.Label(frame_primo_livello_solitario, image=immagini_carte[0])
    immagini_carte_small=carica_immagini_carte_small()
    logo=ImageTk.PhotoImage(Image.open('logo_sf.png'))
    label_logo=tk.Label(frame_primo_livello_solitario, image=logo)
    label_powered_sf=tk.Label(frame_primo_livello_solitario, text="2020 - Powered by Skill Factory",font=("times", 14,'italic'))
    label_clock.place(x=1300,y=5)
    pulsante_cambia.place(x=60,y=370)
    label_titolo_carta_pensata.place(x=25,y=5)
    label_carta_pensata.config(image=immagini_carte[1])
    label_carta_pensata.place(x=5,y=40)
    label_titolo_mazzo_di_carte.place(x=260,y=5)
    label_mazzo_di_carte.place(x=240,y=40)
    pulsante_gira.place(x=285,y=370)
    label_girate.config(text="   0/"+str(len(mazzo_carte))+"  ")
    label_girate.place(x=500,y=370)
    label_img_indovinate.place(x=750,y=60)
    label_indovinate.config(text=str(indovinate))
    label_indovinate.place(x=820,y=65)
    label_img_non_indovinate.place(x=750,y=150)
    label_non_indovinate.config(text=str(non_indovinate))
    label_non_indovinate.place(x=820,y=158)
    label_titolo_tempo.place(x=35,y=455)
    label_secondi.place(x=30,y=515)
    label_tentativi.place(x=160,y=515)
    label_titolo_tentativi.place(x=153,y=455)
    label_secondi.place(x=30,y=480)
    label_tentativi.place(x=160,y=480)
    label_titolo_score.place(x=280,y=455)
    label_score.place(x=280,y=480)
    label_powered_sf.place(x=550,y=557)
    label_logo.place(x=805,y=545)
    start_primo()
   # Se il flag avviaTick e True viene eseguita la funzione Tick(). Questa funzione ogni 200 millisecondi aggiorna l'orologio, il tempo trascorso ed il punteggio
    if avviaTick:
        tick()
    frame_primo_livello_solitario.mainloop()

Come creare gli altri  livello di gioco

Il codice seguente mostra come creare gli  altri livelli di gioco:

def crea_altri_livelli_solitario(root):
    global frame_altri_livelli_solitario
    global label_mazzo_di_carte
    global label_carta_girata
    global label_girate
    global label_carta_pensata
    global label_clock
    global label_titolo_tempo
    global label_titolo_tentativi
    global label_secondi
    global label_tentativi
    global label_titolo_score
    global label_score
    global pulsante_gira
    global pulsante_mischia
    global pulsante_nuova_partita
    global immagini_carte
    global label_titolo_carta_da_indovinare
    global label_titolo_carte_indovinate
    global label_titolo_carte_non_indovinate
    global label_indovinate
    global label_non_indovinate
    global label_carta_indovinata
    global label_carta_non_indovinata
    global label_carte_da_indovinare
    global label_carta_non_indovinata_retro
    global livello

    # Creazione Frame per il secondo e terzo livello di gioco (frame_altri_livelli) ed associazione al pannello di gioco root
    frame_altri_livelli_solitario=tk.Frame(root)
    frame_altri_livelli_solitario.pack(side="top", fill="both", expand = True)
    label_titolo_carte_indovinate=tk.Label(frame_altri_livelli_solitario, text="CARTE INDOVINATE",font=("Helvetica", 14),fg="green")
    label_titolo_carte_non_indovinate=tk.Label(frame_altri_livelli_solitario, text="CARTE NON INDOVINATE",font=("Helvetica", 14),fg="red")
    label_indovinate=tk.Label(frame_altri_livelli_solitario, text="    0    ",font=("Helvetica", 25),fg="white",bg="green")
    label_non_indovinate=tk.Label(frame_altri_livelli_solitario, text="    0    ",font=("Helvetica", 25),fg="white",bg="red")
    #Orologio
    label_clock = tk.Label(frame_altri_livelli_solitario, font=('arial', 14, 'italic'), bg='darkgray',fg='black')
    label_titolo_tempo=tk.Label(frame_altri_livelli_solitario, text="TEMPO",font=("times", 12,"italic"),fg="black")
    label_titolo_tentativi=tk.Label(frame_altri_livelli_solitario, text="TENTATIVI",font=("times", 12,"italic"),fg="black")
    label_secondi=tk.Label(frame_altri_livelli_solitario, font=('arial', 14, 'normal'), bg='blue',fg='white')
    label_tentativi=tk.Label(frame_altri_livelli_solitario, font=('arial', 14, 'normal'), bg='orange',fg='white')
    label_titolo_score=tk.Label(frame_altri_livelli_solitario, text="SCORE",font=("times", 12,"italic"),fg="black")
    label_score=tk.Label(frame_altri_livelli_solitario, font=('arial', 16, 'normal'), bg='palevioletred',fg='white')
    label_titolo_carta_pensata=tk.Label(frame_altri_livelli_solitario, text="CARTA PENSATA",font=("Helvetica", 14))
    label_titolo_mazzo_di_carte=tk.Label(frame_altri_livelli_solitario, text="MAZZO DI CARTE",font=("Helvetica", 14))
    
#Pulsanti per gestire il gioco
    pulsante_cambia=tk.Button(frame_altri_livelli_solitario,text="CAMBIA", width=10, height=2, bd = 3,command=cambia, bg="seagreen",font=("Helvetica", 12))
    pulsante_gira=tk.Button(frame_altri_livelli_solitario,text="GIRA", width=10, height=2, bd = 3,command=gira_altri, bg="teal",font=("Helvetica", 12))
    pulsante_mischia=tk.Button(frame_altri_livelli_solitario,text="MISCHIA", width=10, height=2, bd = 3,command=mischia_altri, bg="mediumpurple",font=("Helvetica", 12))
    pulsante_nuova_partita=tk.Button(frame_altri_livelli_solitario,text="NUOVA PARTITA", width=15, height=2, bd = 3,command=nuova_partita_altri, bg="darkorange",font=("Helvetica", 12))

    label_girate=tk.Label(frame_altri_livelli_solitario, text="   0/10  ",font=("Helvetica", 25),fg="white",bg="tomato")
    immagini_carte=carica_immagini_carte()
    label_carta_pensata=tk.Label(frame_altri_livelli_solitario, image=immagini_carte[1])
    label_mazzo_di_carte=tk.Label(frame_altri_livelli_solitario, image=immagini_carte[0])
    label_carta_girata=tk.Label(frame_altri_livelli_solitario, image=immagini_carte[0])
    label_carte_da_indovinare=tk.Label(frame_altri_livelli_solitario, image=immagini_carte[0])
    label_carta_girata=tk.Label(frame_altri_livelli_solitario, image=immagini_carte[0])
    logo=ImageTk.PhotoImage(Image.open('logo_sf.png'))
    label_logo=tk.Label(frame_altri_livelli_solitario, image=logo)
    label_powered_sf=tk.Label(frame_altri_livelli_solitario, text="2020 - Powered by Skill Factory",font=("times", 14,'italic'))
    label_clock.place(x=1300,y=5)
    pulsante_cambia.place(x=60,y=370)
    label_titolo_carta_pensata.place(x=25,y=5)
    label_carta_pensata.config(image=immagini_carte[1])
    label_carta_pensata.place(x=5,y=40)
    label_titolo_mazzo_di_carte.place(x=260,y=5)
    label_mazzo_di_carte.place(x=240,y=40)
    pulsante_gira.place(x=285,y=370)
    label_girate.config(text="   0/"+str(len(mazzo_carte))+"  ")
    label_girate.place(x=500,y=370)
    label_titolo_tempo.place(x=35,y=455)
    label_secondi.place(x=30,y=515)
    label_tentativi.place(x=160,y=515)
    label_titolo_tentativi.place(x=153,y=455)
    label_secondi.place(x=30,y=480)
    label_tentativi.place(x=160,y=480)
    label_titolo_score.place(x=280,y=455)
    label_score.place(x=280,y=480)
    label_powered_sf.place(x=550,y=557)
    label_logo.place(x=805,y=545)
    label_carta_indovinata=tk.Label(frame_altri_livelli_solitario, image=immagini_carte[0])
    label_carta_non_indovinata=tk.Label(frame_altri_livelli_solitario, image=immagini_carte[0])
    if livello==2:
        label_carta_non_indovinata=tk.Label(frame_altri_livelli_solitario, image=immagini_carte[0])
        label_carta_non_indovinata.bind("<Button>",gira_carta_non_indovinata)
        immagine_help=ImageTk.PhotoImage(Image.open('help.png'))
        label_carta_non_indovinata_help=tk.Label(frame_altri_livelli_solitario, image=immagine_help)
        label_carta_non_indovinata_help.place(x=1230,y=150)
        label_carta_non_indovinata_help.bind("<Button>",help_frame_show)
        label_carta_non_indovinata_retro=tk.Label(frame_altri_livelli_solitario, image=immagini_carte[0])
        label_carta_non_indovinata_retro.bind("<Button>",gira_carta_non_indovinata_back)
        label_carta_non_indovinata_help.place(x=1230,y=150)
        label_carta_non_indovinata_help.bind("<Button>",help_frame_show)
    start_altri()
   # Se il flag avviaTick e True viene eseguita la funzione Tick(). Questa funzione ogni 200 millisecondi aggiorna l'orologio, il tempo trascorso ed il punteggio
    if avviaTick:
        tick()
    frame_altri_livelli_solitario.mainloop()

 

Come abbandonare il Solitario oppure un livello di gioco

Per abbandonare il livello di gioco scelto oppure uscire dal Solitario, basta cliccare sull'icona close in alto a destra del Pannello di gioco.  

La finestra modele seguente permette di abbandonare un livello di gioco.

La finestra modele seguente permette di uscire dal Solitario.

Per associare all'icona close del Pannello di gioco la funzione per abbandonare il livello di gioco oppure il Solitario  abbiamo usato il codice seguete:

root.protocol("WM_DELETE_WINDOW", on_closing)

def on_closing():
    if livello==0:
        if messagebox.askokcancel("EXIT", "Vuoi uscire dal solitario?"):
            root.destroy()
    else:
        if messagebox.askokcancel("EXIT", "Vuoi abbandonare il gioco?"):
            torna_avvio_solitario()

La funzione torna_avvio_solitario() permette di abbandonare il livello di gioco corrente e tornare al livello di avvio. 

   def torna_avvio_solitario():
    global mazzo_carte
    global mazzo_carte_non_indovinate
    global indovinate
    global non_indovinate
    global offset_indovinate
    global offset_non_indovinate
    global tentativi
    global score
    global conta_score
    global time_start
    global livello
    global flag
    if livello==1:
        frame_primo_livello_solitario.pack_forget()
        frame_primo_livello_solitario.quit()
    elif livello>1:
        frame_altri_livelli_solitario.pack_forget()
        frame_altri_livelli_solitario.quit()
    mazzo_carte=[1,2,3,4,5,6,7,8,9,10]
    mazzo_carte_non_indovinate.clear()
    livello=0
    flag=False
    indovinate=0
    offset_indovinate=50
    non_indovinate=0
    offset_non_indovinate=50
    tentativi=1
    score=1000
    conta_score=0
    time_start=0
    crea_avvio_solitario(root)

Descrizione delle Funzioni usate nel gioco 

def tick(): Aggiorna l'orologio, il tempo ed il punteggio ogni 200 millisecondi
def suono(sound,tempo): Gestisce i suoni del gioco
def on_closing(): Associa all'icona close del Pannello di gioco la funzione per abbandonare il livello di gioco oppure il Solitario
def mischia_carte(mazzo): Mischia le carte del mazzo centrale
def carica_immagini_carte(): Carica le immagini del gioco
def carica_immagini_carte_small(): Carica le immagini del primo livello di gioco
def cambia(): Permette di scegliere la carta pensata
def gira_primo(): Gira le carte del mazzo centrale del primo livello di gioco
def gira_altri(): Gira le carte del mazzo centrale del secondo e terzo livello di gioco
def nuova_partita_primo(): Avvia una nuova partita nel primo livello di gioco
def nuova_partita_altri(): Avvia una nuova partita nel secondo e terzo livello di gioco
def mischia_primo(): Mischia le carte nel primo livello di gioco
def mischia_altri(): Mischia le carte nel secondo e terzo livello di gioco
def torna_avvio_solitario(): Abbandona il livello di gioco corrente e torna al livello di avvio
def gira_carta_non_indovinata(event): Gira le carte del mazzo di carte non indovinate
def gira_carta_non_indovinata_back(event): Gira le carte del mazzo di carte non indovinate
def ripristina_carte_non_indovinate(): Ripristina il mazzo di carte non indovinate se si gira una carta del mazzo centrale
def help_frame_hidden(): Nasconde l'help del secondo livello di gioco
def help_frame_show(event): Mostra l'help del secondo livello di gioco
def apprendista(event): Avvia il primo livello di gioco
def principiante(event): Avvia il secondo livello di gioco
def esperto(event): Avvia il terzo livello di gioco
def crea_avvio_solitario(root): Avvia il livello di avvio del solitario
def crea_primo_livello_solitario(root): Crea il frame con tutti i componenti del primo livello di gioco
def crea_altri_livelli_solitario(root): Crea il frame con tutti i componenti del secondo e terzo livello di gioco
def start_primo(): Inizializza il primo livello di gioco
def start_altri(): Inizializza il secondo e terzo livello di gioco

 

Conclusioni

Con questa lezione il gioco del "Solitario del Ferroviere" è finito, sicuramente può essere migliorato e possono essere aggiunte ultriori funzionalità, come ad esempio la registrazione dei punteggi migliori raggiunti, per creare una classifica dei giocatori più bravi.

Il gioco può essere compilato per ottenere un eseguibile che vi permetterà di giocare senza dover usare l'interprete Python.   

Per compilare uno script Python potete installare il tool pyinstaller, con il comando:

pip install pyinstaller

Per compilare lo script dovete usare il comando:

pyinstaller solitario_del_ferroviere.py --noconsole

Dopo la compilazione travate tutto quello che vi serve nella cartella \dist\solitario_del_ferroviere.

Prima di lanciare il file eseguibile solitario_del_ferroviere.exe, dovete caricare nella cartella \dist\solitario_del_ferroviere tutte le immagini ed i file audio.

Buon divertimento ed arrivederci alla prossima lezione!

 


<< Lezione precedente           Lezione successiva >>



 Per scaricare le risorse di questa lezione clicca sul link seguente:risorse_lezione_06

 



 

Share Button
TOP