Python – Module 8 – Dự án cuối khóa – Game phiêu lưu 🏆

Bạn đã vượt qua tất cả thử thách để đến được trùm cuối! Bạn đã học về Biến, If/Else, Vòng lặp, List, và Hàm. Giờ là lúc tháo bánh xe phụ và ghép tất cả mảnh ghép ấy lại với nhau.

Trong module này, bạn sẽ tự tay xây dựng Game Phiêu Lưu Văn Bản của riêng mình!

1. Game phiêu lưu văn bản là gì?

Game phiêu lưu văn bản (Text-Based Adventure hay “Choose Your Own Adventure”) là loại game mà máy tính mô tả khung cảnh, tình huống cho bạn bằng chữ, còn bạn thì gõ lệnh để tương tác với thế giới trong game.

Không có đồ họa. Toàn bộ câu chuyện diễn ra trong trí tưởng tượng của bạn – giống như đọc một cuốn truyện mà bạn là nhân vật chính!

Ví dụ một màn chơi:

Bạn tỉnh dậy trong một tòa lâu đài tối tăm, lạnh lẽo.

❤️ Máu: 100

🎒 Túi đồ: (trống)

Trước mặt bạn là hai cánh cửa:

  ▸ Cánh cửa GỖ bên TRÁI — có ánh sáng le lói

  ▸ Cánh cửa SẮT bên PHẢI — vọng ra tiếng gầm gừ

Bạn làm gì? (trái / phải)

> trái

✅ Bạn mở cánh cửa gỗ và tìm thấy một Rương Kho Báu!

🗝️ Bạn mở rương và nhận được: ⚔️ Kiếm Ma Thuật

⚔️ Kiếm Ma Thuật đã được thêm vào túi đồ!

2. Yêu cầu dự án

Để hoàn thành dự án này, code của bạn phải sử dụng ít nhất một lần mỗi khái niệm chính đã học trong toàn khóa. Đây là danh sách kiểm tra:

  • Biến (Variables): Để theo dõi chỉ số người chơi. Tạo biến cho ten_nguoi_choi, mau, v.v. — tất cả đều phải có type hint!
  • List: Làm túi đồ cho người chơi. Khởi tạo list rỗng: tui_do: list = []
  • Vòng lặp while: Giữ game chạy liên tục cho đến khi người chơi thắng hoặc chết (máu ≤ 0).
  • if / elif / else: Rẽ nhánh câu chuyện. Hỏi người chơi bằng input(), rồi kiểm tra họ gõ gì — “trái”, “phải”, “đánh”, “chạy”, v.v.
  • Hàm (Functions): Tạo ít nhất ba hàm với đầy đủ type hints. Ví dụ: def game_over() -> None:, def tim_kho_bau(tui_do: list) -> list:, def tan_cong_quai(mau_nguoi_choi: int, mau_quai: int) -> int:
  • Type hints: Mọi hàm phải có kiểu tham số và kiểu trả về. Mọi biến nên có type hint.

3. Hướng dẫn xây dựng từng bước

Bước 1: Khởi Tạo Game (Setup)

# --- BƯỚC 1: KHỞI TẠO GAME ---

print("=" * 40)

print("🏰 CHÀO MỪNG ĐẾN VỚI HẦM NGỤC BÓNG TỐI 🏰")

print("=" * 40)

ten_nguoi_choi: str = input("👤 Người chơi, tên bạn là gì? ")

mau: int = 100

tui_do: list = []

game_dang_chay: bool = True

so_phong_da_qua: int = 0

print(f"\n📜 {ten_nguoi_choi}, hãy cố gắng thoát khỏi hầm ngục!\n")

Bước 2: Viết Các Hàm Dùng Chung

Tạo các hàm để tái sử dụng xuyên suốt game. Nhớ type hints!

# --- BƯỚC 2: CÁC HÀM DÙNG CHUNG ---

def game_over(ten: str, tui: list) -> None:

    """Kết thúc game và in tóm tắt."""

    print("\n" + "=" * 40)

    print("💀 GAME OVER 💀")

    print("=" * 40)

    print(f"{ten} đã ngã xuống với {len(tui)} vật phẩm trong túi đồ:")

    for vat_pham in tui:

        print(f"  ▸ {vat_pham}")

    print("=" * 40)


def chien_thang(ten: str, tui: list) -> None:

    """Người chơi chiến thắng!"""

    print("\n" + "=" * 40)

    print("🏆 CHIẾN THẮNG! 🏆")

    print("=" * 40)

    print(f"🌟 {ten} đã thoát khỏi hầm ngục thành công!")

    print(f"🎒 Với {len(tui)} vật phẩm quý giá:")

    for vat_pham in tui:

        print(f"  ▸ {vat_pham}")

    print("=" * 40)


def hien_thi_trang_thai(ten: str, mau_hien_tai: int, tui: list, phong: int) -> None:

    """In trạng thái hiện tại của người chơi."""

    print("\n" + "-" * 30)

    print(f"👤 {ten}")

    print(f"❤️  Máu: {mau_hien_tai}/100")

    print(f"🎒 Túi đồ: {tui if len(tui) > 0 else '(trống)'}")

    print(f"🚪 Phòng đã qua: {phong}")

    print("-" * 30)


def nhan_sat_thuong(mau_hien_tai: int, sat_thuong: int) -> int:

    """Trừ máu và trả về lượng máu mới."""

    mau_moi: int = mau_hien_tai - sat_thuong

    print(f"💔 Bạn nhận {sat_thuong} sát thương! (Máu còn: {mau_moi})")

    return mau_moi


def hoi_mau(mau_hien_tai: int, luong_hoi: int) -> int:

    """Hồi máu và trả về lượng máu mới."""

    mau_moi: int = mau_hien_tai + luong_hoi

    if mau_moi > 100:

        mau_moi = 100

    print(f"💚 Bạn hồi {luong_hoi} máu! (Máu hiện tại: {mau_moi})")

    return mau_moi

Bước 3: Vòng Lặp Chính Của Game

Đây là trái tim của game — nơi mọi thứ diễn ra!

# --- BƯỚC 3: VÒNG LẶP CHÍNH ---

while game_dang_chay:

    hien_thi_trang_thai(ten_nguoi_choi, mau, tui_do, so_phong_da_qua)

    # --- PHÒNG 1: Hành Lang Tối ---

    if so_phong_da_qua == 0:

        print("\n🌑 Bạn đang đứng trong một hành lang tối tăm.")

        print("Có hai cánh cửa:")

        print("  ▸ Cửa GỖ bên TRÁI — có ánh sáng le lói")

        print("  ▸ Cửa SẮT bên PHẢI — vọng ra tiếng gầm gừ")

        lua_chon: str = input("👉 Bạn chọn cửa nào? (trái / phải): ").strip().lower()

        if lua_chon == "trái":

            print("\n✅ Bạn mở cửa gỗ và tìm thấy một Rương Kho Báu!")

            print("🗝️ Trong rương có một ⚔️ Kiếm Ma Thuật!")

            tui_do.append("⚔️ Kiếm Ma Thuật")

            so_phong_da_qua = 1

        elif lua_chon == "phải":

            print("\n⚠️ Bạn mở cửa sắt và đối mặt với một con SÓI HOANG!")

            mau = nhan_sat_thuong(mau, 20)

            if mau <= 0:

                game_over(ten_nguoi_choi, tui_do)

                game_dang_chay = False

            else:

                so_phong_da_qua = 1

        else:

            print("\n❓ Ta không hiểu lệnh đó. Hãy gõ 'trái' hoặc 'phải'.")

    # --- PHÒNG 2: Căn Phòng Bí Ẩn ---

    elif so_phong_da_qua == 1:

        print("\n🔮 Bạn bước vào một căn phòng tròn, trên tường khắc đầy chữ rune.")

        print("Giữa phòng có một BỆ ĐÁ với ba vật phẩm:")

        print("  ▸ 🧪 Bình Máu")

        print("  ▸ 🗝️ Chìa Khóa Bạc")

        print("  ▸ 🛡️ Khiên Gỗ")

        print("⚠️ Nhưng bạn chỉ được chọn MỘT!")

        lua_chon = input("👉 Bạn chọn gì? (máu / khóa / khiên): ").strip().lower()

        if lua_chon == "máu":

            print("\n🧪 Bạn nhặt Bình Máu! (+25 máu)")

            mau = hoi_mau(mau, 25)

            tui_do.append("🧪 Bình Máu")

            so_phong_da_qua = 2

        elif lua_chon == "khóa":

            print("\n🗝️ Bạn nhặt Chìa Khóa Bạc!")

            tui_do.append("🗝️ Chìa Khóa Bạc")

            so_phong_da_qua = 2

        elif lua_chon == "khien":

            print("\n🛡️ Bạn nhặt Khiên Gỗ!")

            tui_do.append("🛡️ Khiên Gỗ")

            so_phong_da_qua = 2

        else:

            print("\n❓ Vật phẩm không hợp lệ. Hãy chọn: máu / khóa / khiên.")

    # --- PHÒNG 3: Cửa Khóa ---

    elif so_phong_da_qua == 2:

        print("\n🚪 Bạn đến trước một cánh cửa lớn bằng bạc, có ổ khóa lấp lánh.")

        if "🗝️ Chìa Khóa Bạc" in tui_do:

            print("🔑 Bạn tra chìa khóa bạc vào ổ... CÁNH CỬA MỞ RA!")

            print("✨ Đằng sau cánh cửa là ÁNH SÁNG MẶT TRỜI!")

            print("🏃 Bạn chạy thật nhanh về phía tự do...")

            so_phong_da_qua = 3

        else:

            print("🔒 Cửa bị khóa! Bạn cần Chìa Khóa Bạc để mở.")

            print("↩️ Bạn phải quay lại tìm chìa khóa...")

            so_phong_da_qua = 1  # Quay lại phòng 2

    # --- THOÁT KHỎI HẦM NGỤC ---

    elif so_phong_da_qua == 3:

        chien_thang(ten_nguoi_choi, tui_do)

        game_dang_chay = False

    # --- KIỂM TRA MÁU ---

    if mau <= 0:

        game_over(ten_nguoi_choi, tui_do)

        game_dang_chay = False

4. Toàn bộ code mẫu hoàn chỉnh

Dưới đây là toàn bộ code ghép lại từ các bước trên. Hãy copy-paste vào file .py và chạy thử!

# ============================================================

# 🏰 GAME PHIÊU LƯU VĂN BẢN: HẦM NGỤC BÓNG TỐI

# Dự án cuối khóa Python

# ============================================================

# --- KHỞI TẠO ---

print("=" * 40)

print("🏰 CHÀO MỪNG ĐẾN VỚI HẦM NGỤC BÓNG TỐI 🏰")

print("=" * 40)

ten_nguoi_choi: str = input("👤 Người chơi, tên bạn là gì? ")

mau: int = 100

tui_do: list = []

game_dang_chay: bool = True

so_phong_da_qua: int = 0

print(f"\n📜 {ten_nguoi_choi}, hãy cố gắng thoát khỏi hầm ngục!\n")


# --- HÀM ---

def game_over(ten: str, tui: list) -> None:

    """Kết thúc game và in tóm tắt."""

    print("\n" + "=" * 40)

    print("💀 GAME OVER 💀")

    print("=" * 40)

    print(f"{ten} đã ngã xuống với {len(tui)} vật phẩm trong túi đồ:")

    for vat_pham in tui:

        print(f"  ▸ {vat_pham}")

    print("=" * 40)


def chien_thang(ten: str, tui: list) -> None:

    """Người chơi chiến thắng!"""

    print("\n" + "=" * 40)

    print("🏆 CHIẾN THẮNG! 🏆")

    print("=" * 40)

    print(f"🌟 {ten} đã thoát khỏi hầm ngục thành công!")

    print(f"🎒 Với {len(tui)} vật phẩm quý giá:")

    for vat_pham in tui:

        print(f"  ▸ {vat_pham}")

    print("=" * 40)


def hien_thi_trang_thai(ten: str, mau_hien_tai: int, tui: list, phong: int) -> None:

    """In trạng thái hiện tại của người chơi."""

    print("\n" + "-" * 30)

    print(f"👤 {ten}")

    print(f"❤️  Máu: {mau_hien_tai}/100")

    print(f"🎒 Túi đồ: {tui if len(tui) > 0 else '(trống)'}")

    print(f"🚪 Phòng đã qua: {phong}")

    print("-" * 30)


def nhan_sat_thuong(mau_hien_tai: int, sat_thuong: int) -> int:

    """Trừ máu và trả về lượng máu mới."""

    mau_moi: int = mau_hien_tai - sat_thuong

    print(f"💔 Bạn nhận {sat_thuong} sát thương! (Máu còn: {mau_moi})")

    return mau_moi


def hoi_mau(mau_hien_tai: int, luong_hoi: int) -> int:

    """Hồi máu và trả về lượng máu mới."""

    mau_moi: int = mau_hien_tai + luong_hoi

    if mau_moi > 100:

        mau_moi = 100

    print(f"💚 Bạn hồi {luong_hoi} máu! (Máu hiện tại: {mau_moi})")

    return mau_moi


# --- VÒNG LẶP CHÍNH ---

while game_dang_chay:

    hien_thi_trang_thai(ten_nguoi_choi, mau, tui_do, so_phong_da_qua)

    # Phòng 0: Hành Lang Tối

    if so_phong_da_qua == 0:

        print("\n🌑 Bạn đang đứng trong một hành lang tối tăm.")

        print("Có hai cánh cửa:")

        print("  ▸ Cửa GỖ bên TRÁI — có ánh sáng le lói")

        print("  ▸ Cửa SẮT bên PHẢI — vọng ra tiếng gầm gừ")

        lua_chon: str = input("👉 Bạn chọn cửa nào? (trái / phải): ").strip().lower()

        if lua_chon == "trái":

            print("\n✅ Bạn mở cửa gỗ và tìm thấy một Rương Kho Báu!")

            print("🗝️ Trong rương có một ⚔️ Kiếm Ma Thuật!")

            tui_do.append("⚔️ Kiếm Ma Thuật")

            so_phong_da_qua = 1

        elif lua_chon == "phải":

            print("\n⚠️ Bạn mở cửa sắt và đối mặt với một con SÓI HOANG!")

            mau = nhan_sat_thuong(mau, 20)

            if mau <= 0:

                game_over(ten_nguoi_choi, tui_do)

                game_dang_chay = False

            else:

                so_phong_da_qua = 1

        else:

            print("\n❓ Ta không hiểu lệnh đó. Hãy gõ 'trái' hoặc 'phải'.")

    # Phòng 1: Căn Phòng Bí Ẩn

    elif so_phong_da_qua == 1:

        print("\n🔮 Bạn bước vào một căn phòng tròn, trên tường khắc đầy chữ rune.")

        print("Giữa phòng có một BỆ ĐÁ với ba vật phẩm:")

        print("  ▸ 🧪 Bình Máu")

        print("  ▸ 🗝️ Chìa Khóa Bạc")

        print("  ▸ 🛡️ Khiên Gỗ")

        print("⚠️ Nhưng bạn chỉ được chọn MỘT!")

        lua_chon = input("👉 Bạn chọn gì? (máu / khóa / khiên): ").strip().lower()

        if lua_chon == "máu":

            print("\n🧪 Bạn nhặt Bình Máu! (+25 máu)")

            mau = hoi_mau(mau, 25)

            tui_do.append("🧪 Bình Máu")

            so_phong_da_qua = 2

        elif lua_chon == "khóa":

            print("\n🗝️ Bạn nhặt Chìa Khóa Bạc!")

            tui_do.append("🗝️ Chìa Khóa Bạc")

            so_phong_da_qua = 2

        elif lua_chon == "khien":

            print("\n🛡️ Bạn nhặt Khiên Gỗ!")

            tui_do.append("🛡️ Khiên Gỗ")

            so_phong_da_qua = 2

        else:

            print("\n❓ Vật phẩm không hợp lệ. Hãy chọn: máu / khóa / khiên.")

    # Phòng 2: Cửa Khóa

    elif so_phong_da_qua == 2:

        print("\n🚪 Bạn đến trước một cánh cửa lớn bằng bạc, có ổ khóa lấp lánh.")

        if "🗝️ Chìa Khóa Bạc" in tui_do:

            print("🔑 Bạn tra chìa khóa bạc vào ổ... CÁNH CỬA MỞ RA!")

            print("✨ Đằng sau cánh cửa là ÁNH SÁNG MẶT TRỜI!")

            print("🏃 Bạn chạy thật nhanh về phía tự do...")

            so_phong_da_qua = 3

        else:

            print("🔒 Cửa bị khóa! Bạn cần Chìa Khóa Bạc để mở.")

            print("↩️ Bạn phải quay lại tìm chìa khóa...")

            so_phong_da_qua = 1

    # Phòng 3: Thoát!

    elif so_phong_da_qua == 3:

        chien_thang(ten_nguoi_choi, tui_do)

        game_dang_chay = False

    # Kiểm tra máu sau mỗi lượt

    if mau <= 0:

        game_over(ten_nguoi_choi, tui_do)

        game_dang_chay = False

5. Mở rộng Thế Giới Game (Thử thách nâng cao)

Khi code mẫu đã chạy ổn định, hãy thử thêm những tính năng dưới đây để biến game thành của riêng bạn!

🔥 Thử thách 1: Trận Đánh Trùm

Tạo một phòng nơi người chơi phải đánh bại trùm bằng cách gõ “đánh” nhiều lần.

def danh_trum(mau_nguoi_choi: int, tui: list) -> int:

    """Trận đánh với trùm hầm ngục. Trả về máu còn lại."""

    mau_trum: int = 50

    co_khieng: bool = "🛡️ Khiên Gỗ" in tui

    co_kiem: bool = "⚔️ Kiếm Ma Thuật" in tui

    print("\n🐉 Một con RỒNG LỬA xuất hiện!")

    print(f"❤️ Máu Rồng: {mau_trum}")

    while mau_trum > 0 and mau_nguoi_choi > 0:

        hanh_dong: str = input("👉 Bạn làm gì? (đánh / chạy): ").strip().lower()

        if hanh_dong == "đánh":

            # Sát thương cơ bản

            sat_thuong_gay_ra: int = 10

            # Nếu có kiếm, gây thêm sát thương

            if co_kiem:

                sat_thuong_gay_ra = sat_thuong_gay_ra + 10

                print("⚔️ Kiếm Ma Thuật phát sáng!")

            mau_trum = mau_trum - sat_thuong_gay_ra

            print(f"💥 Bạn gây {sat_thuong_gay_ra} sát thương lên Rồng! (Máu Rồng: {mau_trum})")

            # Rồng đánh trả

            sat_thuong_nhan: int = 15

            if co_khieng:

                sat_thuong_nhan = sat_thuong_nhan - 5

                print("🛡️ Khiên Gỗ đỡ bớt 5 sát thương!")

            mau_nguoi_choi = mau_nguoi_choi - sat_thuong_nhan

            print(f"🔥 Rồng phun lửa! Bạn nhận {sat_thuong_nhan} sát thương. (Máu: {mau_nguoi_choi})")

        elif hanh_dong == "chạy":

            print("🏃 Bạn bỏ chạy khỏi con Rồng!")

            break

        else:

            print("❓ Gõ 'đánh' hoặc 'chạy'.")

    if mau_trum <= 0:

        print("\n🎉 Bạn đã đánh bại RỒNG LỬA!")

    return mau_nguoi_choi

🧪 Thử thách 2: Sử Dụng Vật Phẩm Trong Túi Đồ

Cho phép người chơi gõ “dùng bình máu” để hồi máu.

def dung_vat_pham(tui: list, mau_hien_tai: int) -> tuple[list, int]:

    """Dùng một vật phẩm trong túi đồ. Trả về (túi đồ mới, máu mới)."""

    vat_pham_muon_dung: str = input("👉 Bạn muốn dùng vật phẩm gì? ").strip()

    for vat_pham in tui:

        if vat_pham_muon_dung.lower() in vat_pham.lower():

            if "Bình Máu" in vat_pham:

                mau_hien_tai = hoi_mau(mau_hien_tai, 30)

                tui.remove(vat_pham)

                return tui, mau_hien_tai

    print(f"❌ Bạn không có '{vat_pham_muon_dung}' trong túi đồ!")

    return tui, mau_hien_tai

🎲 Thử thách 3: Yếu Tố Ngẫu Nhiên

Dùng thư viện random để tạo sự kiện bất ngờ!

import random

def su_kien_ngau_nhien(mau_ht: int, tui: list) -> tuple[int, list]:

    """Kích hoạt một sự kiện ngẫu nhiên."""

    su_kien: int = random.randint(1, 4)

    if su_kien == 1:

        print("\n🦇 Một bầy DƠI bay qua và tấn công bạn!")

        return nhan_sat_thuong(mau_ht, 10), tui

    elif su_kien == 2:

        print("\n💎 Bạn tìm thấy một viên ĐÁ QUÝ trên sàn!")

        tui.append("💎 Đá Quý")

        return mau_ht, tui

    elif su_kien == 3:

        print("\n🍗 Bạn thấy một ĐÙI GÀ bị bỏ lại trên bàn!")

        tui.append("🍗 Đùi Gà")

        return mau_ht, tui

    else:

        print("\n🍀 Bạn cảm thấy may mắn! (+5 máu)")

        return hoi_mau(mau_ht, 5), tui

📜 Thử thách 4: Nhiều Kết Thúc Khác Nhau

Tạo ít nhất 3 cách khác nhau để kết thúc game:

  • 🏆 Kết thúc TỐT: Đánh bại trùm và thoát khỏi hầm ngục
  • 😔 Kết thúc BÌNH THƯỜNG: Thoát mà không đánh trùm
  • 💀 Kết thúc XẤU: Chết trong hầm ngục

6. Mẹo gỡ lỗi (Debugging Tips) 🐛

Khi code không chạy như mong đợi, đây là những lỗi phổ biến và cách sửa:

Triệu chứngNguyên nhân có thểCách sửa
Game chạy một lần rồi dừngThiếu vòng lặp while hoặc game_dang_chay = False sai chỗKiểm tra điều kiện while
input() luôn vào elseSo sánh sai chính tả (vd: “Trái” thay vì “trái”)Dùng .lower() và .strip()
Máu không giảmQuên gán mau = nhan_sat_thuong(mau, 20)Luôn gán kết quả trả về
Game bị kẹt một phòngBiến so_phong_da_qua không được tăngKiểm tra mọi nhánh if đều cập nhật phòng
NameError: name ‘…’ is not definedBiến chưa được khai báo hoặc khai báo sai vị tríKhai báo biến trước khi dùng
Type hint báo lỗiDùng sai kiểu dữ liệuKiểm tra lại kiểu tham số và giá trị trả về

7. Tổng kết Module

Thành phầnVai trò trong game
BiếnLưu máu, tên, trạng thái game
ListTúi đồ chứa vật phẩm
if/elif/elseRẽ nhánh câu chuyện theo lựa chọn
whileGiữ game chạy cho đến khi thắng hoặc thua
HàmTái sử dụng logic (hồi máu, nhận sát thương)
Type hintsLàm code rõ ràng, dễ đọc, dễ sửa

🎉 Chúc Mừng!

Bạn đã hoàn thành toàn bộ khóa học Python! Từ một người chưa từng viết dòng code nào, giờ đây bạn đã có thể:

  • ✅ Tạo biến và lưu trữ dữ liệu
  • ✅ Dùng if/else để ra quyết định
  • ✅ Dùng vòng lặp while để code chạy liên tục
  • ✅ Dùng list để quản lý nhiều mục cùng lúc
  • ✅ Tự xây hàm với type hints đầy đủ
  • ✅ Ghép tất cả lại thành một game hoàn chỉnh!

Bạn chính thức là một Lập Trình Viên Python! Hãy tiếp tục xây dựng, tiếp tục phá vỡ mọi thứ (để sửa chúng), và không ngừng học hỏi! 🚀

(The End)

Hãy liên lạc với chúng tôi nếu bạn cần hỗ trợ:
vuanhduc2685@gmail.com
hoanvtt99@gmail.com

Leave a Reply

Your email address will not be published. Required fields are marked *