Rozdział 17 · Projekt: „Kółko-krzyżyk”

Nowa gra i pierwsza pełna wersja

Finalny akcent pierwszego prototypu — reset gry bez ponownego uruchomienia programu. Ale rozdział dopiero się zaczyna.

Przycisk Nowej Gry

Aby nie uruchamiać programu od nowa po każdej grze, dodajemy przycisk resetu — przywraca wszystkie zmienne i wszystkie komórki do stanu początkowego:

novaya_igra.py
def novaya_igra():
    global tekuschij_igrok, igra_okonchena
    tekuschij_igrok = "X"
    igra_okonchena = False
    for knopka in polya:
        knopka.config(text="")
    status_label.config(text=f"tura gracza: {tekuschij_igrok}")
Pole znów jest puste, status Ruch gracza: X, po wygraniu X w poprzedniej grze
Pełne okno plików Real Prototype: „Nowa gra”

Pełny program

Zbioremy wszystkie części w jednym programie – został on już w pełni przetestowany i jest dostępny osobno Umieść w tej książce:

projects/tkinter/tic-tac-toe/tic_tac_toe_basic.py

Uruchom grę u siebie
Pobierz plik i uruchom go przez python tic_tac_toe_basic.py w terminalu (Rozdział 3) – albo przez Run w VS Code, albo PyCharm.
To PIERWSZY działający prototyp, a nie koniec rozdziału
Zbudowaliśmy prawdziwy działający program — z ruchami, zwycięstwem, remisem i resetem. To uczciwa, pełna, mała gra. Ale począwszy od następnego rozdziału będziemy przyglądać się jej dokładniej: skąd callback wie, że w ogóle ktoś go wywołał; dlaczego przechowywanie stanu w tekście przycisku nie jest najlepszym pomysłem na długo; jak zrobić interfejs, który reaguje na mysz i klawiaturę tym samym kodem. Pod koniec rozdziału (rozdział 17.31) ta sama gra stanie się tic_tac_toe.py — z osobnym modelem stanowym, oświetleniem linii zwycięzców, wynikami meczów i pełnymi testami.
★★ Zadanie samodzielne
Win Score

Dodaj etykiety wyniku zwycięstw X i O, zwiększaj odpowiedni licznik po każdej wygranej — licznik nie powinien zerować się przy przycisku „Nowa gra”.

Challenge
Wyróżnianie linii zwycięskiej

Gdy zostanie znaleziony zwycięzca, zmień kolor tła trzech zwycięskich przycisków — trzeba zwrócić z proverit_pobedu() nie tylko zwycięzcę, ale także indeksy linii.

Praktyka: Nowa gra i pierwsza pełna wersja
Moduł tkinter otwiera natywne okno Python — wykonaj lokalnie w VS Code, PyCharm lub Jupyter
Praktyka kursuje lokalnie
Otwórz praktykę →

Streszczenie sekcji

Czego się nauczyliśmy

  • .bind() reaguje na dowolne zdarzenia — nie tylko kliknięcie przycisku.
  • Duże projekty są budowane w etapach: interfejs → stan → obsługa zdarzeń → reguły → resetują.
  • Lambda z domyślnym ustawieniem (lambda i=indeks: ...) „zamraża”
  • Lista krotek to wygodny sposób na opisanie kilku podobnych kontrol (osiem linii wypłat) bez powtarzania kodu.
  • Pełnoprawna gra prawie zawsze ma sposób, aby rozpocząć od nowa, bez ponownego uruchamiania programu.
  • To dopiero początek rozdziału, ponieważ przyjrzymy się bliżej systemowi wydarzeń Tkinter i odbudujemy grę na bardziej rozbudowanej architekturze.