Game đoán số bằng Python: bài tập nhỏ rèn vòng lặp và điều kiện

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

Muốn biết mình đã hiểu vòng lặp và câu lệnh điều kiện chưa, hãy thử viết một trò chơi. Game đoán số là bài tập nhỏ nhưng "đủ vị": máy chọn ngẫu nhiên một số, người chơi đoán, máy gợi ý lớn hơn hay nhỏ hơn cho đến khi trúng.

Luật chơi

Chương trình chọn bí mật một số nguyên từ 1 đến 100. Người chơi có tối đa 7 lượt. Sau mỗi lần đoán, chương trình báo "cao quá", "thấp quá" hoặc chúc mừng. Hết lượt mà chưa đoán đúng thì thua và hiện đáp án. Số 7 không phải ngẫu nhiên: với mỗi lần đoán chia đôi khoảng còn lại, 7 lượt là đủ để tìm ra mọi số từ 1 đến 100, đó chính là ý tưởng của tìm kiếm nhị phân.

Bước 1: Phiên bản đơn giản nhất

Hãy bắt đầu bằng thứ chạy được, rồi cải tiến dần. Đây là phiên bản đầu tiên:

import random

secret = random.randint(1, 100)
max_tries = 7

print("Mình đang nghĩ một số từ 1 đến 100. Bạn có", max_tries, "lượt đoán.")

for attempt in range(1, max_tries + 1):
    guess = int(input(f"Lượt {attempt}: "))

    if guess == secret:
        print("Chính xác! Bạn thắng sau", attempt, "lượt.")
        break
    elif guess < secret:
        print("Số bạn đoán nhỏ quá.")
    else:
        print("Số bạn đoán lớn quá.")
else:
    print("Hết lượt! Đáp án là", secret)

Có hai điểm thú vị. Hàm random.randint(1, 100) chọn số nguyên ngẫu nhiên, bao gồm cả hai đầu mút. Khối else gắn với vòng for là một đặc điểm hay của Python: nó chỉ chạy khi vòng lặp kết thúc bình thường mà không gặp break, tức là người chơi chưa đoán trúng.

Bước 2: Xử lý dữ liệu nhập sai

Thử gõ chữ "abc" vào chương trình trên, nó sẽ báo lỗi ValueError và dừng đột ngột. Chương trình thực tế không nên như vậy. Ta dùng try/except để bắt lỗi và cho nhập lại, đồng thời không tính lượt oan:

def read_number(prompt, low, high):
    while True:
        text = input(prompt)
        try:
            value = int(text)
        except ValueError:
            print("Vui lòng nhập một số nguyên.")
            continue
        if value < low or value > high:
            print(f"Số phải nằm trong khoảng {low} đến {high}.")
            continue
        return value

Hàm này lặp đến khi nhận được số hợp lệ. Việc tách thành hàm giúp code chính gọn hơn và dễ tái sử dụng.

Bước 3: Hoàn chỉnh game với hàm và chơi lại

import random

def read_number(prompt, low, high):
    while True:
        try:
            value = int(input(prompt))
        except ValueError:
            print("Vui lòng nhập một số nguyên.")
            continue
        if low <= value <= high:
            return value
        print(f"Số phải nằm trong khoảng {low} đến {high}.")

def play(low=1, high=100, max_tries=7):
    secret = random.randint(low, high)
    print(f"Mình đang nghĩ một số từ {low} đến {high}. Bạn có {max_tries} lượt.")
    for attempt in range(1, max_tries + 1):
        guess = read_number(f"Lượt {attempt}/{max_tries}: ", low, high)
        if guess == secret:
            print(f"Chính xác! Bạn thắng sau {attempt} lượt.")
            return True
        print("Nhỏ quá." if guess < secret else "Lớn quá.")
    print("Hết lượt! Đáp án là", secret)
    return False

def main():
    wins = games = 0
    while True:
        games += 1
        wins += play()
        print(f"Thắng {wins}/{games} ván.")
        again = input("Chơi tiếp? (c/k): ").strip().lower()
        if again != "c":
            print("Hẹn gặp lại!")
            break

if __name__ == "__main__":
    main()

Chú ý biểu thức low : Python cho phép so sánh liên tiếp rất tự nhiên. Và wins += play() hoạt động vì giá trị True tính như 1 còn False như 0, tuy nhiên nếu thấy khó đọc bạn có thể viết rõ ràng bằng if.

Gợi ý nâng cấp

  • Thêm độ khó: dễ (1 đến 50), vừa (1 đến 100), khó (1 đến 1000) với số lượt khác nhau.
  • Lưu kỷ lục số lượt ít nhất vào một file văn bản hoặc JSON.
  • Đảo vai: người chơi nghĩ số, máy đoán bằng thuật toán chia đôi.
  • Viết thêm gợi ý "rất gần" khi chênh lệch dưới một ngưỡng nhỏ.
  • Viết bài kiểm thử cho hàm xử lý nhập liệu bằng pytest.

Vì sao 7 lượt là đủ: tìm kiếm nhị phân

Giả sử số bí mật nằm trong khoảng 1 đến 100. Nếu bạn luôn đoán số ở giữa khoảng còn lại, mỗi câu trả lời "lớn quá" hoặc "nhỏ quá" loại bỏ đúng một nửa khả năng. Từ 100 khả năng, sau một lượt còn khoảng 50, rồi 25, 12, 6, 3, 2, 1. Vậy tối đa khoảng 7 lượt là tìm ra đáp án. Đó là ý tưởng của thuật toán tìm kiếm nhị phân, một thuật toán kinh điển trong khoa học máy tính. Bạn có thể tự viết hàm cho máy đoán số của người chơi theo đúng cách này: giữ hai biến low và high, đoán (low + high) // 2, rồi thu hẹp khoảng theo phản hồi. Thử đếm số lượt máy cần với nhiều số bí mật khác nhau để thấy thuật toán hoạt động hiệu quả thế nào.

Bạn đã luyện được gì

Qua trò chơi nhỏ này, bạn đã dùng biến, for, while, if/elif/else, hàm, xử lý ngoại lệ và module random. Quan trọng hơn là thói quen làm từng bước: có bản chạy được trước, rồi mới xử lý lỗi, tách hàm và thêm tính năng.

Nếu bạn muốn học Python từ nền tảng đến các dự án lớn hơn, hãy xem các khóa học tại codebem.com.

author_photo
Nguyễn Đình Cường

0 comment