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
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 tkinter import messagebox # Libreria per gestire le finestre modali di scelta
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: apprendisti, principainti 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:
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")
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()
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