Hướng dẫn tic tac toe python beginner - tic tac toe python mới bắt đầu

Chơi trò chơi máy tính là một cách tuyệt vời để thư giãn hoặc thử thách bản thân. Một số người thậm chí còn làm điều đó một cách chuyên nghiệp. Nó cũng rất vui và giáo dục để xây dựng các trò chơi máy tính của riêng bạn. Trong hướng dẫn này, bạn sẽ xây dựng một trò chơi Tic-Tac-Toe cổ điển bằng cách sử dụng Python và Tkinter.

Show

Với dự án này, bạn sẽ trải qua các quy trình suy nghĩ cần thiết để tạo trò chơi của riêng bạn. Bạn cũng sẽ học cách tích hợp các kỹ năng và kiến ​​thức lập trình đa dạng của mình để phát triển một trò chơi máy tính chức năng và thú vị.

Trong hướng dẫn này, bạn sẽ học cách:

  • Lập trình trò chơi Tic-Tac-Toe cổ điển logic sử dụng Pythonclassic tic-tac-toe game’s logic using Python
  • Tạo giao diện người dùng đồ họa (GUI) của trò chơi bằng bộ công cụ Tkintergraphical user interface (GUI) using the Tkinter tool kit
  • Tích hợp trò chơi logic logic và GUI vào một trò chơi máy tính đầy đủ chức năngfully functional computer game

Như đã đề cập, bạn sẽ sử dụng khung GUI Tkinter từ Thư viện tiêu chuẩn Python để tạo giao diện trò chơi của bạn. Youllll cũng sử dụng mẫu mô hình-view-Controller và cách tiếp cận hướng đối tượng để sắp xếp mã của bạn. Để biết thêm về các khái niệm này, hãy xem các liên kết trong các điều kiện tiên quyết.

Để tải xuống toàn bộ mã nguồn cho dự án này, nhấp vào liên kết trong hộp bên dưới:

Demo: Một trò chơi tic-tac-toe trong Python

Trong dự án từng bước này, bạn sẽ xây dựng một trò chơi tic-tac-toe ở Python. Bạn sẽ sử dụng bộ công cụ Tkinter từ Thư viện tiêu chuẩn Python để tạo GUI GUI trò chơi. Trong video demo sau đây, bạn sẽ hiểu được cách trò chơi của bạn sẽ hoạt động sau khi bạn hoàn thành hướng dẫn này:

Trò chơi Tic-Tac-Toe của bạn sẽ có một giao diện tái tạo bảng trò chơi ba lần cổ điển. Người chơi sẽ thay phiên nhau thực hiện các động thái của họ trên một thiết bị dùng chung. Màn hình trò chơi ở đầu cửa sổ sẽ hiển thị tên của người chơi sẽ đi tiếp theo.

Nếu một người chơi thắng, thì màn hình trò chơi sẽ hiển thị một tin nhắn chiến thắng với tên người chơi hoặc Mark (X hoặc O). Đồng thời, sự kết hợp chiến thắng của các ô sẽ được tô sáng trên bảng.

Cuối cùng, menu tệp trò chơi sẽ có các tùy chọn để đặt lại trò chơi nếu bạn muốn chơi lại hoặc thoát khỏi trò chơi khi bạn chơi xong.

Nếu điều này nghe có vẻ là một dự án thú vị với bạn, thì hãy đọc tiếp để bắt đầu!

Tổng quan dự án

Mục tiêu của bạn với dự án này là tạo ra một trò chơi tic-tac-toe ở Python. Đối với giao diện trò chơi, bạn sẽ sử dụng bộ công cụ GUI Tkinter, xuất hiện trong cài đặt Python tiêu chuẩn như một pin bao gồm.

Trò chơi Tic-Tac-Toe dành cho hai người chơi. Một người chơi chơi X và các vở kịch khác O. Người chơi thay phiên nhau đặt điểm của họ trên một mạng lưới các ô ba phần ba. Nếu một người chơi nhất định có ba điểm liên tiếp theo chiều ngang, chiều dọc hoặc đường chéo, thì người chơi đó sẽ thắng trò chơi. Trò chơi sẽ được gắn nếu không ai có ba liên tiếp vào thời điểm tất cả các ô được đánh dấu.

Với các quy tắc này, bạn sẽ cần phải tập hợp các thành phần trò chơi sau:

  • Bảng điều khiển trò chơi mà bạn sẽ xây dựng với một lớp gọi là
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    9board, which you’ll build with a class called
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    9
  • Trò chơi logic logic, mà bạn sẽ quản lý bằng cách sử dụng một lớp gọi là
    # tic_tac_toe.py
    
    import tkinter as tk
    from tkinter import font
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
    
    0logic, which you’ll manage using a class called
    # tic_tac_toe.py
    
    import tkinter as tk
    from tkinter import font
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
    
    0

Bảng trò chơi sẽ hoạt động như một sự pha trộn giữa chế độ xem và bộ điều khiển trong thiết kế điều khiển mô hình. Để xây dựng bảng, bạn sẽ sử dụng một cửa sổ Tkinter, bạn có thể tạo bằng cách khởi tạo lớp

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
1. Cửa sổ này sẽ có hai thành phần chính:view and controller in a model-view-controller design. To build the board, you’ll use a Tkinter window, which you can create by instantiating the
# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
1 class. This window will have two main components:

  1. Hiển thị hàng đầu: Hiển thị thông tin về trạng thái trò chơi Shows information about the game’s status
  2. Lưới của các tế bào: đại diện cho các động tác trước đó và không gian hoặc ô có sẵn Represents previous moves and available spaces or cells

Bạn sẽ tạo màn hình trò chơi bằng tiện ích

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
2, cho phép bạn hiển thị văn bản và hình ảnh.

Đối với lưới các ô, bạn sẽ sử dụng một loạt các vật dụng

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
3 được sắp xếp trong một lưới. Khi một người chơi nhấp vào một trong những nút này, logic trò chơi sẽ chạy để xử lý người chơi di chuyển và xác định xem có người chiến thắng hay không. Trong trường hợp này, logic trò chơi sẽ hoạt động như mô hình, sẽ quản lý dữ liệu, logic và các quy tắc của trò chơi của bạn.model, which will manage the data, logic, and rules of your game.

Bây giờ bạn có một ý tưởng chung về cách xây dựng trò chơi tic-tac-toe của mình, bạn nên xem một vài điều kiện tiên quyết về kiến ​​thức mà mà sẽ cho phép bạn tận dụng tối đa hướng dẫn này.

Điều kiện tiên quyết

Để hoàn thành dự án trò chơi tic-tac-toe này, bạn nên thoải mái hoặc ít nhất là quen thuộc với các khái niệm và chủ đề được đề cập trong các tài nguyên sau:

  • Lập trình Gui Python với Tkinter
  • Lập trình hướng đối tượng (OOP) trong Python 3
  • Python "cho các vòng lặp (lặp lại xác định)
  • Khi nào nên sử dụng danh sách hiểu trong Python
  • Model-View-Controller (MVC) đã giải thích-với Legos
  • Từ điển trong Python
  • Làm thế nào để lặp lại thông qua một từ điển trong Python
  • Các chức năng chính trong Python
  • Viết mã Pythonic và Clean với tên có tên

Nếu bạn không có tất cả các kiến ​​thức được đề xuất trước khi bắt đầu hướng dẫn này, thì điều đó ổn. Bạn sẽ học bằng cách làm, vì vậy hãy tiếp tục và cho nó một vòng xoáy! Bạn luôn có thể dừng lại và xem xét các tài nguyên được liên kết ở đây nếu bạn bị mắc kẹt.

Bước 1: Thiết lập bảng trò chơi tic-tac-toe với tkinter

Để khởi động mọi thứ, bạn sẽ bắt đầu bằng cách tạo bảng trò chơi. Trước khi làm điều này, bạn cần quyết định cách sắp xếp mã cho trò chơi Tic-Tac-Toe của bạn. Bởi vì dự án này sẽ khá nhỏ, ban đầu bạn có thể giữ tất cả các mã trong một tệp

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
4 duy nhất. Bằng cách này, chạy mã và thực hiện trò chơi của bạn sẽ bị căng thẳng hơn.

Đi trước và kích hoạt trình chỉnh sửa mã yêu thích của bạn hoặc IDE. Sau đó tạo tệp

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
5 trong thư mục làm việc hiện tại của bạn:

# tic_tac_toe.py

"""A tic-tac-toe game built with Python and Tkinter."""

Trong suốt hướng dẫn này, bạn sẽ được thêm mã vào tệp này, vì vậy hãy giữ cho nó mở và gần. Nếu bạn muốn lấy toàn bộ mã cho dự án trò chơi tic-tac-toe này, thì bạn có thể nhấp vào phần có thể thu gọn sau và sao chép mã từ nó:

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()

Có toàn bộ mã nguồn trước sẽ cho phép bạn kiểm tra tiến trình của mình trong khi đi qua hướng dẫn.

Ngoài ra, bạn cũng có thể tải xuống mã nguồn trò chơi từ GitHub bằng cách nhấp vào liên kết trong hộp bên dưới:

Bây giờ bạn đã biết mã cuối cùng của trò chơi sẽ như thế nào, đó là thời gian để đảm bảo bạn có phiên bản tkinter phù hợp cho dự án này. Sau đó, bạn sẽ tiếp tục và tạo bảng trò chơi của mình.

Đảm bảo phiên bản tkinter phù hợp

Để hoàn thành dự án này, bạn sẽ sử dụng cài đặt Python tiêu chuẩn. Không cần phải tạo ra một môi trường ảo vì không cần sự phụ thuộc bên ngoài. Gói duy nhất mà bạn cần là Tkinter, đi kèm với thư viện tiêu chuẩn Python.

Tuy nhiên, bạn cần đảm bảo rằng bạn đã cài đặt đúng phiên bản Tkinter. Bạn nên có tkinter lớn hơn hoặc bằng 8,6. Nếu không, trò chơi của bạn đã giành được công việc.

Bạn có thể kiểm tra phiên bản Tkinter hiện tại của mình bằng cách bắt đầu phiên tương tác Python và chạy mã sau:

>>>

>>> import tkinter
>>> tkinter.TkVersion
8.6

Nếu mã này không hiển thị phiên bản lớn hơn hoặc bằng 8.6 cho cài đặt Tkinter của bạn, thì bạn sẽ cần phải sửa nó.

Trên Ubuntu Linux, bạn có thể cần cài đặt gói

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
6 bằng cách sử dụng Trình quản lý gói hệ thống,
# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
7. Điều đó bởi vì thông thường, Ubuntu không bao gồm Tkinter trong cài đặt Python mặc định của nó.

Khi bạn đã cài đặt Tkinter đúng cách, thì bạn cần kiểm tra phiên bản hiện tại của nó. Nếu phiên bản Tkinter thấp hơn 8.6, thì bạn sẽ phải cài đặt một phiên bản Python gần đây hơn bằng cách tải xuống từ trang tải xuống chính thức hoặc bằng cách sử dụng một công cụ như Pyenv hoặc Docker.

Trên macOS và Windows, một tùy chọn đơn giản là cài đặt phiên bản Python lớn hơn hoặc bằng 3.9.8 từ trang tải xuống.

Khi bạn chắc chắn rằng bạn có phiên bản tkinter phù hợp, bạn có thể quay lại trình chỉnh sửa mã của mình và bắt đầu viết mã. Bạn sẽ bắt đầu với lớp Python mà mà sẽ đại diện cho bảng trò chơi tic-tac-toe.

Tạo một lớp để đại diện cho bảng trò chơi

Để xây dựng bảng của trò chơi Tic-Tac-Toe của bạn, bạn sẽ sử dụng lớp

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
8, cho phép bạn tạo cửa sổ chính của ứng dụng Tkinter của bạn. Sau đó, bạn sẽ thêm một màn hình trên khung trên cùng và một lưới các ô bao phủ phần còn lại của cửa sổ chính.

Đi trước và nhập các đối tượng cần thiết và xác định lớp bảng:

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}

Trong đoạn mã này, trước tiên bạn nhập

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
9 dưới dạng
 1# tic_tac_toe.py
 2# ...
 3
 4class TicTacToeBoard(tk.Tk):
 5    # ...
 6
 7    def _create_board_display(self):
 8        display_frame = tk.Frame(master=self)
 9        display_frame.pack(fill=tk.X)
10        self.display = tk.Label(
11            master=display_frame,
12            text="Ready?",
13            font=font.Font(size=28, weight="bold"),
14        )
15        self.display.pack()
0 để đưa tên mô -đun vào không gian tên hiện tại của bạn. Sử dụng chữ viết tắt
 1# tic_tac_toe.py
 2# ...
 3
 4class TicTacToeBoard(tk.Tk):
 5    # ...
 6
 7    def _create_board_display(self):
 8        display_frame = tk.Frame(master=self)
 9        display_frame.pack(fill=tk.X)
10        self.display = tk.Label(
11            master=display_frame,
12            text="Ready?",
13            font=font.Font(size=28, weight="bold"),
14        )
15        self.display.pack()
0 là một thông lệ phổ biến khi sử dụng Tkinter trong mã của bạn.

Sau đó, bạn nhập mô -đun

 1# tic_tac_toe.py
 2# ...
 3
 4class TicTacToeBoard(tk.Tk):
 5    # ...
 6
 7    def _create_board_display(self):
 8        display_frame = tk.Frame(master=self)
 9        display_frame.pack(fill=tk.X)
10        self.display = tk.Label(
11            master=display_frame,
12            text="Ready?",
13            font=font.Font(size=28, weight="bold"),
14        )
15        self.display.pack()
2 trực tiếp từ
# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
9. Bạn sẽ sử dụng mô -đun này sau này trong hướng dẫn này để điều chỉnh phông chữ của màn hình trò chơi của bạn.

Lớp

>>> import tkinter
>>> tkinter.TkVersion
8.6
9 kế thừa từ
# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
8, làm cho nó trở thành một cửa sổ GUI chính thức. Cửa sổ này sẽ đại diện cho bảng trò chơi. Bên trong
 1# tic_tac_toe.py
 2# ...
 3
 4class TicTacToeBoard(tk.Tk):
 5    # ...
 6
 7    def _create_board_display(self):
 8        display_frame = tk.Frame(master=self)
 9        display_frame.pack(fill=tk.X)
10        self.display = tk.Label(
11            master=display_frame,
12            text="Ready?",
13            font=font.Font(size=28, weight="bold"),
14        )
15        self.display.pack()
6, trước tiên bạn gọi phương thức siêu lớp
 1# tic_tac_toe.py
 2# ...
 3
 4class TicTacToeBoard(tk.Tk):
 5    # ...
 6
 7    def _create_board_display(self):
 8        display_frame = tk.Frame(master=self)
 9        display_frame.pack(fill=tk.X)
10        self.display = tk.Label(
11            master=display_frame,
12            text="Ready?",
13            font=font.Font(size=28, weight="bold"),
14        )
15        self.display.pack()
6 để khởi tạo đúng lớp cha. Để làm điều này, bạn sử dụng hàm Super () tích hợp.

Thuộc tính

 1# tic_tac_toe.py
 2# ...
 3
 4class TicTacToeBoard(tk.Tk):
 5    # ...
 6
 7    def _create_board_display(self):
 8        display_frame = tk.Frame(master=self)
 9        display_frame.pack(fill=tk.X)
10        self.display = tk.Label(
11            master=display_frame,
12            text="Ready?",
13            font=font.Font(size=28, weight="bold"),
14        )
15        self.display.pack()
8 của
# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
8 xác định văn bản sẽ hiển thị trên thanh tiêu đề cửa sổ. Trong ví dụ này, bạn đặt tiêu đề thành chuỗi
 1# tic_tac_toe.py
 2# ...
 3
 4class TicTacToeBoard(tk.Tk):
 5    # ...
 6
 7    def _create_board_grid(self):
 8        grid_frame = tk.Frame(master=self)
 9        grid_frame.pack()
10        for row in range(3):
11            self.rowconfigure(row, weight=1, minsize=50)
12            self.columnconfigure(row, weight=1, minsize=75)
13            for col in range(3):
14                button = tk.Button(
15                    master=grid_frame,
16                    text="",
17                    font=font.Font(size=36, weight="bold"),
18                    fg="black",
19                    width=3,
20                    height=2,
21                    highlightbackground="lightblue",
22                )
23                self._cells[button] = (row, col)
24                button.grid(
25                    row=row,
26                    column=col,
27                    padx=5,
28                    pady=5,
29                    sticky="nsew"
30                )
0.

Thuộc tính không công khai

 1# tic_tac_toe.py
 2# ...
 3
 4class TicTacToeBoard(tk.Tk):
 5    # ...
 6
 7    def _create_board_grid(self):
 8        grid_frame = tk.Frame(master=self)
 9        grid_frame.pack()
10        for row in range(3):
11            self.rowconfigure(row, weight=1, minsize=50)
12            self.columnconfigure(row, weight=1, minsize=75)
13            for col in range(3):
14                button = tk.Button(
15                    master=grid_frame,
16                    text="",
17                    font=font.Font(size=36, weight="bold"),
18                    fg="black",
19                    width=3,
20                    height=2,
21                    highlightbackground="lightblue",
22                )
23                self._cells[button] = (row, col)
24                button.grid(
25                    row=row,
26                    column=col,
27                    padx=5,
28                    pady=5,
29                    sticky="nsew"
30                )
1 giữ một từ điển trống ban đầu. Từ điển này sẽ ánh xạ các nút hoặc ô trên bảng trò chơi theo tọa độ tương ứng của chúng, ROW và cột trên lưới. Các tọa độ này sẽ là số nguyên phản chiếu hàng và cột nơi sẽ xuất hiện một nút nhất định.

Để tiếp tục với bảng trò chơi, bây giờ bạn cần tạo một màn hình nơi bạn có thể cung cấp thông tin về trạng thái và kết quả của trò chơi. Đối với màn hình này, bạn sẽ sử dụng tiện ích

 1# tic_tac_toe.py
 2# ...
 3
 4class TicTacToeBoard(tk.Tk):
 5    # ...
 6
 7    def _create_board_grid(self):
 8        grid_frame = tk.Frame(master=self)
 9        grid_frame.pack()
10        for row in range(3):
11            self.rowconfigure(row, weight=1, minsize=50)
12            self.columnconfigure(row, weight=1, minsize=75)
13            for col in range(3):
14                button = tk.Button(
15                    master=grid_frame,
16                    text="",
17                    font=font.Font(size=36, weight="bold"),
18                    fg="black",
19                    width=3,
20                    height=2,
21                    highlightbackground="lightblue",
22                )
23                self._cells[button] = (row, col)
24                button.grid(
25                    row=row,
26                    column=col,
27                    padx=5,
28                    pady=5,
29                    sticky="nsew"
30                )
2 làm bảng hiển thị và tiện ích
 1# tic_tac_toe.py
 2# ...
 3
 4class TicTacToeBoard(tk.Tk):
 5    # ...
 6
 7    def _create_board_grid(self):
 8        grid_frame = tk.Frame(master=self)
 9        grid_frame.pack()
10        for row in range(3):
11            self.rowconfigure(row, weight=1, minsize=50)
12            self.columnconfigure(row, weight=1, minsize=75)
13            for col in range(3):
14                button = tk.Button(
15                    master=grid_frame,
16                    text="",
17                    font=font.Font(size=36, weight="bold"),
18                    fg="black",
19                    width=3,
20                    height=2,
21                    highlightbackground="lightblue",
22                )
23                self._cells[button] = (row, col)
24                button.grid(
25                    row=row,
26                    column=col,
27                    padx=5,
28                    pady=5,
29                    sticky="nsew"
30                )
3 để hiển thị thông tin cần thiết.

Bây giờ hãy tiếp tục và thêm phương thức sau vào lớp

>>> import tkinter
>>> tkinter.TkVersion
8.6
9 của bạn:

 1# tic_tac_toe.py
 2# ...
 3
 4class TicTacToeBoard(tk.Tk):
 5    # ...
 6
 7    def _create_board_display(self):
 8        display_frame = tk.Frame(master=self)
 9        display_frame.pack(fill=tk.X)
10        self.display = tk.Label(
11            master=display_frame,
12            text="Ready?",
13            font=font.Font(size=28, weight="bold"),
14        )
15        self.display.pack()

Ở đây, một sự cố về những gì phương thức này làm từng dòng:

  • Dòng 8 tạo ra một đối tượng

     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    2 để giữ màn hình trò chơi. Lưu ý rằng đối số
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    6 được đặt thành
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    7, điều đó có nghĩa là cửa sổ chính của trò chơi sẽ là cha mẹ của khung.
    creates a
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    2 object to hold the game display. Note that the
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    6 argument is set to
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    7, which means that the game’s main window will be the frame’s parent.

  • Dòng 9 sử dụng Trình quản lý hình học

     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    8 để đặt đối tượng khung vào cửa sổ chính Đường viền trên cùng. Bằng cách đặt đối số
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    9 thành
    # tic_tac_toe.py
    # ...
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._create_board_display()
            self._create_board_grid()
    
    0, bạn đảm bảo rằng khi người dùng thay đổi kích thước cửa sổ, khung sẽ lấp đầy toàn bộ chiều rộng của nó.
    uses the
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    8 geometry manager to place the frame object on the main window’s top border. By setting the
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    9 argument to
    # tic_tac_toe.py
    # ...
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._create_board_display()
            self._create_board_grid()
    
    0, you ensure that when the user resizes the window, the frame will fill its entire width.

  • Dòng 10 đến 14 Tạo đối tượng

     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    3. Nhãn này cần sống bên trong đối tượng khung, vì vậy bạn đặt đối số
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    6 của nó thành khung thực tế. Nhãn ban đầu sẽ hiển thị văn bản
    # tic_tac_toe.py
    # ...
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._create_board_display()
            self._create_board_grid()
    
    3, cho thấy trò chơi đã sẵn sàng để đi và người chơi có thể bắt đầu một trận đấu mới. Cuối cùng, bạn thay đổi kích thước phông chữ của nhãn thành
    # tic_tac_toe.py
    # ...
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._create_board_display()
            self._create_board_grid()
    
    4 pixel và làm cho nó in đậm.
    create a
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    3 object. This label needs to live inside the frame object, so you set its
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    6 argument to the actual frame. The label will initially show the text
    # tic_tac_toe.py
    # ...
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._create_board_display()
            self._create_board_grid()
    
    3, which indicates that the game is ready to go, and the players can start a new match. Finally, you change the label’s font size to
    # tic_tac_toe.py
    # ...
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._create_board_display()
            self._create_board_grid()
    
    4 pixels and make it bold.

  • Dòng 15 gói nhãn hiển thị bên trong khung bằng trình quản lý hình học

     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    8. packs the display label inside the frame using the
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    8 geometry manager.

Mát mẻ! Bạn đã có màn hình trò chơi. Bây giờ bạn có thể tạo lưới của các ô. Một trò chơi Tic-Tac-Toe cổ điển có một lưới ba tế bào.

Ở đây, một phương pháp tạo ra lưới các ô bằng cách sử dụng các đối tượng

# tic_tac_toe.py
# ...

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._create_board_display()
        self._create_board_grid()
6:

 1# tic_tac_toe.py
 2# ...
 3
 4class TicTacToeBoard(tk.Tk):
 5    # ...
 6
 7    def _create_board_grid(self):
 8        grid_frame = tk.Frame(master=self)
 9        grid_frame.pack()
10        for row in range(3):
11            self.rowconfigure(row, weight=1, minsize=50)
12            self.columnconfigure(row, weight=1, minsize=75)
13            for col in range(3):
14                button = tk.Button(
15                    master=grid_frame,
16                    text="",
17                    font=font.Font(size=36, weight="bold"),
18                    fg="black",
19                    width=3,
20                    height=2,
21                    highlightbackground="lightblue",
22                )
23                self._cells[button] = (row, col)
24                button.grid(
25                    row=row,
26                    column=col,
27                    padx=5,
28                    pady=5,
29                    sticky="nsew"
30                )

Ồ! Phương pháp này làm rất nhiều! Ở đây, một lời giải thích về những gì mỗi dòng làm:

  • Dòng 8 tạo ra một đối tượng

     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    2 để giữ lưới các ô của trò chơi. Bạn đặt đối số
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    6 thành
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    7, điều đó một lần nữa có nghĩa là cửa sổ chính của trò chơi sẽ là cha mẹ của đối tượng khung này.
    creates a
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    2 object to hold the game’s grid of cells. You set the
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    6 argument to
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    7, which again means that the game’s main window will be the parent of this frame object.

  • Dòng 9 sử dụng Trình quản lý hình học

     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    8 để đặt đối tượng khung trên cửa sổ chính. Khung này sẽ chiếm khu vực dưới màn hình trò chơi, tất cả các cách đến cuối cửa sổ. uses the
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    8 geometry manager to place the frame object on the main window. This frame will occupy the area under the game display, all the way to the bottom of the window.

  • Dòng 10 bắt đầu một vòng lặp lặp lại từ

    # tic_tac_toe.py
    # ...
    
    def main():
        """Create the game's board and run its main loop."""
        board = TicTacToeBoard()
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    1 đến
    # tic_tac_toe.py
    # ...
    
    def main():
        """Create the game's board and run its main loop."""
        board = TicTacToeBoard()
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    2. Các số này đại diện cho tọa độ hàng của mỗi ô trong lưới. Hiện tại, bạn sẽ có các hàng
    # tic_tac_toe.py
    # ...
    
    def main():
        """Create the game's board and run its main loop."""
        board = TicTacToeBoard()
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    3 trên lưới. Tuy nhiên, bạn sẽ thay đổi số ma thuật này sau này và cung cấp tùy chọn sử dụng kích thước lưới khác, chẳng hạn như bốn bởi bốn.
    starts a loop that iterates from
    # tic_tac_toe.py
    # ...
    
    def main():
        """Create the game's board and run its main loop."""
        board = TicTacToeBoard()
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    1 to
    # tic_tac_toe.py
    # ...
    
    def main():
        """Create the game's board and run its main loop."""
        board = TicTacToeBoard()
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    2. These numbers represent the row coordinates of each cell in the grid. For now, you’ll have
    # tic_tac_toe.py
    # ...
    
    def main():
        """Create the game's board and run its main loop."""
        board = TicTacToeBoard()
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    3 rows on the grid. However, you’ll change this magic number later and provide the option of using a different grid size, such as four by four.

  • Dòng 11 và 12 cấu hình chiều rộng và kích thước tối thiểu của mỗi ô trên lưới. configure the width and minimum size of every cell on the grid.

  • Dòng 13 vòng trên ba tọa độ cột. Một lần nữa, bạn sử dụng ba cột, nhưng bạn sẽ thay đổi số này sau này để cung cấp sự linh hoạt hơn và loại bỏ các số ma thuật. loops over the three column coordinates. Again you use three columns, but you’ll change this number later to provide more flexibility and get rid of magic numbers.

  • Các dòng 14 đến 22 Tạo một đối tượng

    # tic_tac_toe.py
    # ...
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._create_board_display()
            self._create_board_grid()
    
    6 cho mọi ô trên lưới. Lưu ý rằng bạn đặt một số thuộc tính, bao gồm
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    6,
    # tic_tac_toe.py
    # ...
    
    def main():
        """Create the game's board and run its main loop."""
        board = TicTacToeBoard()
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    6,
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_display(self):
     8        display_frame = tk.Frame(master=self)
     9        display_frame.pack(fill=tk.X)
    10        self.display = tk.Label(
    11            master=display_frame,
    12            text="Ready?",
    13            font=font.Font(size=28, weight="bold"),
    14        )
    15        self.display.pack()
    
    2, v.v.
    create a
    # tic_tac_toe.py
    # ...
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._create_board_display()
            self._create_board_grid()
    
    6 object for every cell on the grid. Note that you set several attributes, including
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    6,
    # tic_tac_toe.py
    # ...
    
    def main():
        """Create the game's board and run its main loop."""
        board = TicTacToeBoard()
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    6,
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_display(self):
     8        display_frame = tk.Frame(master=self)
     9        display_frame.pack(fill=tk.X)
    10        self.display = tk.Label(
    11            master=display_frame,
    12            text="Ready?",
    13            font=font.Font(size=28, weight="bold"),
    14        )
    15        self.display.pack()
    
    2, and so on.

  • Dòng 23 Thêm mọi nút mới vào từ điển

     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    1. Các nút hoạt động như các phím và tọa độ của chúng được biểu hiện là ____ 79, làm việc như các giá trị. adds every new button to the
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    1 dictionary. The buttons work as keys, and their coordinates—expressed as
    # tic_tac_toe.py
    # ...
    
    def main():
        """Create the game's board and run its main loop."""
        board = TicTacToeBoard()
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    9—work as values.

  • Các dòng 24 đến 30 Cuối cùng cũng thêm mọi nút vào cửa sổ chính bằng Trình quản lý hình học

     1# tic_tac_toe.py
     2
     3import tkinter as tk
     4from tkinter import font
     5from typing import NamedTuple
     6
     7class Player(NamedTuple):
     8    label: str
     9    color: str
    10
    11class Move(NamedTuple):
    12    row: int
    13    col: int
    14    label: str = ""
    15
    16# ...
    
    0. finally add every button to the main window using the
     1# tic_tac_toe.py
     2
     3import tkinter as tk
     4from tkinter import font
     5from typing import NamedTuple
     6
     7class Player(NamedTuple):
     8    label: str
     9    color: str
    10
    11class Move(NamedTuple):
    12    row: int
    13    col: int
    14    label: str = ""
    15
    16# ...
    
    0 geometry manager.

Bây giờ bạn đã triển khai

 1# tic_tac_toe.py
 2
 3import tkinter as tk
 4from tkinter import font
 5from typing import NamedTuple
 6
 7class Player(NamedTuple):
 8    label: str
 9    color: str
10
11class Move(NamedTuple):
12    row: int
13    col: int
14    label: str = ""
15
16# ...
1 và
 1# tic_tac_toe.py
 2
 3import tkinter as tk
 4from tkinter import font
 5from typing import NamedTuple
 6
 7class Player(NamedTuple):
 8    label: str
 9    color: str
10
11class Move(NamedTuple):
12    row: int
13    col: int
14    label: str = ""
15
16# ...
2, bạn có thể gọi cho họ từ trình khởi tạo lớp. Đi trước và thêm hai dòng sau vào
 1# tic_tac_toe.py
 2# ...
 3
 4class TicTacToeBoard(tk.Tk):
 5    # ...
 6
 7    def _create_board_display(self):
 8        display_frame = tk.Frame(master=self)
 9        display_frame.pack(fill=tk.X)
10        self.display = tk.Label(
11            master=display_frame,
12            text="Ready?",
13            font=font.Font(size=28, weight="bold"),
14        )
15        self.display.pack()
6 trong lớp
>>> import tkinter
>>> tkinter.TkVersion
8.6
9 của bạn:

# tic_tac_toe.py
# ...

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._create_board_display()
        self._create_board_grid()

Hai dòng này kết hợp bảng trò chơi bằng cách thêm màn hình và lưới các ô. Có phải là tuyệt vời không?

Với những bản cập nhật này, bạn gần như có thể chạy ứng dụng của mình và xem trò chơi Tic-Tac-Toe của bạn sẽ trông như thế nào. Bạn chỉ cần viết thêm một vài dòng mã nồi hơi. Bạn cần khởi tạo

>>> import tkinter
>>> tkinter.TkVersion
8.6
9 và gọi phương thức
 1# tic_tac_toe.py
 2
 3import tkinter as tk
 4from tkinter import font
 5from typing import NamedTuple
 6
 7class Player(NamedTuple):
 8    label: str
 9    color: str
10
11class Move(NamedTuple):
12    row: int
13    col: int
14    label: str = ""
15
16# ...
6 của nó để khởi chạy ứng dụng Tkinter của bạn.

Đi trước và thêm đoạn mã sau vào cuối tệp

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
5 của bạn:

# tic_tac_toe.py
# ...

def main():
    """Create the game's board and run its main loop."""
    board = TicTacToeBoard()
    board.mainloop()

if __name__ == "__main__":
    main()

Snippet mã này xác định chức năng

 1# tic_tac_toe.py
 2
 3import tkinter as tk
 4from tkinter import font
 5from typing import NamedTuple
 6
 7class Player(NamedTuple):
 8    label: str
 9    color: str
10
11class Move(NamedTuple):
12    row: int
13    col: int
14    label: str = ""
15
16# ...
8 cho trò chơi của bạn. Bên trong chức năng này, trước tiên bạn khởi tạo
>>> import tkinter
>>> tkinter.TkVersion
8.6
9 và sau đó chạy vòng chính của nó bằng cách gọi
 1# tic_tac_toe.py
 2
 3import tkinter as tk
 4from tkinter import font
 5from typing import NamedTuple
 6
 7class Player(NamedTuple):
 8    label: str
 9    color: str
10
11class Move(NamedTuple):
12    row: int
13    col: int
14    label: str = ""
15
16# ...
6.

Cấu trúc

# tic_tac_toe.py
import tkinter as tk
from itertools import cycle
from tkinter import font
# ...

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

class TicTacToeBoard(tk.Tk):
    # ...
1 là một mẫu phổ biến trong các ứng dụng Python. Nó cho phép bạn kiểm soát việc thực thi mã của bạn. Trong trường hợp này, cuộc gọi đến
 1# tic_tac_toe.py
 2
 3import tkinter as tk
 4from tkinter import font
 5from typing import NamedTuple
 6
 7class Player(NamedTuple):
 8    label: str
 9    color: str
10
11class Move(NamedTuple):
12    row: int
13    col: int
14    label: str = ""
15
16# ...
8 sẽ chỉ xảy ra nếu bạn chạy tệp
# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
4 dưới dạng chương trình thực thi, trái ngược với mô -đun có thể nhập.

Đó là nó! Bây giờ bạn đã sẵn sàng để chạy trò chơi của bạn lần đầu tiên. Tất nhiên, trò chơi không thể chơi được, nhưng bảng đã sẵn sàng. Để chạy trò chơi, hãy tiếp tục và thực hiện lệnh sau trên dòng lệnh của bạn:

Khi bạn đã chạy lệnh này, thì bạn sẽ nhận được cửa sổ sau trên màn hình của mình:

Hướng dẫn tic tac toe python beginner - tic tac toe python mới bắt đầu

Mát mẻ! Trò chơi tic-tac-toe của bạn đang bắt đầu trông giống như thật. Bây giờ bạn cần làm cho cửa sổ này phản ứng với các hành động của người chơi trên bảng.

Bước 2: Thiết lập logic trò chơi tic-tac-toe trong Python

Cho đến thời điểm này, bạn đã kết hợp một bảng trò chơi Tic-Tac-Toe phù hợp bằng Tkinter. Bây giờ bạn cần phải nghĩ về cách đối phó với logic trò chơi. Logic này sẽ bao gồm mã xử lý một người chơi di chuyển và xác định xem người chơi này có thắng trò chơi hay không.

Một số ý tưởng là chìa khóa khi thực hiện logic của một trò chơi tic-tac-toe. Đầu tiên, bạn cần một đại diện hợp lệ của người chơi và động thái của họ. Bạn cũng cần một lớp cấp cao hơn để thể hiện chính trò chơi. Trong phần này, bạn sẽ xác định các lớp cho ba khái niệm logic này.players and their moves. You also need a higher-level class to represent the game itself. In this section, you’ll define classes for these three logic concepts.

Bạn có thể tải xuống mã nguồn cho bước này bằng cách nhấp vào liên kết bên dưới và điều hướng đến thư mục

# tic_tac_toe.py
import tkinter as tk
from itertools import cycle
from tkinter import font
# ...

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

class TicTacToeBoard(tk.Tk):
    # ...
4:

Xác định các lớp học cho người chơi và các bước đi của họ

Trong vòng đầu tiên, bạn sẽ xác định các lớp để đại diện cho người chơi và các bước di chuyển của họ trên bảng trò chơi. Những lớp học này sẽ khá xương trần. Tất cả những gì họ cần là một vài thuộc tính mỗi. Họ không cần phải có bất kỳ phương pháp nào.players and their moves on the game board. These classes will be pretty bare-bones. All they need is a few attributes each. They don’t even need to have any methods.

Bạn có thể sử dụng một vài công cụ để xây dựng các lớp đáp ứng các yêu cầu này. Ví dụ: bạn có thể sử dụng một lớp dữ liệu hoặc một tuple có tên. Trong hướng dẫn này, bạn sẽ sử dụng một tuple có tên cho cả hai lớp vì loại lớp này cung cấp tất cả những gì bạn cần.

Thay vì sử dụng

# tic_tac_toe.py
import tkinter as tk
from itertools import cycle
from tkinter import font
# ...

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

class TicTacToeBoard(tk.Tk):
    # ...
5 cổ điển từ mô -đun
# tic_tac_toe.py
import tkinter as tk
from itertools import cycle
from tkinter import font
# ...

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

class TicTacToeBoard(tk.Tk):
    # ...
6, bạn sẽ sử dụng lớp
# tic_tac_toe.py
import tkinter as tk
from itertools import cycle
from tkinter import font
# ...

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

class TicTacToeBoard(tk.Tk):
    # ...
7 từ
# tic_tac_toe.py
import tkinter as tk
from itertools import cycle
from tkinter import font
# ...

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

class TicTacToeBoard(tk.Tk):
    # ...
8 như một cách để cung cấp thông tin gợi ý loại ban đầu trong các lớp của bạn.

Quay trở lại Trình chỉnh sửa mã của bạn và thêm mã sau khi bắt đầu tệp

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
5 của bạn:

 1# tic_tac_toe.py
 2
 3import tkinter as tk
 4from tkinter import font
 5from typing import NamedTuple
 6
 7class Player(NamedTuple):
 8    label: str
 9    color: str
10
11class Move(NamedTuple):
12    row: int
13    col: int
14    label: str = ""
15
16# ...

Ở đây, một sự cố của đoạn mã này:

  • Dòng 5 Nhập khẩu

    # tic_tac_toe.py
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    # ...
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
    class TicTacToeBoard(tk.Tk):
        # ...
    
    7 từ
    # tic_tac_toe.py
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    # ...
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
    class TicTacToeBoard(tk.Tk):
        # ...
    
    8.
    imports
    # tic_tac_toe.py
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    # ...
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
    class TicTacToeBoard(tk.Tk):
        # ...
    
    7 from
    # tic_tac_toe.py
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    # ...
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
    class TicTacToeBoard(tk.Tk):
        # ...
    
    8.

  • Dòng 7 đến 9 Xác định lớp

    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    02. Thuộc tính ____103 sẽ lưu trữ các dấu hiệu trình phát cổ điển, X và O. Thuộc tính
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    04 sẽ chứa một chuỗi có màu tkinter. Bạn sẽ sử dụng màu này để xác định người chơi đích trên bảng trò chơi.
    define the
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    02 class. The
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    03 attribute will store the classic player signs, X and O. The
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    04 attribute will hold a string with a Tkinter color. You’ll use this color to identify the target player on the game board.

  • Dòng 11 đến 14 Xác định lớp

    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    05. Các thuộc tính
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    06 và
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    07 sẽ giữ các tọa độ xác định tế bào mục tiêu di chuyển. Thuộc tính
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    03 sẽ giữ dấu hiệu xác định trình phát, X hoặc O. Lưu ý rằng
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    03 mặc định cho chuỗi trống,
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    10, điều đó có nghĩa là động thái cụ thể này vẫn chưa được phát.
    define the
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    05 class. The
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    06 and
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    07 attributes will hold the coordinates that identify the move’s target cell. The
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    03 attribute will hold the sign that identifies the player, X or O. Note that
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    03 defaults to the empty string,
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    10, which means that this specific move hasn’t been played yet.

Với hai lớp này, bây giờ bạn có thể xác định lớp mà bạn sẽ sử dụng để đại diện cho logic trò chơi.

Tạo một lớp để đại diện cho logic trò chơi

Trong phần này, bạn sẽ xác định một lớp để quản lý logic trò chơi. Lớp học này sẽ chăm sóc xử lý các động tác, tìm người chiến thắng, chuyển đổi người chơi và thực hiện một vài nhiệm vụ khác. Quay lại tệp

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
5 của bạn và thêm lớp sau ngay trước lớp
>>> import tkinter
>>> tkinter.TkVersion
8.6
9 của bạn:

# tic_tac_toe.py
import tkinter as tk
from itertools import cycle
from tkinter import font
# ...

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

class TicTacToeBoard(tk.Tk):
    # ...

Tại đây, trước tiên bạn nhập

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
13 từ mô -đun
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
14. Sau đó, bạn xác định
# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
0, trình khởi tạo có hai đối số,
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
16 và
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
17. Đối số
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
16 sẽ giữ một bộ của hai đối tượng
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
02, đại diện cho người chơi X và O. Đối số này mặc định là
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
20, một hằng số mà bạn sẽ xác định trong giây lát.

Đối số

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
17 sẽ giữ một số đại diện cho kích thước của bảng trò chơi. Trong một trò chơi Tic-Tac-Toe cổ điển, kích thước này sẽ là
# tic_tac_toe.py
# ...

def main():
    """Create the game's board and run its main loop."""
    board = TicTacToeBoard()
    board.mainloop()

if __name__ == "__main__":
    main()
3. Trong lớp của bạn, đối số mặc định là
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
23, một hằng số khác mà bạn sẽ xác định sớm.

Bên trong

 1# tic_tac_toe.py
 2# ...
 3
 4class TicTacToeBoard(tk.Tk):
 5    # ...
 6
 7    def _create_board_display(self):
 8        display_frame = tk.Frame(master=self)
 9        display_frame.pack(fill=tk.X)
10        self.display = tk.Label(
11            master=display_frame,
12            text="Ready?",
13            font=font.Font(size=28, weight="bold"),
14        )
15        self.display.pack()
6, bạn xác định các thuộc tính phiên bản sau:

Thuộc tínhSự mô tả
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
25
Một bộ lặp theo chu kỳ trên bộ tup đầu vào của
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
16
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
27
Kích thước bảng
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
28
Người chơi hiện tại
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
29
Sự kết hợp của các tế bào xác định người chiến thắng
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
30
Danh sách người chơi di chuyển trong một trò chơi nhất định
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
31
Một biến boolean để xác định xem trò chơi có người chiến thắng hay không
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
32
Một danh sách chứa các kết hợp ô xác định chiến thắng

Thuộc tính

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
25 gọi
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
13 từ mô -đun
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
14. Chức năng này lấy một sự khác biệt như một đối số và trả về một trình lặp lại mang lại theo chu kỳ các mục từ đầu vào có thể điều chỉnh được. Trong trường hợp này, đối số của
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
13 là bộ phận của người chơi mặc định được truyền qua đối số
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
16. Khi bạn trải qua hướng dẫn này, bạn sẽ tìm hiểu thêm về tất cả các thuộc tính trong bảng trên.

Về dòng cuối cùng trong

 1# tic_tac_toe.py
 2# ...
 3
 4class TicTacToeBoard(tk.Tk):
 5    # ...
 6
 7    def _create_board_display(self):
 8        display_frame = tk.Frame(master=self)
 9        display_frame.pack(fill=tk.X)
10        self.display = tk.Label(
11            master=display_frame,
12            text="Ready?",
13            font=font.Font(size=28, weight="bold"),
14        )
15        self.display.pack()
6, nó gọi
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
39, đây là phương pháp mà bạn cũng sẽ xác định trong một khoảnh khắc.

Bây giờ hãy tiếp tục và xác định các hằng số sau ngay dưới lớp

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
05:

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
0

Như bạn đã học,

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
23 giữ kích thước của bảng Tic-Tac-Toe. Thông thường, kích thước này là
# tic_tac_toe.py
# ...

def main():
    """Create the game's board and run its main loop."""
    board = TicTacToeBoard()
    board.mainloop()

if __name__ == "__main__":
    main()
3. Vì vậy, bạn sẽ có một lưới ba tế bào trên bảng.

Mặt khác,

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
20 xác định một bộ hai mặt hàng. Mỗi mục đại diện cho một người chơi trong trò chơi. Các thuộc tính
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
03 và
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
04 của mỗi người chơi được đặt thành các giá trị phù hợp. Người chơi X sẽ có màu xanh và người chơi O sẽ có màu xanh lá cây.

Thiết lập bảng trò chơi trừu tượng

Quản lý trạng thái trò chơi trong mỗi thời điểm là một bước cơ bản trong logic trò chơi. Bạn cần theo dõi mọi di chuyển trên bảng. Để thực hiện việc này, bạn sẽ sử dụng thuộc tính

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
30 mà bạn sẽ cập nhật bất cứ khi nào người chơi thực hiện di chuyển.

Bạn cũng cần xác định kết hợp ô nào trên bảng xác định chiến thắng. Bạn sẽ lưu trữ các kết hợp này trong thuộc tính

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
32.

Ở đây, phương thức

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
39, tính toán các giá trị ban đầu cho
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
30 và
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
32:

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
1

Trong

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
39, bạn sử dụng danh sách hiểu để cung cấp danh sách ban đầu các giá trị cho
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
30. Sự hiểu biết tạo ra một danh sách các danh sách. Mỗi danh sách bên trong sẽ chứa các đối tượng
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
05 trống. Một động thái trống lưu trữ tọa độ của ô chứa của nó và một chuỗi trống là nhãn người chơi ban đầu.

Dòng cuối cùng của phương thức này gọi

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
54 và gán giá trị trả về của nó thành
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
32. Bạn sẽ thực hiện phương pháp mới này trong phần sau.

Tìm ra các kết hợp chiến thắng

Trên một bảng Tic-Tac-Toe cổ điển, bạn sẽ có tám kết hợp chiến thắng có thể. Về cơ bản, chúng là các hàng, cột và đường chéo của bảng. Hình minh họa sau đây cho thấy những kết hợp chiến thắng này:

Hướng dẫn tic tac toe python beginner - tic tac toe python mới bắt đầu

Làm thế nào bạn có được tọa độ của tất cả các kết hợp này bằng mã Python? Có một số cách để làm điều đó. Trong mã bên dưới, bạn sẽ sử dụng bốn toàn bộ danh sách để có được tất cả các kết hợp chiến thắng có thể có:

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
2

Đầu vào chính cho phương pháp này là thuộc tính

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
30. Theo mặc định, thuộc tính này sẽ giữ một danh sách chứa ba người phụ. Mỗi người đăng ký sẽ đại diện cho một hàng trên lưới và có ba đối tượng
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
05 trong đó.

Sự hiểu biết đầu tiên lặp lại trên các hàng trên lưới, có được tọa độ của mọi ô và xây dựng một nhóm tọa độ. Mỗi tọa độ tọa độ đại diện cho một sự kết hợp chiến thắng. Sự hiểu biết thứ hai tạo ra những người con chứa tọa độ của mỗi ô trong các cột lưới.

Các khái niệm thứ ba và thứ tư sử dụng một cách tiếp cận tương tự để có được tọa độ của mọi ô trong các đường chéo bảng. Cuối cùng, phương thức trả về một danh sách các danh sách chứa tất cả các kết hợp chiến thắng có thể có trên bảng Tic-Tac-Toe.

Với thiết lập ban đầu này cho bảng trò chơi của bạn, bạn đã sẵn sàng để bắt đầu suy nghĩ về việc xử lý các động tác của người chơi.

Bước 3: Xử lý người chơi di chuyển trên trò chơi logic logic

Trong trò chơi Tic-Tac-Toe này, bạn sẽ xử lý một loại sự kiện: người chơi di chuyển. Được dịch sang các thuật ngữ Tkinter, di chuyển của người chơi chỉ là một cú nhấp chuột vào ô đã chọn, được biểu thị bằng một tiện ích nút.players’ moves. Translated to Tkinter terms, a player’s move is just a click on the selected cell, which is represented by a button widget.

Mỗi người chơi di chuyển sẽ kích hoạt một loạt các hoạt động trên lớp

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
0. Các hoạt động này bao gồm:

  • Xác nhận di chuyển
  • Kiểm tra người chiến thắng
  • Kiểm tra một trò chơi bị ràng buộc
  • Đang chuyển người chơi cho bước tiếp theo

Trong các phần sau, bạn sẽ viết mã để xử lý tất cả các hoạt động này trong lớp

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
0 của bạn.

Để tải xuống mã nguồn cho bước này từ GitHub, nhấp vào liên kết bên dưới và điều hướng đến thư mục

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
60:

Xác nhận người chơi di chuyển

Bạn cần xác nhận di chuyển mỗi khi người chơi nhấp vào một ô nhất định trên bảng TIC-TAC-TEE. Câu hỏi là: Điều gì xác định một động thái hợp lệ? Vâng, ít nhất hai điều kiện làm cho một động thái hợp lệ. Người chơi chỉ có thể chơi nếu:

  1. Trò chơi không có người chiến thắng.
  2. Động thái được chọn đã không được chơi.

Đi trước và thêm phương thức sau vào cuối

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
0:

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
3

Phương thức

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
62 lấy một đối tượng
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
05 làm đối số. Ở đây, những gì phần còn lại của phương pháp làm:

  • Dòng 9 Nhận tọa độ

    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    06 và
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    07 từ đầu vào
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    66.
    gets the
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    06 and
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    07 coordinates from the input
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    66.

  • Dòng 10 kiểm tra xem việc di chuyển tại tọa độ hiện tại,

    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    67, vẫn giữ một chuỗi trống làm nhãn của nó. Điều kiện này sẽ là
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    68 nếu không có người chơi nào thực hiện đầu vào
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    66 trước đó.
    checks if the move at the current coordinates,
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    67, still holds an empty string as its label. This condition will be
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    68 if no player has made the input
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    66 before.

  • Dòng 11 kiểm tra nếu trò chơi không có người chiến thắng chưa. checks if the game doesn’t have a winner yet.

Phương pháp này trả về một giá trị boolean là kết quả của việc kiểm tra xem trò chơi có người chiến thắng không và động thái hiện tại chưa được chơi.

Xử lý người chơi di chuyển để tìm một người chiến thắng

Bây giờ, thời gian để bạn xác định xem người chơi có thắng trò chơi hay không sau khi di chuyển cuối cùng của họ. Đây có thể là mối quan tâm chính của bạn với tư cách là nhà thiết kế trò chơi. Tất nhiên, bạn sẽ có nhiều cách khác nhau để tìm hiểu xem một người chơi nhất định đã thắng trò chơi.

Trong dự án này, bạn sẽ sử dụng các ý tưởng sau để xác định người chiến thắng:

  • Mỗi ô trên bảng trò chơi có một đối tượng
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    05 liên quan.
  • Mỗi đối tượng
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    05 có thuộc tính
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    03 xác định người chơi đã thực hiện di chuyển.

Để tìm hiểu xem người chơi cuối cùng đã thắng trò chơi, bạn sẽ kiểm tra xem nhãn của người chơi có có mặt trong tất cả các động tác có thể có trong một kết hợp chiến thắng nhất định hay không.

Hãy tiếp tục và thêm phương thức sau vào lớp

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
0 của bạn:

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
4

Ở đây, một sự cố về những gì phương thức mới này làm từng dòng:

  • Dòng 7 xác định

    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    74, lấy đối tượng
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    05 làm đối số.
    defines
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    74, which takes a
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    05 object as an argument.

  • Dòng 9 Nhận tọa độ

    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    06 và
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    07 từ đầu vào
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    66.
    gets the
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    06 and
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    07 coordinates from the input
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    66.

  • Dòng 10 kiểm tra xem việc di chuyển tại tọa độ hiện tại,

    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    67, vẫn giữ một chuỗi trống làm nhãn của nó. Điều kiện này sẽ là
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    68 nếu không có người chơi nào thực hiện đầu vào
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    66 trước đó.
    assigns the input
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    66 to the item at
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    67 in the list of current moves.

  • Dòng 11 bắt đầu một vòng lặp về các kết hợp chiến thắng. starts a loop over the winning combinations.

  • Các dòng 12 đến 15 chạy một biểu thức máy phát truy xuất tất cả các nhãn từ các động tác trong kết hợp chiến thắng hiện tại. Kết quả sau đó được chuyển đổi thành một đối tượng

    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    81. run a generator expression that retrieves all the labels from the moves in the current winning combination. The result is then converted into a
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    81 object.

  • Dòng 16 xác định một biểu thức boolean kiểm tra xem động thái hiện tại có xác định chiến thắng hay không. Kết quả được lưu trữ trong

    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    82. defines a Boolean expression that checks if the current move determined a win or not. The result is stored in
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    82.

  • Dòng 17 Kiểm tra nội dung của

    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    82. Nếu biến giữ
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    68, thì
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    31 được đặt thành
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    68 và
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    29 được đặt thành kết hợp hiện tại. Sau đó, vòng lặp phá vỡ và chức năng chấm dứt.
    checks the content of
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    82. If the variable holds
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    68, then
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    31 is set to
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    68 and
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    29 is set to the current combination. Then the loop breaks and the function terminates.

Trên các dòng 12 đến 16, một vài điểm và ý tưởng cần làm rõ. Để hiểu rõ hơn các dòng 12 đến 15, hãy nói rằng tất cả các nhãn trong các động tác được liên kết với các ô của tổ hợp chiến thắng hiện tại giữ X. Trong trường hợp đó, biểu thức máy phát sẽ mang lại ba nhãn x.

Khi bạn cung cấp chức năng

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
88 tích hợp với một số phiên bản X, bạn sẽ nhận được một tập hợp với một phiên bản X. Bộ don don cho phép các giá trị lặp lại.

Vì vậy, nếu tập hợp trong

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
89 chứa một giá trị khác với chuỗi trống, thì bạn có một người chiến thắng. Trong ví dụ này, người chiến thắng đó sẽ là người chơi có nhãn X. Dòng 16 kiểm tra cả hai điều kiện này.

Để kết thúc chủ đề tìm kiếm người chiến thắng trong trò chơi Tic-Tac-Toe của bạn, hãy tiếp tục và thêm phương pháp sau vào cuối lớp

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
0 của bạn:

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
5

Phương pháp này trả về giá trị Boolean được lưu trữ trong

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
31 bất cứ khi nào bạn cần kiểm tra xem trận đấu hiện tại có người chiến thắng hay không. Bạn sẽ sử dụng phương pháp này sau này trong hướng dẫn này.

Kiểm tra các trò chơi bị ràng buộc

Trong trò chơi Tic-Tac-Toe, nếu người chơi chơi trên tất cả các ô và ở đó, không có người chiến thắng nào, thì trò chơi sẽ bị trói. Vì vậy, bạn có hai điều kiện để kiểm tra trước khi khai báo trò chơi là ràng buộc:

  1. Tất cả các động thái có thể đã được chơi.
  2. Trò chơi không có người chiến thắng.

Đi trước và thêm phương thức sau vào cuối

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
0 để kiểm tra các điều kiện này:

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
6

Bên trong

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
93, trước tiên bạn kiểm tra xem trò chơi chưa có người chiến thắng nào không. Sau đó, bạn sử dụng chức năng
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
94 tích hợp để kiểm tra xem tất cả các động tác trong
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
30 có nhãn khác với chuỗi trống không. Nếu đây là trường hợp, thì tất cả các ô có thể đã được phát. Nếu cả hai điều kiện là đúng, thì trò chơi được buộc.

Chuyển đổi người chơi giữa các lượt

Mỗi khi người chơi thực hiện một động thái hợp lệ, bạn cần chuyển đổi trình phát hiện tại để người chơi khác có thể thực hiện bước tiếp theo. Để cung cấp chức năng này, hãy tiếp tục và thêm phương thức sau vào lớp

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
0 của bạn:

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
7

Bởi vì

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
25 giữ một trình lặp lại các vòng lặp theo chu kỳ trên hai người chơi mặc định, bạn có thể gọi
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
98 trên trình lặp lại này để có được trình phát tiếp theo bất cứ khi nào bạn cần. Cơ chế chuyển đổi này sẽ cho phép người chơi tiếp theo thay phiên nhau và tiếp tục trò chơi.

Bước 4: Xử lý người chơi di chuyển trên bảng trò chơi

Tại thời điểm này, bạn có thể xử lý các cầu thủ di chuyển trên logic trò chơi. Bây giờ bạn phải kết nối logic này với chính bảng trò chơi. Bạn cũng cần viết mã để làm cho bảng phản hồi với các động tác của người chơi.

Đầu tiên, hãy tiếp tục và đưa logic trò chơi vào bảng trò chơi. Để thực hiện việc này, hãy cập nhật lớp

>>> import tkinter
>>> tkinter.TkVersion
8.6
9 như trong mã bên dưới:

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
8

Trong đoạn mã này, trước tiên bạn thêm đối số

>>> import tkinter
>>> tkinter.TkVersion
8.6
00 vào trình khởi tạo
>>> import tkinter
>>> tkinter.TkVersion
8.6
9. Sau đó, bạn gán đối số này cho một thuộc tính thể hiện,
>>> import tkinter
>>> tkinter.TkVersion
8.6
02, sẽ cho phép bạn truy cập đầy đủ vào logic trò chơi từ bảng trò chơi.

Bản cập nhật thứ hai là sử dụng

>>> import tkinter
>>> tkinter.TkVersion
8.6
03 để đặt kích thước bảng thay vì sử dụng số ma thuật. Bản cập nhật này cũng cho phép bạn sử dụng các kích thước bảng khác nhau. Ví dụ: bạn có thể tạo một lưới bốn bảng, có thể là một trải nghiệm thú vị.

Với những bản cập nhật này, bạn đã sẵn sàng để tìm cách xử lý các cầu thủ di chuyển trên lớp

>>> import tkinter
>>> tkinter.TkVersion
8.6
9.

Như thường lệ, bạn có thể tải xuống mã nguồn cho bước này bằng cách nhấp vào liên kết bên dưới và điều hướng đến thư mục

>>> import tkinter
>>> tkinter.TkVersion
8.6
05:

Xử lý sự kiện di chuyển của người chơi

Phương pháp

 1# tic_tac_toe.py
 2
 3import tkinter as tk
 4from tkinter import font
 5from typing import NamedTuple
 6
 7class Player(NamedTuple):
 8    label: str
 9    color: str
10
11class Move(NamedTuple):
12    row: int
13    col: int
14    label: str = ""
15
16# ...
6 trên lớp
# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
8 chạy những gì mà Lọ gọi là vòng lặp chính hoặc vòng lặp sự kiện. Đây là một vòng lặp vô hạn trong đó tất cả các sự kiện GUI xảy ra. Bên trong vòng lặp này, bạn có thể xử lý các sự kiện trên giao diện người dùng ứng dụng. Một sự kiện là một hành động của người dùng trên GUI, chẳng hạn như Keypress, Chuột di chuyển hoặc nhấp chuột.main loop or event loop. This is an infinite loop in which all the GUI events happen. Inside this loop, you can handle the events on the application’s user interface. An event is a user action on the GUI, such as a keypress, mouse move, or mouse click.

Khi một người chơi trong trò chơi Tic-Tac-Toe của bạn, hãy nhấp vào một ô, một sự kiện nhấp chuột xảy ra bên trong vòng lặp sự kiện trò chơi. Bạn có thể xử lý sự kiện này bằng cách cung cấp một phương thức xử lý thích hợp trên lớp

>>> import tkinter
>>> tkinter.TkVersion
8.6
9 của bạn. Để thực hiện việc này, hãy quay lại trình chỉnh sửa mã của bạn và thêm phương thức
>>> import tkinter
>>> tkinter.TkVersion
8.6
09 sau ở cuối lớp:

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
9

Phương pháp này là cơ bản trong trò chơi tic-tac-toe của bạn bởi vì nó kết hợp gần như tất cả các hành vi logic và gui của trò chơi. Ở đây, một bản tóm tắt về những gì phương pháp này làm:

  • Dòng 7 xác định

    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    10, lấy một đối tượng sự kiện Tkinter làm đối số. defines
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    10, which takes a Tkinter event object as an argument.

  • Dòng 9 lấy tiện ích kích hoạt sự kiện hiện tại. Tiện ích này sẽ là một trong những nút trên lưới bảng. retrieves the widget that triggered the current event. This widget will be one of the buttons on the board grid.

  • Dòng 10 Giải nén nút Tọa độ thành hai biến cục bộ,

    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    11 và
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    12.
    unpacks the button’s coordinates into two local variables,
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    11 and
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    12.

  • Dòng 11 tạo ra một đối tượng

    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    05 mới bằng cách sử dụng
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    11,
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    12 và thuộc tính người chơi hiện tại ____ ____103 làm đối số.
    creates a new
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    05 object using
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    11,
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    12, and the current player’s
    """A tic-tac-toe game built with Python and Tkinter."""
    
    import tkinter as tk
    from itertools import cycle
    from tkinter import font
    from typing import NamedTuple
    
    class Player(NamedTuple):
        label: str
        color: str
    
    class Move(NamedTuple):
        row: int
        col: int
        label: str = ""
    
    BOARD_SIZE = 3
    DEFAULT_PLAYERS = (
        Player(label="X", color="blue"),
        Player(label="O", color="green"),
    )
    
    class TicTacToeGame:
        def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
            self._players = cycle(players)
            self.board_size = board_size
            self.current_player = next(self._players)
            self.winner_combo = []
            self._current_moves = []
            self._has_winner = False
            self._winning_combos = []
            self._setup_board()
    
        def _setup_board(self):
            self._current_moves = [
                [Move(row, col) for col in range(self.board_size)]
                for row in range(self.board_size)
            ]
            self._winning_combos = self._get_winning_combos()
    
        def _get_winning_combos(self):
            rows = [
                [(move.row, move.col) for move in row]
                for row in self._current_moves
            ]
            columns = [list(col) for col in zip(*rows)]
            first_diagonal = [row[i] for i, row in enumerate(rows)]
            second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
            return rows + columns + [first_diagonal, second_diagonal]
    
        def toggle_player(self):
            """Return a toggled player."""
            self.current_player = next(self._players)
    
        def is_valid_move(self, move):
            """Return True if move is valid, and False otherwise."""
            row, col = move.row, move.col
            move_was_not_played = self._current_moves[row][col].label == ""
            no_winner = not self._has_winner
            return no_winner and move_was_not_played
    
        def process_move(self, move):
            """Process the current move and check if it's a win."""
            row, col = move.row, move.col
            self._current_moves[row][col] = move
            for combo in self._winning_combos:
                results = set(self._current_moves[n][m].label for n, m in combo)
                is_win = (len(results) == 1) and ("" not in results)
                if is_win:
                    self._has_winner = True
                    self.winner_combo = combo
                    break
    
        def has_winner(self):
            """Return True if the game has a winner, and False otherwise."""
            return self._has_winner
    
        def is_tied(self):
            """Return True if the game is tied, and False otherwise."""
            no_winner = not self._has_winner
            played_moves = (
                move.label for row in self._current_moves for move in row
            )
            return no_winner and all(played_moves)
    
        def reset_game(self):
            """Reset the game state to play again."""
            for row, row_content in enumerate(self._current_moves):
                for col, _ in enumerate(row_content):
                    row_content[col] = Move(row, col)
            self._has_winner = False
            self.winner_combo = []
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self, game):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._game = game
            self._create_menu()
            self._create_board_display()
            self._create_board_grid()
    
        def _create_menu(self):
            menu_bar = tk.Menu(master=self)
            self.config(menu=menu_bar)
            file_menu = tk.Menu(master=menu_bar)
            file_menu.add_command(label="Play Again", command=self.reset_board)
            file_menu.add_separator()
            file_menu.add_command(label="Exit", command=quit)
            menu_bar.add_cascade(label="File", menu=file_menu)
    
        def _create_board_display(self):
            display_frame = tk.Frame(master=self)
            display_frame.pack(fill=tk.X)
            self.display = tk.Label(
                master=display_frame,
                text="Ready?",
                font=font.Font(size=28, weight="bold"),
            )
            self.display.pack()
    
        def _create_board_grid(self):
            grid_frame = tk.Frame(master=self)
            grid_frame.pack()
            for row in range(self._game.board_size):
                self.rowconfigure(row, weight=1, minsize=50)
                self.columnconfigure(row, weight=1, minsize=75)
                for col in range(self._game.board_size):
                    button = tk.Button(
                        master=grid_frame,
                        text="",
                        font=font.Font(size=36, weight="bold"),
                        fg="black",
                        width=3,
                        height=2,
                        highlightbackground="lightblue",
                    )
                    self._cells[button] = (row, col)
                    button.bind("<ButtonPress-1>", self.play)
                    button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
        def play(self, event):
            """Handle a player's move."""
            clicked_btn = event.widget
            row, col = self._cells[clicked_btn]
            move = Move(row, col, self._game.current_player.label)
            if self._game.is_valid_move(move):
                self._update_button(clicked_btn)
                self._game.process_move(move)
                if self._game.is_tied():
                    self._update_display(msg="Tied game!", color="red")
                elif self._game.has_winner():
                    self._highlight_cells()
                    msg = f'Player "{self._game.current_player.label}" won!'
                    color = self._game.current_player.color
                    self._update_display(msg, color)
                else:
                    self._game.toggle_player()
                    msg = f"{self._game.current_player.label}'s turn"
                    self._update_display(msg)
    
        def _update_button(self, clicked_btn):
            clicked_btn.config(text=self._game.current_player.label)
            clicked_btn.config(fg=self._game.current_player.color)
    
        def _update_display(self, msg, color="black"):
            self.display["text"] = msg
            self.display["fg"] = color
    
        def _highlight_cells(self):
            for button, coordinates in self._cells.items():
                if coordinates in self._game.winner_combo:
                    button.config(highlightbackground="red")
    
        def reset_board(self):
            """Reset the game's board to play again."""
            self._game.reset_game()
            self._update_display(msg="Ready?")
            for button in self._cells.keys():
                button.config(highlightbackground="lightblue")
                button.config(text="")
                button.config(fg="black")
    
    def main():
        """Create the game's board and run its main loop."""
        game = TicTacToeGame()
        board = TicTacToeBoard(game)
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    03 attribute as arguments.

  • Dòng 12 bắt đầu một câu lệnh có điều kiện kiểm tra xem người chơi di chuyển có hợp lệ hay không. Nếu việc di chuyển là hợp lệ, thì khối mã

    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    17 sẽ chạy. Nếu không, không có hành động nữa diễn ra. starts a conditional statement that checks if the player’s move is valid or not. If the move is valid, then the
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    17 code block runs. Otherwise, no further action takes place.

  • Dòng 13 Cập nhật nút nhấp chuột bằng cách gọi phương thức

    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    18. Bạn sẽ viết phương pháp này trong phần tiếp theo. Nói tóm lại, phương thức cập nhật văn bản nút Nút để phản ánh nhãn và màu hiện tại của người chơi. updates the clicked button by calling the
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    18 method. You’ll write this method in the next section. In short, the method updates the button’s text to reflect the current player’s label and color.

  • Dòng 14 gọi

    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    19 trên đối tượng
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    02 bằng cách sử dụng di chuyển hiện tại làm đối số.
    calls
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    19 on the
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    02 object using the current move as an argument.

  • Dòng 15 kiểm tra nếu trò chơi bị ràng buộc. Nếu trường hợp đó, thì màn hình trò chơi sẽ được cập nhật tương ứng. checks if the game is tied. If that’s the case, then the game display gets updated accordingly.

  • Dòng 17 kiểm tra xem người chơi hiện tại đã thắng trò chơi. Sau đó, Line 18 nêu bật các ô chiến thắng và dòng 19 đến 21 cập nhật màn hình trò chơi để xác nhận người chiến thắng. checks if the current player has won the game. Then line 18 highlights the winning cells, and lines 19 to 21 update the game display to acknowledge the winner.

  • Dòng 22 chạy nếu trò chơi không bị trói và ở đó không có người chiến thắng. Trong trường hợp này, các dòng 23 đến 25 chuyển đổi trình phát cho bước tiếp theo và cập nhật màn hình để chỉ ra người chơi sẽ chơi tiếp theo. runs if the game isn’t tied and there’s no winner. In this case, lines 23 to 25 toggle the player for the next move and update the display to point out the player who will play next.

Bạn đã gần tới! Với một vài cập nhật và bổ sung, trò chơi Tic-Tac-Toe của bạn sẽ sẵn sàng cho trận đấu đầu tiên của nó.

Bước tiếp theo là kết nối mọi nút trên bảng trò chơi với phương thức

>>> import tkinter
>>> tkinter.TkVersion
8.6
09. Để làm điều này, hãy quay lại phương thức
 1# tic_tac_toe.py
 2
 3import tkinter as tk
 4from tkinter import font
 5from typing import NamedTuple
 6
 7class Player(NamedTuple):
 8    label: str
 9    color: str
10
11class Move(NamedTuple):
12    row: int
13    col: int
14    label: str = ""
15
16# ...
2 và cập nhật nó như trong mã bên dưới:

>>> import tkinter
>>> tkinter.TkVersion
8.6
0

Dòng được tô sáng liên kết sự kiện nhấp chuột của mỗi nút trên bảng trò chơi với phương thức

>>> import tkinter
>>> tkinter.TkVersion
8.6
09. Bằng cách này, bất cứ khi nào người chơi nhấp vào một nút đã cho, phương thức sẽ chạy để xử lý di chuyển và cập nhật trạng thái trò chơi.

Cập nhật bảng trò chơi để phản ánh trạng thái trò chơi

Để hoàn thành mã để xử lý người chơi di chuyển trên bảng trò chơi, bạn cần viết ba phương thức trợ giúp. Các phương pháp này sẽ hoàn thành các hành động sau:

  • Cập nhật nút nhấp chuột
  • Cập nhật màn hình trò chơi
  • Làm nổi bật các tế bào chiến thắng

Để khởi động mọi thứ, hãy tiếp tục và thêm

>>> import tkinter
>>> tkinter.TkVersion
8.6
18 vào
>>> import tkinter
>>> tkinter.TkVersion
8.6
9:

>>> import tkinter
>>> tkinter.TkVersion
8.6
1

Trong đoạn mã này,

>>> import tkinter
>>> tkinter.TkVersion
8.6
18 gọi
>>> import tkinter
>>> tkinter.TkVersion
8.6
27 trên nút đã nhấp để đặt thuộc tính
>>> import tkinter
>>> tkinter.TkVersion
8.6
28 của nó thành nhãn người chơi hiện tại. Phương pháp này cũng đặt màu nền văn bản,
>>> import tkinter
>>> tkinter.TkVersion
8.6
29, thành màu người chơi hiện tại.

Phương pháp trợ giúp tiếp theo để thêm là

>>> import tkinter
>>> tkinter.TkVersion
8.6
30:

>>> import tkinter
>>> tkinter.TkVersion
8.6
2

Trong phương pháp này, thay vì sử dụng

>>> import tkinter
>>> tkinter.TkVersion
8.6
27 để điều chỉnh văn bản và màu sắc của màn hình trò chơi, bạn sử dụng ký hiệu đăng ký theo kiểu từ điển. Sử dụng loại ký hiệu này là một tùy chọn khác mà Tkinter cung cấp để truy cập vào các thuộc tính của Widget.

Cuối cùng, bạn cần một phương pháp trợ giúp để làm nổi bật các tế bào chiến thắng một khi một người chơi nhất định thực hiện một động thái chiến thắng:

>>> import tkinter
>>> tkinter.TkVersion
8.6
3

Vòng lặp bên trong

>>> import tkinter
>>> tkinter.TkVersion
8.6
32 lặp lại các mục trong từ điển
 1# tic_tac_toe.py
 2# ...
 3
 4class TicTacToeBoard(tk.Tk):
 5    # ...
 6
 7    def _create_board_grid(self):
 8        grid_frame = tk.Frame(master=self)
 9        grid_frame.pack()
10        for row in range(3):
11            self.rowconfigure(row, weight=1, minsize=50)
12            self.columnconfigure(row, weight=1, minsize=75)
13            for col in range(3):
14                button = tk.Button(
15                    master=grid_frame,
16                    text="",
17                    font=font.Font(size=36, weight="bold"),
18                    fg="black",
19                    width=3,
20                    height=2,
21                    highlightbackground="lightblue",
22                )
23                self._cells[button] = (row, col)
24                button.grid(
25                    row=row,
26                    column=col,
27                    padx=5,
28                    pady=5,
29                    sticky="nsew"
30                )
1. Từ điển này ánh xạ các nút vào hàng và cột của chúng tọa độ trên lưới bảng. Nếu các tọa độ hiện tại nằm trong sự kết hợp tế bào chiến thắng, thì màu nền của nút được đặt thành
>>> import tkinter
>>> tkinter.TkVersion
8.6
34, làm nổi bật sự kết hợp ô trên bảng.

Với phương pháp trợ giúp cuối cùng này, trò chơi tic-tac-toe của bạn đã sẵn sàng cho trận đấu đầu tiên!

Chạy trò chơi Tic-Tac-Toe của bạn lần đầu tiên

Để kết thúc việc kết hợp logic và giao diện người dùng của trò chơi Tic-Tac-Toe của bạn, bạn cần cập nhật chức năng trò chơi

 1# tic_tac_toe.py
 2
 3import tkinter as tk
 4from tkinter import font
 5from typing import NamedTuple
 6
 7class Player(NamedTuple):
 8    label: str
 9    color: str
10
11class Move(NamedTuple):
12    row: int
13    col: int
14    label: str = ""
15
16# ...
8. Cho đến thời điểm này, bạn chỉ có một đối tượng
>>> import tkinter
>>> tkinter.TkVersion
8.6
9. Bạn cần tạo một đối tượng
# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
0 và chuyển nó cho hàm tạo được cập nhật
>>> import tkinter
>>> tkinter.TkVersion
8.6
9.

Quay lại

 1# tic_tac_toe.py
 2
 3import tkinter as tk
 4from tkinter import font
 5from typing import NamedTuple
 6
 7class Player(NamedTuple):
 8    label: str
 9    color: str
10
11class Move(NamedTuple):
12    row: int
13    col: int
14    label: str = ""
15
16# ...
8 và cập nhật nó như trong mã bên dưới:

>>> import tkinter
>>> tkinter.TkVersion
8.6
4

Trong mã này, dòng được tô sáng đầu tiên tạo ra một thể hiện là

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
0, mà bạn sẽ sử dụng để xử lý logic trò chơi. Dòng được tô sáng thứ hai chuyển thể hiện mới cho hàm tạo lớp
>>> import tkinter
>>> tkinter.TkVersion
8.6
9, đưa logic trò chơi vào bảng trò chơi.

Với những bản cập nhật này, bây giờ bạn có thể chạy trò chơi của mình. Để thực hiện việc này, hãy kích hoạt một cửa sổ thiết bị đầu cuối và điều hướng đến thư mục chứa tệp

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
5 của bạn. Sau đó chạy lệnh sau:

Khi lệnh này đã chạy, thì cửa sổ chính trò chơi của bạn sẽ xuất hiện trên màn hình của bạn. Hãy tiếp tục và thử nó! Nó sẽ hành xử một cái gì đó như thế này:

Ồ! Dự án trò chơi của bạn trông tuyệt vời cho đến nay! Nó cho phép hai người chơi chia sẻ chuột của họ và chơi một trận đấu Tic-Tac-Toe cổ điển. GUI GUI trông đẹp và nói chung, trò chơi hoạt động như mong đợi.

Trong phần sau, bạn sẽ viết mã để cho phép người chơi khởi động lại trò chơi và chơi lại. Bạn cũng sẽ cung cấp tùy chọn thoát khỏi trò chơi.

Bước 5: Cung cấp các tùy chọn để chơi lại và thoát khỏi trò chơi

Trong phần này, bạn sẽ cung cấp cho trò chơi tic-tac-toe của bạn một menu chính. Menu này sẽ có một tùy chọn để khởi động lại trò chơi để người chơi có thể bắt đầu một trận đấu khác. Nó cũng có một tùy chọn để thoát khỏi trò chơi khi người chơi đã chơi xong.main menu. This menu will have an option to restart the game so that the players can start another match. It’ll also have an option to exit the game once the players have finished playing.

Các menu chính thường là một thành phần thiết yếu của nhiều ứng dụng GUI. Vì vậy, học cách tạo ra chúng trong Tkinter là một bài tập tốt để cải thiện các kỹ năng liên quan đến GUI của bạn ngoài chính sự phát triển của trò chơi.

Đây là một ví dụ về cách xây dựng các trò chơi của riêng bạn là một trải nghiệm học tập mạnh mẽ vì nó cho phép bạn tích hợp kiến ​​thức và kỹ năng mà sau này bạn có thể sử dụng trong các dự án không trò chơi khác.

Mã nguồn đầy đủ cho bước này có sẵn để tải xuống. Chỉ cần nhấp vào liên kết bên dưới và điều hướng đến thư mục

>>> import tkinter
>>> tkinter.TkVersion
8.6
43:

Xây dựng thực đơn chính của trò chơi

Để thêm menu chính vào ứng dụng Tkinter, bạn có thể sử dụng lớp

>>> import tkinter
>>> tkinter.TkVersion
8.6
44. Lớp này cho phép bạn tạo một thanh menu trên đầu cửa sổ Tkinter của bạn. Nó cũng cho phép bạn thêm các menu thả xuống vào thanh menu.

Tại đây, mã tạo ra và thêm một menu chính vào trò chơi tic-tac-toe của bạn:

>>> import tkinter
>>> tkinter.TkVersion
8.6
5

Ở đây, những gì mã này làm từng dòng:

  • Dòng 8 xác định một phương thức trợ giúp gọi là

    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    45 để xử lý việc tạo menu ở một nơi duy nhất. defines a helper method called
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    45 to handle the menu creation in a single place.

  • Dòng 9 tạo ra một thể hiện là

    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    46, sẽ hoạt động như thanh menu. creates an instance of
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    46, which will work as the menu bar.

  • Dòng 10 Đặt đối tượng thanh menu làm menu chính của cửa sổ Tkinter hiện tại của bạn. sets the menu bar object as the main menu of your current Tkinter window.

  • Dòng 11 tạo một thể hiện khác của

    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    46 để cung cấp menu tệp. Lưu ý rằng đối số
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    6 trong Trình xây dựng lớp được đặt thành đối tượng thanh menu của bạn.
    creates another instance of
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    46 to provide a File menu. Note that the
     1# tic_tac_toe.py
     2# ...
     3
     4class TicTacToeBoard(tk.Tk):
     5    # ...
     6
     7    def _create_board_grid(self):
     8        grid_frame = tk.Frame(master=self)
     9        grid_frame.pack()
    10        for row in range(3):
    11            self.rowconfigure(row, weight=1, minsize=50)
    12            self.columnconfigure(row, weight=1, minsize=75)
    13            for col in range(3):
    14                button = tk.Button(
    15                    master=grid_frame,
    16                    text="",
    17                    font=font.Font(size=36, weight="bold"),
    18                    fg="black",
    19                    width=3,
    20                    height=2,
    21                    highlightbackground="lightblue",
    22                )
    23                self._cells[button] = (row, col)
    24                button.grid(
    25                    row=row,
    26                    column=col,
    27                    padx=5,
    28                    pady=5,
    29                    sticky="nsew"
    30                )
    
    6 argument in the class constructor is set to your menu bar object.

  • Các dòng 12 đến 15 Thêm tùy chọn menu mới vào menu Tệp bằng phương thức

    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    49. Tùy chọn mới này sẽ có nhãn
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    50. Khi người dùng nhấp vào tùy chọn này, ứng dụng sẽ chạy phương thức
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    51 mà bạn cung cấp thông qua đối số
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    52. Bạn sẽ viết phương pháp này trong phần sau.
    add a new menu option to the File menu using the
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    49 method. This new option will have the label
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    50. When a user clicks this option, the application will run the
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    51 method, which you provided through the
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    52 argument. You’ll write this method in the following section.

  • Dòng 16 Thêm một bộ phân cách menu bằng phương pháp

    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    53. Dấu tách rất hữu ích khi bạn cần tách các nhóm lệnh liên quan trong menu thả xuống nhất định. adds a menu separator using the
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    53 method. Separators are useful when you need to separate groups of related commands in a given dropdown menu.

  • Dòng 17 Thêm lệnh thoát vào menu Tệp. Lệnh này sẽ làm cho lối thoát trò chơi bằng cách gọi hàm

    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    54. adds an Exit command to the File menu. This command will make the game exit by calling the
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    54 function.

  • Dòng 18 Cuối cùng cũng thêm menu tệp vào thanh menu bằng cách gọi

    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    55 với các đối số thích hợp. finally adds the File menu to the menu bar by calling
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    55 with appropriate arguments.

Để thực sự thêm menu chính vào cửa sổ chính trò chơi của bạn, bạn cần gọi

>>> import tkinter
>>> tkinter.TkVersion
8.6
45 từ bộ khởi tạo của
>>> import tkinter
>>> tkinter.TkVersion
8.6
9. Vì vậy, hãy tiếp tục và thêm dòng sau vào phương pháp lớp
 1# tic_tac_toe.py
 2# ...
 3
 4class TicTacToeBoard(tk.Tk):
 5    # ...
 6
 7    def _create_board_display(self):
 8        display_frame = tk.Frame(master=self)
 9        display_frame.pack(fill=tk.X)
10        self.display = tk.Label(
11            master=display_frame,
12            text="Ready?",
13            font=font.Font(size=28, weight="bold"),
14        )
15        self.display.pack()
6:

>>> import tkinter
>>> tkinter.TkVersion
8.6
6

Với bản cập nhật cuối cùng này, menu chính trò chơi của bạn gần như đã sẵn sàng để sử dụng. Tuy nhiên, trước khi sử dụng nó, bạn phải thực hiện phương thức

>>> import tkinter
>>> tkinter.TkVersion
8.6
51. Đó là những gì bạn sẽ làm trong phần sau để cho phép người chơi chơi lại.

Thực hiện tùy chọn chơi lại

Để đặt lại bảng trò chơi và cho phép người chơi chơi lại, bạn cần thêm mã vào cả hai lớp,

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
0 và
>>> import tkinter
>>> tkinter.TkVersion
8.6
9.

Trong lớp logic trò chơi, bạn cần đặt lại thuộc tính

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
30 để giữ danh sách các đối tượng
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
05 trống ban đầu. Bạn cũng cần đặt lại
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
31 và
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
29 cho trạng thái ban đầu của chúng. Mặt khác, trong lớp bảng trò chơi, bạn cần đặt lại màn hình bảng và các ô về trạng thái ban đầu của chúng.

Quay lại

# tic_tac_toe.py

import tkinter as tk
from tkinter import font

class TicTacToeBoard(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
0 trong Trình chỉnh sửa mã của bạn và thêm phương thức sau ngay ở cuối lớp:

>>> import tkinter
>>> tkinter.TkVersion
8.6
7

Vòng lặp

>>> import tkinter
>>> tkinter.TkVersion
8.6
67 trong
>>> import tkinter
>>> tkinter.TkVersion
8.6
68 đặt tất cả các di chuyển hiện tại đến một đối tượng
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
05 trống. Một đặc điểm chính của di chuyển trống rỗng là thuộc tính ____103 của nó giữ chuỗi trống,
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
10.

Sau khi cập nhật các động tác hiện tại, các phương thức đặt

"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
31 thành
>>> import tkinter
>>> tkinter.TkVersion
8.6
73 và
"""A tic-tac-toe game built with Python and Tkinter."""

import tkinter as tk
from itertools import cycle
from tkinter import font
from typing import NamedTuple

class Player(NamedTuple):
    label: str
    color: str

class Move(NamedTuple):
    row: int
    col: int
    label: str = ""

BOARD_SIZE = 3
DEFAULT_PLAYERS = (
    Player(label="X", color="blue"),
    Player(label="O", color="green"),
)

class TicTacToeGame:
    def __init__(self, players=DEFAULT_PLAYERS, board_size=BOARD_SIZE):
        self._players = cycle(players)
        self.board_size = board_size
        self.current_player = next(self._players)
        self.winner_combo = []
        self._current_moves = []
        self._has_winner = False
        self._winning_combos = []
        self._setup_board()

    def _setup_board(self):
        self._current_moves = [
            [Move(row, col) for col in range(self.board_size)]
            for row in range(self.board_size)
        ]
        self._winning_combos = self._get_winning_combos()

    def _get_winning_combos(self):
        rows = [
            [(move.row, move.col) for move in row]
            for row in self._current_moves
        ]
        columns = [list(col) for col in zip(*rows)]
        first_diagonal = [row[i] for i, row in enumerate(rows)]
        second_diagonal = [col[j] for j, col in enumerate(reversed(columns))]
        return rows + columns + [first_diagonal, second_diagonal]

    def toggle_player(self):
        """Return a toggled player."""
        self.current_player = next(self._players)

    def is_valid_move(self, move):
        """Return True if move is valid, and False otherwise."""
        row, col = move.row, move.col
        move_was_not_played = self._current_moves[row][col].label == ""
        no_winner = not self._has_winner
        return no_winner and move_was_not_played

    def process_move(self, move):
        """Process the current move and check if it's a win."""
        row, col = move.row, move.col
        self._current_moves[row][col] = move
        for combo in self._winning_combos:
            results = set(self._current_moves[n][m].label for n, m in combo)
            is_win = (len(results) == 1) and ("" not in results)
            if is_win:
                self._has_winner = True
                self.winner_combo = combo
                break

    def has_winner(self):
        """Return True if the game has a winner, and False otherwise."""
        return self._has_winner

    def is_tied(self):
        """Return True if the game is tied, and False otherwise."""
        no_winner = not self._has_winner
        played_moves = (
            move.label for row in self._current_moves for move in row
        )
        return no_winner and all(played_moves)

    def reset_game(self):
        """Reset the game state to play again."""
        for row, row_content in enumerate(self._current_moves):
            for col, _ in enumerate(row_content):
                row_content[col] = Move(row, col)
        self._has_winner = False
        self.winner_combo = []

class TicTacToeBoard(tk.Tk):
    def __init__(self, game):
        super().__init__()
        self.title("Tic-Tac-Toe Game")
        self._cells = {}
        self._game = game
        self._create_menu()
        self._create_board_display()
        self._create_board_grid()

    def _create_menu(self):
        menu_bar = tk.Menu(master=self)
        self.config(menu=menu_bar)
        file_menu = tk.Menu(master=menu_bar)
        file_menu.add_command(label="Play Again", command=self.reset_board)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=quit)
        menu_bar.add_cascade(label="File", menu=file_menu)

    def _create_board_display(self):
        display_frame = tk.Frame(master=self)
        display_frame.pack(fill=tk.X)
        self.display = tk.Label(
            master=display_frame,
            text="Ready?",
            font=font.Font(size=28, weight="bold"),
        )
        self.display.pack()

    def _create_board_grid(self):
        grid_frame = tk.Frame(master=self)
        grid_frame.pack()
        for row in range(self._game.board_size):
            self.rowconfigure(row, weight=1, minsize=50)
            self.columnconfigure(row, weight=1, minsize=75)
            for col in range(self._game.board_size):
                button = tk.Button(
                    master=grid_frame,
                    text="",
                    font=font.Font(size=36, weight="bold"),
                    fg="black",
                    width=3,
                    height=2,
                    highlightbackground="lightblue",
                )
                self._cells[button] = (row, col)
                button.bind("<ButtonPress-1>", self.play)
                button.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")

    def play(self, event):
        """Handle a player's move."""
        clicked_btn = event.widget
        row, col = self._cells[clicked_btn]
        move = Move(row, col, self._game.current_player.label)
        if self._game.is_valid_move(move):
            self._update_button(clicked_btn)
            self._game.process_move(move)
            if self._game.is_tied():
                self._update_display(msg="Tied game!", color="red")
            elif self._game.has_winner():
                self._highlight_cells()
                msg = f'Player "{self._game.current_player.label}" won!'
                color = self._game.current_player.color
                self._update_display(msg, color)
            else:
                self._game.toggle_player()
                msg = f"{self._game.current_player.label}'s turn"
                self._update_display(msg)

    def _update_button(self, clicked_btn):
        clicked_btn.config(text=self._game.current_player.label)
        clicked_btn.config(fg=self._game.current_player.color)

    def _update_display(self, msg, color="black"):
        self.display["text"] = msg
        self.display["fg"] = color

    def _highlight_cells(self):
        for button, coordinates in self._cells.items():
            if coordinates in self._game.winner_combo:
                button.config(highlightbackground="red")

    def reset_board(self):
        """Reset the game's board to play again."""
        self._game.reset_game()
        self._update_display(msg="Ready?")
        for button in self._cells.keys():
            button.config(highlightbackground="lightblue")
            button.config(text="")
            button.config(fg="black")

def main():
    """Create the game's board and run its main loop."""
    game = TicTacToeGame()
    board = TicTacToeBoard(game)
    board.mainloop()

if __name__ == "__main__":
    main()
29 thành một danh sách trống. Ba lần đặt lại này đảm bảo rằng đại diện trừu tượng của trò chơi đã sẵn sàng để bắt đầu một trận đấu mới.

Lưu ý rằng

>>> import tkinter
>>> tkinter.TkVersion
8.6
75 không đặt lại người chơi trở lại X khi chuẩn bị trò chơi cho một trận đấu mới. Thông thường, người chiến thắng của trận đấu trước sẽ đi đầu tiên trong trận tiếp theo. Vì vậy, không cần thiết lập lại người chơi ở đây.

Khi bạn đã cung cấp chức năng mới cần thiết trong logic trò chơi, thì bạn đã sẵn sàng cập nhật chức năng bảng trò chơi. Đi trước và thêm phương thức sau vào cuối

>>> import tkinter
>>> tkinter.TkVersion
8.6
9:

>>> import tkinter
>>> tkinter.TkVersion
8.6
8

Phương thức

>>> import tkinter
>>> tkinter.TkVersion
8.6
51 này hoạt động như sau:

  • Dòng 9 gọi

    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    68 để đặt lại biểu diễn trừu tượng của bảng. calls
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    68 to reset the board’s abstract representation.

  • Dòng 10 cập nhật màn hình bảng để giữ văn bản ban đầu,

    # tic_tac_toe.py
    # ...
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._create_board_display()
            self._create_board_grid()
    
    3. updates the board display to hold the initial text,
    # tic_tac_toe.py
    # ...
    
    class TicTacToeBoard(tk.Tk):
        def __init__(self):
            super().__init__()
            self.title("Tic-Tac-Toe Game")
            self._cells = {}
            self._create_board_display()
            self._create_board_grid()
    
    3.

  • Dòng 11 bắt đầu một vòng lặp trên các nút trên lưới bảng. starts a loop over the buttons on the board grid.

  • Các dòng 12 đến 14 khôi phục mỗi nút

    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    80,
    # tic_tac_toe.py
    # ...
    
    def main():
        """Create the game's board and run its main loop."""
        board = TicTacToeBoard()
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    6 và
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    29 thuộc tính cho trạng thái ban đầu của chúng.
    restore every button’s
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    80,
    # tic_tac_toe.py
    # ...
    
    def main():
        """Create the game's board and run its main loop."""
        board = TicTacToeBoard()
        board.mainloop()
    
    if __name__ == "__main__":
        main()
    
    6, and
    >>> import tkinter
    >>> tkinter.TkVersion
    8.6
    
    29 properties to their initial state.

Đó là nó! Với tính năng cuối cùng này, dự án trò chơi tic-tac-toe của bạn đã hoàn tất. Hãy tiếp tục và thử nó!

Sự kết luận

Trong suốt dự án từng bước này, bạn đã tạo ra một trò chơi máy tính Tic-Tac-Toe cổ điển sử dụng Python và Tkinter. Khung GUI này có sẵn trong Thư viện tiêu chuẩn Python. Nó chạy trên Windows, Linux và MacOS, vì vậy trò chơi của bạn sẽ hoạt động tuyệt vời trên cả ba nền tảng. Điều đó khá tuyệt!

Trong hướng dẫn này, bạn đã học được cách:

  • Thực hiện logic của trò chơi Tic-Tac-Toe cổ điển bằng cách sử dụng Pythonlogic of the classic tic-tac-toe game using Python
  • Xây dựng bảng trò chơi hoặc GUI bằng Tkinter từ Thư viện tiêu chuẩn Pythongame’s board or GUI using Tkinter from the Python standard library
  • Kết nối trò chơi logic và GUI để làm cho trò chơi hoạt động chính xácwork correctly

Kiến thức này cung cấp cho bạn nền tảng để tạo các dự án GUI và GUI mới và phức tạp hơn, điều này sẽ giúp bạn đưa các kỹ năng Python của bạn lên một tầm cao mới.

Bước tiếp theo

Trò chơi Tic-Tac-Toe mà bạn đã thực hiện trong hướng dẫn này khá là xương trần. Tuy nhiên, bạn có thể mở rộng nó theo một số cách khác nhau và thú vị. Một số ý tưởng để đưa dự án trò chơi này lên cấp độ tiếp theo bao gồm cho phép người dùng của bạn:

  • Sử dụng kích thước bảng trò chơi khác
  • Chơi trên máy tính

Những ý tưởng khác bạn có thể đưa ra để mở rộng dự án này? Hãy sáng tạo và vui chơi!

Bây giờ bạn đã hoàn thành dự án này, đây là một số dự án tuyệt vời bổ sung để tiếp tục xây dựng các trò chơi của riêng bạn với Python:

  • Tạo trò chơi Python đầu tiên của bạn: Rock, Paper, Kéo! Bạn sẽ học cách nhận đầu vào của người dùng, làm cho máy tính chọn một hành động ngẫu nhiên, xác định người chiến thắng và chia mã của bạn thành các chức năng.

  • Pygame: Một đoạn mồi về lập trình trò chơi trong Python: Trong hướng dẫn từng bước này, bạn sẽ học cách sử dụng pygame. Thư viện này cho phép bạn tạo các trò chơi và các chương trình đa phương tiện phong phú trong Python. Bạn sẽ học cách vẽ các mục trên màn hình của mình, thực hiện phát hiện va chạm, xử lý đầu vào của người dùng và nhiều hơn nữa!

  • Xây dựng một trò chơi Asteroids với Python và Pygame: Bài viết này sẽ chỉ cho bạn cách tạo một trò chơi trong pygame!

  • Arcade: Một đoạn mồi trên khung trò chơi Python: Bài viết này là một bản tiếp theo tuyệt vời bởi vì nó cho bạn thấy một khung trò chơi Python khác cho phép bạn tạo ra các trò chơi phức tạp hơn.

  • Xây dựng một trò chơi nền tảng trong Python với Arcade: Trong hướng dẫn từng bước này, bạn sẽ xây dựng một trò chơi nền tảng trong Python bằng thư viện Arcade. Youllll bao gồm các kỹ thuật để thiết kế các cấp độ, tìm nguồn cung ứng tài sản và thực hiện các tính năng nâng cao.

  • Xây dựng một công cụ trò chơi tic-tac-toe với một người chơi AI trong Python: Trong hướng dẫn từng bước này, bạn sẽ xây dựng một công cụ trò chơi toàn cầu trong Python với các quy tắc Tic-Tac-Toe và hai người chơi máy tính, bao gồm cả một người chơi không thể đánh bại Người chơi AI sử dụng thuật toán Minimax.

Làm thế nào để bạn tạo ra một trò chơi Tic Tac Toe cho người mới bắt đầu ở Python?

Các bước để xây dựng một trò chơi Python Tic Tac Toe..
Tạo cửa sổ hiển thị cho trò chơi của chúng tôi ..
Vẽ lưới trên vải nơi chúng tôi sẽ chơi tic tac toe ..
Vẽ thanh trạng thái bên dưới khung vẽ để hiển thị lượt của người chơi nào là nó và ai thắng trò chơi ..
Khi ai đó thắng trò chơi hoặc trò chơi là một trận hòa thì chúng tôi thiết lập lại trò chơi ..

Người mới bắt đầu sử dụng mã nào cho Python?

Ý tưởng dự án Python: Cấp độ mới bắt đầu..
Tạo một trình tạo mã.....
Xây dựng một máy tính đếm ngược.....
Viết một phương thức sắp xếp.....
Xây dựng một bài kiểm tra tương tác.....
Tic-tac-toe theo văn bản.....
Tạo một bộ chuyển đổi nhiệt độ/đo lường.....
Xây dựng một ứng dụng quầy.....
Xây dựng một trò chơi đoán số ..

Làm thế nào để bạn lập trình một trò chơi Python cho người mới bắt đầu?

Bước 1: Xin chào Bunny..
Nhập thư viện pygame.....
Khởi tạo pygame và thiết lập cửa sổ hiển thị ..
Tải hình ảnh mà bạn sẽ sử dụng cho chú thỏ ..
Tiếp tục lặp qua mã thụt lề sau.....
Đổ đầy màn hình với màu đen trước khi bạn vẽ bất cứ thứ gì ..
Thêm hình ảnh thỏ mà bạn đã tải vào màn hình tại x = 100 và y = 100 ..

Trò chơi Python dễ dàng nhất để thực hiện là gì?

Các dự án Python bạn có thể xây dựng..
Điên cuồng ..
Đoán trò chơi số (máy tính).
Đoán trò chơi số (người dùng).
Oẳn tù tì..
Hangman..
Đếm thời gian đếm ngược ..
Tạo mật khẩu..
Bộ mã hóa / bộ giải mã mã QR ..