Dự án “Nhà thám hiểm và cánh cửa bí mật” của bạn Đinh Hoàng Long, học sinh khóa CS 101 Trại hè Lập trình 2021, đã được thầy cô STEAM for Vietnam hết lời khen ngợi. Làm thế nào để bạn Long có thể sáng tạo ra một trò chơi đầy ấn tượng và thu hút như thế? Hãy cùng STEAM for Vietnam tìm hiểu cách làm dự án “Nhà thám hiểm và cánh cửa bí mật” như thế nào nhé!
Sau khi học về câu điều kiện và vòng lặp, chúng ta đã có thể tạo được một game nhập vai đơn giản giống như bạn Hoàng Long. Một số kiến thức cần thiết để áp dụng trong game mà các bạn học sinh cần nhớ:
input()
để nhập dữ liệu trong Python.print()
để in thông báo ra màn hình.if
, elif
, và else
trong Python.boolean
trong Python với so sánh ==
.random
để tạo số ngẫu nhiên.while
trong Python.Cốt truyện game là hành trình hết sức khó khăn của một nhà thám hiểm vô tình đi lạc vào một tòa lâu đài cổ kính. Xung quanh là không gian tối tăm, tĩnh mịch không một tiếng động, bạn ấy vừa hoang mang, vừa lo sợ khi trên tay chỉ cầm một ngọn đuốc le lói ánh sáng. Liệu điều gì đang chờ nhà thám hiểm trong tòa lâu đài này đây?
Bỗng nhiên, nhà thám hiểm tìm thấy 4 căn phòng bí ẩn. Mỗi căn phòng lại có một kết cục khác nhau cho số phận của nhà thám hiểm đó! Các bạn học sinh có thể trải nghiệm game bằng cách nhấn vào đường link sau trước khi bắt tay vào code nhé!: https://s4v.trinket.io/sites/adventure-game
Trước khi bắt đầu viết code, chúng ta sẽ xây dựng một sơ đồ để hình dung thuật toán của game. Điều này rất cần thiết để chúng ta có thể hình dung các bước giải quyết một bài toán và code dễ dàng hơn.
Hãy bắt đầu với vị trí đầu tiên của nhà thám hiểm, đối diện với 4 cánh cửa trong tòa lâu đài tối tăm.
Căn phòng thứ nhất: nhà thám hiểm ngỡ ngàng trước vô số vàng bạc, kim cương lấp lánh. Nếu may mắn chọn đúng căn phòng này, nhà thám hiểm sẽ có thể thoát khỏi tòa lâu đài và trở nên giàu có với rương kho báu khổng lồ.
Căn phòng thứ hai: một con yêu tinh xấu xí, đáng sợ đang ẩn náu trong căn phòng để chờ nhà thám hiểm đi đến. Nó xông ra với một cây chùy trên tay và khiến nhà thám hiểm phải bỏ mạng ngay tại căn phòng này.
Căn phòng thứ ba: một con rồng khổng lồ đang nằm ngủ ngay góc phòng. Nếu nhà thám hiểm hoảng hốt và hét lên, con rồng sẽ tỉnh giấc và phun lửa thiêu rụi nhà thám hiểm ngay lập tức. Còn khi nhà thám hiểm đứng im không nhúc nhích, con rồng vô tình thức dậy thì sẽ trông thấy và nuốt trọn nhà thám hiểm. Vậy phải làm thế nào đây? Cách an toàn nhất là nhẹ nhàng đi ra khỏi phòng. Thế nhưng không hiểu sao cánh cửa lại bị khóa. Khi đó, tay nắm cửa đột nhiên phát ra tiếng động, bẫy được kích hoạt và khiến cho nhà thám hiểm bị rơi ra khỏi tòa lâu đài. Nhà thám hiểm đã trở về thành phố mà không có kho báu.
Căn phòng thứ tư: Bước vào căn phòng cuối cùng, nhà thám hiểm sẽ gặp con nhân sư với một câu đố hóc búa. Nhân sư rất thông minh và nó bắt nhà thám hiểm đoán đúng con số nó đang nghĩ trong đầu. Con số từ 1 đến 10. Nếu đoán đúng, nhân sư sẽ cho nhà thám hiểm đi khỏi lâu đài. Nếu đoán sai, nhà thám hiểm sẽ phải ở lại làm nô lệ cho nhân sư.
Để hoàn thiện trò chơi, các bạn học sinh cần hỏi thêm người chơi có muốn tiếp tục chơi hay dừng lại sau khi đã mở cửa 1 căn phòng không nhé!
Bước 1: Viết giới thiệu game
Chúng ta sẽ sử dụng chương trình Thonny để thực hiện game này. Trước tiên, chúng ta cần sử dụng câu lệnh print()
để in ra màn hình vị trí bắt đầu của nhà thám hiểm. Để cho game sinh động, chúng ta sẽ thêm hình vẽ lâu đài bằng các ký tự ASCII (Nguồn: https://www.asciiart.eu/buildings-and-places/castles).
LAUDAI = """
|>>> |>>>
| |>>> |>>> |
* | | *
/ \ * * / \
/___\ _/ \ / \_ /___\
[ ] |/ \_________/ \| [ ]
[ I ] / \ / \ [ I ]
[ ]_ _ _ / \ / \ _ _ _[ ]
[ ] U U | {#########} {#########} | U U [ ]
[ ]====/ \=======/ \=======/ \====[ ]
[ ] | | I |_ _ _ _| I | | [ ]
[___] |_ _ _ _ _ _| | U U U | |_ _ _ _ _ _| [___]
\===/ I | U U U U U | |=======| | U U U U U | I \===/
\=/ |===========| I | + W + | I |===========| \=/
| I | | |_______| | | I |
| | | ||||||||| | | |
| | | I ||vvvvv|| I | | |
_-_-|______|-----------|_____|| ||_____|-----------|______|-_-_
/________\ /______|| ||______\ /________\
|__________|-------|________\_____/________|-------|__________|
"""
print("Bạn đang ở trong một căn phòng tối tăm nằm trong một lâu đài bí hiểm.")
print(LAUDAI)
print("Có 4 cánh cửa trước mặt bạn, bạn hãy chọn một cánh cửa để thám hiểm.")
Để yêu cầu người chơi chọn cửa để khám phá, chúng ta sẽ sử dụng câu lệnh input()
:
a = input("Bạn chọn cánh cửa sổ: ")
Bước 2: Viết phần lựa chọn phòng
Câu lệnh input()
chuyển dữ liệu người dùng nhập thành chuỗi nên a sẽ có kiểu dữ liệu chuỗi (string). Các bạn sẽ kiểm tra giá trị người chơi nhập vào từ bàn phím để xem người chơi chọn cửa số mấy để thám hiểm. Vì a có kiểu dữ liệu chuỗi nên chúng ta sẽ kiểm tra với “1”, “2”, “3”, “4”. Chúng ta lưu ý phải có dấu ""
. Để kiểm tra xem hai chuỗi có giống nhau không chúng ta có thể sử dụng ==
. Khi kiểm tra, kết quả trả về sẽ có kiểu dữ liệu boolean True
hoặc False
. Vì có bốn phòng nên chúng ta sẽ sử dụng câu lệnh điều kiện rẽ nhánh để kiểm tra xem người chơi chọn thám hiểm phòng nào:
if a == "1":
print("Bạn đang ở phòng 1.")
elif a == "2":
print("Bạn đang ở phòng 2.")
elif a == "3":
print("Bạn đang ở phòng 3.")
elif a == "4":
print("Bạn đang ở phòng 4.")
else:
print("Xin lỗi, bạn chỉ có thể nhập 1,2,3 hoặc 4")
Câu lệnh điều kiện rẽ nhánh sẽ kiểm tra điều kiện ở câu lệnh if
trước, sau đó sẽ đến điều kiện ở các câu lệnh elif
. Nếu tất cả điều kiện đó đều không thoả mãn thì sẽ thực hiện dòng lệnh ở else
. Dòng lệnh ở else
giúp nhắc nhở người chơi phải nhập các số 1, 2, 3, hoặc 4. Chúng ta lưu ý đi sau if
và elif
là điều kiện nhưng ở else
thì không. Có một cách rất hay để chúng ta có thể kiểm tra code mình viết (debug) đó là sử dụng câu lệnh print()
. Khi chạy code, chúng ta hãy nhập vào bất kì phòng nào và xem chương trình in ra màn hình đúng phòng không.
Sau khi kiểm tra phần chọn phòng, chúng ta sẽ thêm vào một câu lệnh để hỏi người chơi muốn chơi tiếp hay dừng lại:
exit_choice = input("Ấn Enter để chơi lại, hoặc gõ thoát để đóng trò chơi.")
Sau khi người dùng nhập câu trả lời, chúng ta phải kiểm tra và nếu người chơi muốn chơi tiếp, chúng ta sẽ thực hiện lại toàn bộ các câu lệnh ở trên. Các bạn hãy sử dụng kiến thức vòng lặp while
. Trong khi biến exit_choice không phải là “thoát” thì chúng ta sẽ quay lại thực hiện toàn bộ các câu lệnh. Để kiểm tra điều kiện không phải, chúng ta sử dụng !=
:
while exit_choice != "thoát":
Tuy nhiên, chương trình chúng ta vẫn còn một lỗi nho nhỏ đấy. Đó chính là khi lần đầu tiên chơi, biến exit_choice chưa được gán bất kỳ giá trị nào. Chúng ta có thể gán biến đó với bất kỳ giá trị nào, ngoại trừ “thoát” để có thể bắt đầu trò chơi:
exit_choice = "c"
Chương trình hoàn chỉnh sẽ là:
exit_choice = "c"
while exit_choice != "thoát":
if a == "1":
print("Bạn đang ở phòng 1.")
elif a == "2":
print("Bạn đang ở phòng 2.")
elif a == "3":
print("Bạn đang ở phòng 3.")
elif a == "4":
print("Bạn đang ở phòng 4.")
else:
print("Xin lỗi, bạn chỉ có thể nhập 1,2,3 hoặc 4")
exit_choice = input("Ấn Enter để chơi lại, hoặc gõ thoát để đóng trò chơi.")
Bước 3: Viết phần lựa chọn từng phòng:
Sau khi đã chia thành từng trường hợp, chúng ta sẽ đi theo sơ đồ đã vẽ ở sơ đồ 1. Với phòng 1, chúng ta sẽ in ra màn hình chúc mừng người chơi đã chọn đúng phòng có kho báu và hỏi người chơi muốn chơi tiếp hay dừng lại:
if a == "1":
print("Bạn đã tìm thấy một căn phòng chứa kho báu, phát tài rồi!")
print("Bạn đã thắng cuộc, trò chơi kết thúc.")
print("(Khởi động lại để tiếp tục khám phá.)")
Với phòng 2 có con yêu tinh, chúng ta sẽ in ra màn hình chia buồn với người chơi và hỏi người chơi muốn chơi tiếp hay dừng lại:
elif a == "2":
print("Cửa bật mở, một con yêu tinh xông ra và phang chuỳ vào đầu bạn.")
print("Bạn đã chết, trò chơi kết thúc.")
print("(Khởi động lại để tiếp tục khám phá.)")
Với phòng 3 có con rồng, chúng ta sẽ yêu cầu người chơi chọn làm gì sau khi thấy con rồng. Có ba lựa chọn tương ứng với ba số 1, 2, 3:
elif a == "3":
print("Bạn bước vào căn phòng và thấy một con rồng đang ngủ say, bạn sẽ: ")
print("1: Hét to lên để hăm doạ con rồng.")
print("2: Từ từ đi ra khỏi phòng.")
print("3: Chả làm gì cả.")
b = input("Nhập lựa chọn của bạn vào đây: ")
Chúng ta sử dụng biến mới b để lưu câu trả lời của người chơi, tương tự như khi chúng ta hỏi người chơi chọn phòng nào. Và chúng ta cũng sẽ sử dụng câu lệnh điều kiện rẽ nhánh để chia thành các trường hợp lựa chọn:
if b == "1":
print("Con rồng giật mình và phun lửa vào bạn.")
print("Bạn đã bị thiêu rụi, trò chơi kết thúc.")
elif b == "2":
print("Bạn định ra khỏi phòng thì nhận ra cánh cửa đã khóa, bạn chạm vào tay nắm cửa cũ kỹ và nó phát ra tiếng động!")
print("Bẫy được kích hoạt, bạn rơi ra khỏi lâu đài và bạn thấy thành phố trước mắt mình.")
print("Bạn đã thoát, trò chơi kết thúc.")
print("(Khởi động lại để tiếp tục khám phá.)")
elif b == "3":
print("Bạn đứng đó hồi lâu và con rồng thức dậy, vừa nhìn thấy bạn, con rồng lập tức nuốt chửng bạn ngay!")
print("Bạn đã trở thành bữa ăn ngon cho rồng, bạn đã chết, trò chơi kết thúc.")
print("(Khởi động lại để tiếp tục khám phá.)")
else:
print("Xin lỗi, bạn chỉ có thể nhập 1,2,3.")
Ở căn phòng cuối cùng có một con nhân sư yêu cầu nhà thám hiểm phải đoán được số nó đang nghĩ. Chúng ta cũng bắt đầu nhánh ở phòng 4 bằng việc hỏi người chơi đoán số nhân sư đang nghĩ:
elif a == "4":
print("Căn phòng bạn bước vào có một con nhân sư.")
print("Nhân sư bắt bạn phải đoán được số mà nó đang nghĩ đến trong các số nguyên từ 1 đến 10.")
print("Nếu bạn đoán đúng, nhân sư sẽ cho bạn đi.")
print("Ngược lại bạn phải làm nô lệ cho nó!")
number = int(input("Bạn chọn số nào: "))
Chúng ta cùng tìm hiểu cách để nhân sư nghĩ ra một số ngẫu nhiên. Để có thể tạo một số nguyên ngẫu nhiên từ 1 đến 10, chúng ta sẽ sử dụng thư viện (library) random trong Python. Thư viện random sẽ gồm rất nhiều câu lệnh nhỏ với những chức năng khác nhau. Ở đây chúng ta sẽ sử dụng random.randint() với hai input là 1 và 10. Tuy nhiên trước hết, chúng ta phải gọi thư viện đó trong Python bằng câu lệnh import.
Chúng ta sử dụng câu lệnh int()
để chuyển kiểu dữ liệu từ chuỗi (string) sang số nguyên (int). Mục đích để kiểm tra số người dùng nhập và số nguyên tạo ngẫu nhiên bằng random.randint():
import random
if number == random.randint(1,10):
print("Nhân sư gầm lên thất vọng. Bạn đã đoán đúng.")
print("Nhân sư phải thả bạn đi.")
print("Bạn đã chiến thắng. Trò chơi kết thúc.")
print("(Khởi động lại để tiếp tục khám phá.)")
else:
print("Nhân sư cười khoái trá. Bạn đã đoán sai!")
print("Bạn đã trở thành nô lệ của nhân sư!")
print("Bạn đã thua, trò chơi kết thúc.")
print("(Khởi động lại để tiếp tục khám phá.)")
Chúng ta sẽ thêm câu lệnh # -*- coding: utf-8 -*-
để hiển thị tiếng Việt. Đồng thời, các bạn học sinh lưu ý chương trình hoàn chỉnh phải lùi lề. Chương trình Python hoàn chỉnh của game sẽ là:
# -*- coding: utf-8 -*-
import random
LAUDAI = """
|>>> |>>>
| |>>> |>>> |
* | | *
/ \ * * / \
/___\ _/ \ / \_ /___\
[ ] |/ \_________/ \| [ ]
[ I ] / \ / \ [ I ]
[ ]_ _ _ / \ / \ _ _ _[ ]
[ ] U U | {#########} {#########} | U U [ ]
[ ]====/ \=======/ \=======/ \====[ ]
[ ] | | I |_ _ _ _| I | | [ ]
[___] |_ _ _ _ _ _| | U U U | |_ _ _ _ _ _| [___]
\===/ I | U U U U U | |=======| | U U U U U | I \===/
\=/ |===========| I | + W + | I |===========| \=/
| I | | |_______| | | I |
| | | ||||||||| | | |
| | | I ||vvvvv|| I | | |
_-_-|______|-----------|_____|| ||_____|-----------|______|-_-_
/________\ /______|| ||______\ /________\
|__________|-------|________\_____/________|-------|__________|
"""
exit_choice = "c"
while exit_choice != "thoát":
print("Bạn đang ở trong một căn phòng tối tăm nằm trong một lâu đài bí hiểm.")
print(LAUDAI)
print("Có 4 cánh cửa trước mặt bạn, bạn hãy chọn một cánh cửa để thám hiểm.")
a = input("Bạn chọn cánh cửa số: ")
if a == "1":
print("Bạn đã tìm thấy một căn phòng chứa kho báu, phát tài rồi!")
print("Bạn đã thắng cuộc, trò chơi kết thúc.")
print("(Khởi động lại để tiếp tục khám phá.)")
elif a == "2":
print("Cửa bật mở, một con yêu tinh xông ra và phang chuỳ vào đầu bạn.")
print("Bạn đã chết, trò chơi kết thúc.")
print("(Khởi động lại để tiếp tục khám phá.)")
elif a == "3":
print("Bạn bước vào căn phòng và thấy một con rồng đang ngủ say, bạn sẽ: ")
print("1 : Hét to lên để hăm doạ con rồng.")
print("2 : Từ từ ra khỏi phòng.")
print("3 : Chả làm gì cả.")
b = input("Nhập lựa chọn của bạn vào đây: ")
if b == "1":
print("Con rồng giật mình và phun lửa vào bạn.")
print("Bạn đã bị thiêu rụi, trò chơi kết thúc.")
elif b == "2":
print("Bạn định ra khỏi phòng thì nhận ra cánh cửa đã khóa, bạn chạm vào tay nắm cửa cũ kỹ và nó phát ra tiếng động!")
print("Bẫy được kích hoạt, bạn rơi ra khỏi lâu đài và bạn thấy thành phố trước mắt mình.")
print("Bạn đã thoát, trò chơi kết thúc.")
print("(Khởi động lại để tiếp tục khám phá.)")
elif b == "3":
print("Bạn đứng đó hồi lâu và con rồng thức dậy, vừa nhìn thấy bạn, con rồng lập tức nuốt chửng bạn ngay!")
print("Bạn đã trở thành bữa ăn ngon cho rồng, bạn đã chết, trò chơi kết thúc.")
print("(Khởi động lại để tiếp tục khám phá.)")
else:
print("Xin lỗi, bạn chỉ có thể nhập 1,2,3.")
elif a == "4":
print("Căn phòng bạn bước vào có một con nhân sư.")
print("Nhân sư bắt bạn phải đoán được số mà nó đang nghĩ đến trong các số nguyên từ 1 đến 10.")
print("Nếu bạn đoán đúng, nhân sư sẽ cho bạn đi.")
print("Ngược lại bạn phải làm nô lệ cho nó!")
number = int(input("Bạn chọn số nào: "))
if number == random.randint(1,10):
print("Nhân sư gầm lên thất vọng. Bạn đã đoán đúng.")
print("Nhân sư phải thả bạn đi.")
print("Bạn đã chiến thắng. Trò chơi kết thúc.")
print("(Khởi động lại để tiếp tục khám phá.)")
else:
print("Nhân sư cười khoái trá. Bạn đã đoán sai!")
print("Bạn đã trở thành nô lệ của nhân sư!")
print("Bạn đã thua, trò chơi kết thúc.")
print("(Khởi động lại để tiếp tục khám phá.)")
else:
print("Xin lỗi, bạn chỉ có thể nhập 1,2,3 hoặc 4")
exit_choice = input("Ấn Enter để chơi lại, hoặc gõ thoát để đóng trò chơi.")
STEAM for Vietnam khuyến khích các bạn học sinh hãy thử sáng tạo cốt truyện, tạo nhiều phòng và thử thách cho nhà thám hiểm hơn. Bên cạnh đó, các bạn cũng có thể cải tiến thêm cho game như thế này: khi người chơi nhập sai yêu cầu (Ví dụ: không phải các số từ 1 đến 4 cho số phòng), chương trình sẽ cho người chơi nhập lại đến khi đúng.
Chỉ với những kiến thức từ hai bài đầu tiên của khoá CS101, bạn Hoàng Long đã tạo ra được một game đơn giản nhưng cũng không kém phần thú vị và gay cấn. STEAM for Vietnam tin rằng bạn học sinh nào cũng có thể sáng tạo dự án cá nhân đầy ấn tượng như vậy. Các bạn hãy thử bắt tay vào thực hiện dự án nhé! Sau khi hoàn thành game, các bạn có thể chia sẻ game của mình trên STEAMese Profile để khoe cùng mọi người.
— — —
STEAM for Vietnam Foundation là tổ chức phi lợi nhuận 501(c)(3) được thành lập tại Hoa Kỳ với sứ mệnh thúc đẩy các hoạt động liên quan tới giáo dục STEAM (Science — Khoa học, Technology — Công nghệ, Engineering — Kỹ thuật, Arts — Nghệ thuật, Mathematics — Toán học) tại Việt nam. STEAM for Vietnam được thành lập và vận hành bởi đội ngũ tình nguyện viên là du học sinh và chuyên gia người Việt trên khắp thế giới.
— — —
📧Email: hello@steamforvietnam.org
🌐Website: www.steamforvietnam.org
🌐Fanpage: STEAM for Vietnam
📺YouTube: http://bit.ly/S4V_YT
🌐Zalo: Zalo Official