Xây dựng trò chơi Sudoku trên Terminal bằng Python
Chào mừng bạn đến với hướng dẫn xây dựng trò chơi Sudoku trên Terminal sử dụng Python. Dự án này không chỉ giúp bạn nâng cao kỹ năng lập trình mà còn giới thiệu các khái niệm quan trọng như cấu trúc dữ liệu, thuật toán, và xử lý đầu vào người dùng. Trong bài viết này, tôi sẽ hướng dẫn bạn từng bước để tạo ra một trò chơi Sudoku đơn giản nhưng đầy thú vị.
Mục tiêu của Dự án
Dự án này sử dụng GitHub Copilot để hỗ trợ trong việc tạo cấu trúc ban đầu cho dự án. Chúng tôi sẽ sử dụng các thư viện có sẵn trong Python để giúp đơn giản hóa việc phát triển trò chơi.
Cách Tiếp Cận Hướng Đối Tượng
Thay vì viết mã trong một tập lệnh duy nhất, tôi chia nhỏ trò chơi thành hai lớp chính: Board
và Game
. Việc tách biệt này giúp mã nguồn trở nên sạch sẽ và dễ quản lý hơn.
- Lớp Board: Chịu trách nhiệm về dữ liệu và trạng thái của bảng Sudoku. Nó sẽ tạo bảng khởi đầu và in bảng ra màn hình.
- Lớp Game: Quản lý luồng trò chơi, xử lý đầu vào của người dùng và điều phối các nước đi bằng cách gọi các phương thức của đối tượng Board.
Đại Diện Bảng Chơi
Lớp Board
đại diện cho lưới Sudoku bằng cách sử dụng một mảng 2D, hay còn gọi là danh sách của các danh sách. Đây là cách mô hình lưới rõ ràng và trực quan, với mỗi danh sách bên trong đại diện cho một hàng.
python
import random
class Board:
def __init__(self):
self.removed_cells = []
self.board = self.create_board()
self.board, self.removed_cells = self.remove_numbers()
def create_board(self):
# Khởi tạo bảng 9x9
new_board = [[0 for _ in range(9)] for _ in range(9)]
nums = random.sample(range(1, 10), 9) # Tạo hàng đầu tiên với các số từ 1-9
# Tiến hành thêm logic xây dựng bảng Sudoku
return new_board
Hàm remove_numbers
sẽ loại bỏ 50 số từ bảng mà người chơi cần đoán.
Xử Lý Đầu Vào Người Dùng
Lớp Game
chịu trách nhiệm cho tất cả các tương tác với người dùng. Nó sẽ yêu cầu người dùng nhập tọa độ hàng và cột, và xác thực đầu vào để tránh các lỗi phổ biến trước khi chuyển nước đi đến đối tượng Board.
Một kỹ thuật quan trọng ở đây là việc kết hợp string.strip().split()
để làm sạch và phân tích đầu vào, cũng như sử dụng khối try...except
để xử lý các đầu vào không phải số một cách nhẹ nhàng. Điều này giúp cho chương trình trở nên thân thiện và ổn định hơn.
python
class Game:
def __init__(self, board):
self.board = board
def start_game(self):
print("Bắt đầu một trò chơi Sudoku mới!")
self.board.display_board()
def make_move(self):
while True:
try:
user_input = input("Nhập tọa độ ô (hàng, cột) hoặc nhập ## để kết thúc: ").strip().split()
if user_input == ['##']:
print("Trò chơi đã kết thúc bởi người dùng.")
break
Xác Thực Giải Pháp
Trái tim của trò chơi là kiểm tra xem một bảng đã hoàn chỉnh hay chưa. Lớp Game
xử lý điều này bằng cách kiểm tra bốn điều kiện riêng biệt:
- Tất cả các số đã được điền chưa?
- Tất cả các hàng có hợp lệ không?
- Tất cả các cột có hợp lệ không?
- Tất cả các lưới 3x3 có hợp lệ không?
Một ô chưa được điền sẽ chứa giá trị 0. Do đó, chúng ta chỉ cần kiểm tra sự tồn tại của số 0 để đánh giá điều kiện đầu tiên.
Đối với ba điều kiện tiếp theo, một thủ thuật mạnh mẽ và hiệu quả là sử dụng tập hợp (set). Tập hợp chỉ lưu trữ các giá trị duy nhất, vì vậy bạn có thể dễ dàng phát hiện ra các bản sao bằng cách so sánh độ dài của danh sách với độ dài của tập hợp được tạo ra từ danh sách đó.
python
# Hàm hỗ trợ kiểm tra các số trùng lặp trong danh sách
def has_duplicates(numbers):
return len(numbers) != len(set(numbers)) # Sử dụng set để kiểm tra duy nhất
Kiểm tra này ngắn gọn là cơ sở để xác thực mọi hàng, cột và lưới con trong bảng, khiến cho quy trình xác thực trở nên đơn giản và dễ đọc.
Tạo Bảng Chơi
Logic để tạo ra một bảng Sudoku khởi đầu hợp lệ là một thuật toán phức tạp. Đối với dự án này, tôi đã lấy cảm hứng từ các kỹ thuật được mô tả trên các trang web sau:
Cải Tiến Tương Lai
Một vài bước tiếp theo thú vị cho dự án này có thể bao gồm:
- Thực hiện một trình giải sử dụng thuật toán quay lui.
- Thêm giao diện người dùng đơn giản bằng cách sử dụng thư viện như
curses
để xử lý các phím đơn và vẽ lại màn hình động. - Thêm các cấp độ khó bằng cách sử dụng các trạng thái bảng khởi đầu khác nhau.
- Thực hiện kiểm thử đơn vị.
Kết Luận
Xây dựng một trò chơi Sudoku là một dự án thú vị và bổ ích, giúp bạn tiếp cận nhiều khái niệm cơ bản. Quá trình phân chia bài toán thành các chức năng nhỏ hơn, như xác thực đầu vào và xác thực bảng, là một cách tuyệt vời để nâng cao kỹ năng lập trình của bạn.
Xem mã nguồn đầy đủ
Cấu trúc dự án
sudoku-terminal
├── src
│ ├── main.py # Điểm vào của ứng dụng
│ ├── board.py # Chứa lớp Board để quản lý bảng Sudoku
│ ├── game.py # Chứa lớp Game để quản lý logic trò chơi
│ └── utils.py # Chứa các hàm tiện ích cho trò chơi
├── tests
│ ├── test_board.py # Kiểm thử đơn vị cho lớp Board
│ ├── test_game.py # Kiểm thử đơn vị cho lớp Game
│ └── test_utils.py # Kiểm thử đơn vị cho các hàm tiện ích
├── requirements.txt # Danh sách các phụ thuộc của dự án
└── README.md # Tài liệu dự án
Cài Đặt
Để cài đặt các phụ thuộc cần thiết, hãy chạy:
pip install -r requirements.txt
Chạy Trò Chơi
Để bắt đầu trò chơi, thực hiện lệnh sau:
python src/main.py
Đóng Góp
Rất hoan nghênh sự đóng góp! Hãy tự do gửi pull request…