Chào mừng đến với Bài 9: Trận chiến sống còn của chú Rắn! Đây là chặng bay cuối cùng để hoàn thiện trò chơi này.
Ở bài trước, chú rắn của chúng ta đã biết bò và nghe lời điều khiển từ bàn phím. Hôm nay, chúng ta sẽ lập trình 3 quy luật sinh tồn quan trọng nhất của trò chơi:
Ăn mồi: Khi đầu rắn chạm vào mồi $\rightarrow$ mồi nhảy đi chỗ khác, điểm số tăng lên và thân rắn dài ra.
Xử lý thân rắn: Khi rắn bò, các đốt thân phía sau phải tự động bò theo đầu rắn.
Va chạm (Game Over): Đâm vào tường hoặc tự cắn vào đuôi mình thì trò chơi sẽ kết thúc.
Để làm thân rắn dài ra, chúng ta cần dùng đến Danh sách (List) ở Bài 5 để chứa các đốt thân mới. Mỗi khi rắn ăn mồi, ta sẽ tạo ra một đốt thân mới và ném vào danh sách này.
Chúng ta tìm lên phần trên của file (dưới chỗ tạo moi) để khai báo thêm danh sách thân rắn và biến điểm số:
# Danh sách chứa các đốt thân của rắn (Ban đầu chưa ăn gì nên danh sách trống)
cac_dot_than = []
# Biến số lưu điểm (Bài 2)
diem = 0
Logic cho con:
"Làm sao máy tính biết rắn đã ăn được mồi? Chúng ta sẽ dùng toán học: Nếu khoảng cách giữa đầu rắn và viên mồi nhỏ hơn 20 pixel (kích thước của đầu rắn), nghĩa là chúng đã chạm vào nhau!"
Chúng ta gõ đoạn code này vào bên trong vòng lặp while True (ngay dưới lệnh di_chuyen()):
# Kiểm tra va chạm giữa Đầu rắn và Mồi
if dau_ran.distance(moi) < 20:
# 1. Bắt mồi nhảy sang một vị trí ngẫu nhiên trên màn hình
import random
x = random.randint(-280, 280)
y = random.randint(-280, 280)
moi.goto(x, y)
# 2. Tạo ra một đốt thân mới (hình vuông màu xanh nhạt hơn cho đẹp)
dot_moi = turtle.Turtle()
dot_moi.shape("square")
dot_moi.color("lightgreen")
dot_moi.penup()
cac_dot_than.append(dot_moi) # Bỏ đốt mới vào tủ chứa danh sách
# 3. Tăng điểm số
diem = diem + 10
print("Điểm của con hiện tại là:", diem)
Đây là phần đòi hỏi tư duy logic cao nhất bài. Chúng ta cần hiểu quy luật "bám đuôi":
"Khi xe lửa chạy, toa sau sẽ lao vào vị trí của toa trước vừa đi qua. Thân rắn cũng vậy: Đốt cuối cùng sẽ nhảy vào vị trí của đốt sát vách nó, cứ thế lùi dần lên cho đến đốt số 0 sẽ nhảy vào vị trí cũ của Đầu rắn."
Hãy gõ đoạn code di chuyển thân này ngay phía dưới đoạn code ăn mồi vừa rồi (vẫn ở trong while True):
# Di chuyển các đốt thân phía sau (Vòng lặp ngược từ dưới lên đầu)
for index in range(len(cac_dot_than) - 1, 0, -1):
x = cac_dot_than[index - 1].xcor()
y = cac_dot_than[index - 1].ycor()
cac_dot_than[index].goto(x, y)
# Riêng đốt đầu tiên (vị trí số 0) sẽ chạy theo đầu rắn
if len(cac_dot_than) > 0:
x = dau_ran.xcor()
y = dau_ran.ycor()
cac_dot_than[0].goto(x, y)
Game chỉ vui khi có thử thách! Nếu rắn đâm vào 4 bức tường (tọa độ vượt quá $\pm300$) hoặc đầu rắn chạm vào bất kỳ đốt thân nào trong danh sách cac_dot_than, trò chơi sẽ reset về ban đầu.
Hãy đoạn code xử lý luật chơi này vào cuối vòng lặp while True:
# 1. Kiểm tra đâm vào tường
if dau_ran.xcor() > 290 or dau_ran.xcor() < -290 or dau_ran.ycor() > 290 or dau_ran.ycor() < -290:
print("Oài! Đâm vào tường rồi! GAME OVER!")
time.sleep(1)
dau_ran.goto(0, 0)
dau_ran.direction = "stop"
# Xóa các đốt thân cũ trên màn hình
for dot in cac_dot_than:
dot.goto(1000, 1000) # Đẩy đốt cũ ra khỏi màn hình
cac_dot_than.clear() # Xóa sạch danh sách thân
diem = 0 # Reset điểm về 0
# 2. Kiểm tra tự cắn vào đuôi mình
for dot in cac_dot_than:
if dot.distance(dau_ran) < 20:
print("Cắn trúng đuôi rồi! GAME OVER!")
time.sleep(1)
dau_ran.goto(0, 0)
dau_ran.direction = "stop"
for d in cac_dot_than:
d.goto(1000, 1000)
cac_dot_than.clear()
diem = 0
Bây giờ hãy bấm nút Run để tận hưởng thành quả của chuỗi ngày học tập chăm chỉ vừa qua. Một trò chơi hoàn chỉnh, mượt mà do chính tay các con gõ từng dòng code đã hoạt động!
Sau khi chơi thử và thi đấu xem ai cao điểm hơn, chúng ta có thể thấy:
Lập trình không hề khó, chỉ cần có tư duy logic và sự kiên trì bẻ gãy từng lỗi sai (bugs) là làm được.
Gợi ý hướng đi tiếp theo: "Bây giờ ta đã tốt nghiệp khóa căn bản rồi. Sắp tới chúng ta có thể dựa trên những tư duy này để tìm hiểu và tự chế một ứng dụng điện thoại thực tế để dùng, hay làm các phần mềm giải toán thông minh hơn"
Cảm giác tự tay làm ra một trò chơi ở tuổi 12-14 sẽ kích hoạt niềm đam mê công nghệ cực kỳ lớn cho các bạn nhỏ. Chúc mừng các bạn đã hoàn thành khóa học!