Come creare un gioco di tris in Python?

In questo articolo, realizzeremo un semplice gioco del Tris usando Python. Questo progetto ti aiuterà a comprendere la logica di base di un gioco e come strutturare il codice in modo efficace.

I giochi sono un passatempo universale, e ne esistono di svariati tipi: dai giochi web, a quelli per dispositivi mobili, fino a quelli per computer. Non ci concentreremo sulla creazione di un gioco complesso, ma svilupperemo un gioco del Tris a riga di comando, usando Python.

Se non hai familiarità con il Tris, puoi provare a giocarlo visivamente qui per comprenderne le regole. Non ti preoccupare, le rivedremo insieme.

Il Gioco del Tris

Questo tutorial è organizzato in tre sezioni distinte. Inizieremo con una spiegazione del funzionamento del gioco del Tris, seguita da un esame dell’algoritmo necessario per implementarne la logica. Infine, analizzeremo il codice strutturato e il suo funzionamento.

Se hai già familiarità con le regole del Tris, puoi saltare direttamente alla seconda sezione.

Dunque, senza ulteriori indugi, iniziamo con la prima sezione.

Come Giocare a Tris

In ogni partita ci saranno due giocatori, ciascuno rappresentato da un segno differente. Generalmente, i segni usati sono X e O. Il gioco si svolge su una griglia di 9 caselle.

Ecco una rappresentazione visiva della griglia del Tris:

Tabella del Tris

Ecco come si svolge una partita:

  • Il primo giocatore inserisce il suo segno in una delle caselle vuote.
  • Il secondo giocatore fa lo stesso, inserendo il suo segno in una casella vuota.
  • L’obiettivo di ogni giocatore è allineare i propri segni in una riga, colonna o diagonale.
  • La partita continua finché un giocatore non vince o finisce in pareggio, riempiendo tutte le caselle senza che nessuno abbia completato un allineamento vincente.

Vediamo degli esempi di partite visivamente.

Nell’esempio sopra, il giocatore X vince la partita avendo allineato tutti i suoi segni in diagonale.

Ci sono 8 possibili allineamenti vincenti. Vediamoli tutti.

Infine, una partita può finire in pareggio se la griglia si riempie senza allineamenti vincenti. Spero che ora tu abbia chiaro come si gioca a Tris.

È giunto il momento di fare pratica. Puoi visitare questo link e giocare un po’ per capire bene le meccaniche del gioco. Se hai già familiarità con il Tris, puoi passare direttamente alla prossima sezione.

Ora passiamo all’algoritmo.

L’Algoritmo

In questa sezione, discuteremo l’algoritmo necessario per scrivere il codice del gioco. Questo algoritmo ti aiuterà a implementare il gioco in qualsiasi linguaggio di programmazione. Vediamo come è strutturato.

  • Creiamo una griglia di gioco usando un array bidimensionale, e inizializziamo ogni elemento come vuoto.
    • Possiamo rappresentare una casella vuota con un qualsiasi simbolo. Useremo un trattino, ‘-‘.
  • Scriviamo una funzione per verificare se la griglia è piena o meno.
    • La funzione scorrerà la griglia e restituirà ‘false’ se trova una casella vuota, altrimenti restituirà ‘true’.
  • Scriviamo una funzione per verificare se un giocatore ha vinto.
    • Dobbiamo controllare tutte le possibili combinazioni vincenti discusse nella sezione precedente.
    • Controlleremo tutte le righe, colonne e le due diagonali.
  • Scriviamo una funzione per visualizzare la griglia, dato che la mostreremo più volte ai giocatori durante il gioco.
  • Scriviamo una funzione per avviare il gioco.
    • Selezioneremo a caso il primo giocatore.
    • Useremo un ciclo infinito che si interromperà solo quando la partita sarà finita (vittoria o pareggio).
      • Mostreremo la griglia al giocatore per consentirgli di selezionare la prossima casella.
      • Chiederemo al giocatore di inserire il numero di riga e colonna.
      • Aggiorneremo la casella con il simbolo del giocatore.
      • Controlleremo se il giocatore attuale ha vinto la partita.
      • Se il giocatore ha vinto, mostreremo un messaggio di vittoria e interromperemo il ciclo infinito.
      • Quindi, controlleremo se la griglia è piena.
      • Se la griglia è piena, mostreremo un messaggio di pareggio e interromperemo il ciclo infinito.
    • Infine, mostreremo la griglia finale ai giocatori.

Potresti essere in grado di visualizzare il funzionamento del gioco. Non preoccuparti se non hai capito tutto a fondo, diventerà più chiaro una volta visto il codice.

Passiamo quindi alla sezione del codice. Presuppongo che tu abbia Python installato nel tuo computer per provare il codice.

Il Codice

Ecco il codice completo:

import random

class TicTacToe:

    def __init__(self):
        self.board = []

    def create_board(self):
        for i in range(3):
            row = []
            for j in range(3):
                row.append('-')
            self.board.append(row)

    def get_random_first_player(self):
        return random.randint(0, 1)

    def fix_spot(self, row, col, player):
        self.board[row][col] = player

    def is_player_win(self, player):
        win = None
        n = len(self.board)
        # controllo righe
        for i in range(n):
            win = True
            for j in range(n):
                if self.board[i][j] != player:
                    win = False
                    break
            if win:
                return win
        # controllo colonne
        for i in range(n):
            win = True
            for j in range(n):
                if self.board[j][i] != player:
                    win = False
                    break
            if win:
                return win
        # controllo diagonali
        win = True
        for i in range(n):
            if self.board[i][i] != player:
                win = False
                break
        if win:
            return win
        win = True
        for i in range(n):
            if self.board[i][n - 1 - i] != player:
                win = False
                break
        if win:
            return win
        return False

    def is_board_filled(self):
        for row in self.board:
            for item in row:
                if item == '-':
                    return False
        return True

    def swap_player_turn(self, player):
        return 'X' if player == 'O' else 'O'

    def show_board(self):
        for row in self.board:
            for item in row:
                print(item, end=" ")
            print()

    def start(self):
        self.create_board()
        player="X" if self.get_random_first_player() == 1 else 'O'
        while True:
            print(f"Turno del giocatore {player}")
            self.show_board()
            row, col = list(map(int, input("Inserisci numero riga e colonna: ").split()))
            print()
            self.fix_spot(row - 1, col - 1, player)
            if self.is_player_win(player):
                print(f"Il giocatore {player} ha vinto!")
                break
            if self.is_board_filled():
                print("Pareggio!")
                break
            player = self.swap_player_turn(player)
        print()
        self.show_board()

# avvio del gioco
tic_tac_toe = TicTacToe()
tic_tac_toe.start()

Ecco un esempio di output del codice:

$ python tic_tac_toe.py
Turno del giocatore X
- - -
- - -
- - -
Inserisci numero riga e colonna: 1 1

Turno del giocatore O
X - -
- - -
- - -
Inserisci numero riga e colonna: 2 1

Turno del giocatore X
X - -
O - -
- - -
Inserisci numero riga e colonna: 1 2

Turno del giocatore O
X X -
O - -
- - -
Inserisci numero riga e colonna: 1 3

Turno del giocatore X
X X O
O - -
- - -
Inserisci numero riga e colonna: 2 2

Turno del giocatore O
X X O
O X -
- - -
Inserisci numero riga e colonna: 3 3

Turno del giocatore X
X X O
O X -
- - O
Inserisci numero riga e colonna: 3 2

Il giocatore X ha vinto!

X X O
O X -
- X O

Ecco alcuni punti importanti per comprendere meglio la struttura del codice:

  • Abbiamo usato una classe per raggruppare tutti i metodi in un unico posto. Ciò rende il codice riutilizzabile in altri progetti.
  • Abbiamo definito diverse funzioni per ogni specifica operazione, anche se si tratta di operazioni piccole. Ciò rende il codice più semplice da mantenere.
  • Questi due approcci permettono di aggiornare l’app senza sforzo nel caso in cui si voglia espandere il gioco.

Sentiti libero di adattare questa struttura e migliorarla in base alle tue esigenze. La struttura del codice non è fissa.

Conclusioni

Congratulazioni! Hai creato un gioco da zero. Non si tratta di uno dei giochi con una grafica complessa a cui siamo abituati, ma questo progetto ti aiuta a capire la logica dei giochi e a mantenere un codice pulito e strutturato. Segui principi simili per creare altri giochi interessanti. Puoi trovare ispirazione nei giochi della tua infanzia.

Buon coding! 👩‍💻

Esplora anche come creare un gioco di indovinelli e come realizzare Unit Test con il modulo Unittest di Python.

Ti è piaciuto questo articolo? Condividilo con i tuoi amici!