Các bạn học sinh có còn nhớ dự án ““Nhà thám hiểm và cánh cửa bí mật” hay không? Ở dự án đó, nhà thám hiểm đã phải trải qua hành trình thật khó khăn khi phải lựa chọn 4 căn phòng bí ẩn, thế nhưng bạn ấy đã thành công lấy được kho báu và rời khỏi lâu đài. Trở lại với tòa lâu đài cổ kính đầy rẫy nguy hiểm, các con quái vật sau khi để mất kho báu đã họp bàn với nhau để tìm cách bảo vệ tòa lâu đài tốt hơn. Vậy là, nhân sư đã nâng cấp trò chơi của mình, không còn chỉ là game đoán số thông thường, mà là một thử thách sắp xếp đòi hỏi khả năng tính toán chính xác.
Lần này, nhà thám hiểm lại quyết định quay trở lại tòa lâu đài bí ẩn. Làm thế nào để các bạn học sinh có thể giúp cho nhà thám hiểm an toàn rời khỏi nơi nguy hiểm đó? Để vượt qua thử thách của nhân sư, nhiệm vụ của chúng ta là sắp xếp các dãy số lộn xộn theo thứ tự từ lớn đến bé hoặc từ bé đến lớn. Chúng ta sẽ được chọn mình sắp xếp bao nhiêu số. Đặc biệt, các số trong dãy số sẽ ở dưới dạng các biểu thức cộng trừ, đòi hỏi sự tính toán thật nhanh và chính xác. Hãy thử sức chơi game với nhân sư ngay nào:
https://s4v.trinket.io/sites/sorting
Kiến thức lập trình
Một số kiến thức chúng ta đã được học ở khoá CS 101 sẽ được áp dụng để hoàn thành game nhập vai đơn giản này:
- Thư viện random để tạo số ngẫu nhiên.
- Vòng lặp for và while trong Python.
- Hàm (function) trong Python
- Chuỗi ký tự gồm nhiều dòng (Multi-line String)
- Mảng trong Python
Bắt đầu code thôi nào !!!!!
- Luật chơi:
Trò chơi bắt đầu khi nhân sư tạo một dãy số ngẫu nhiên dưới dạng các biểu thức cộng, trừ. Nếu sắp xếp theo thứ tự từ bé đến lớn, nhân sư sẽ hỏi người chơi lần lượt từ số bé nhất, số bé thứ hai, số bé thứ ba,… đến số lớn nhất.
Ví dụ: Một dãy số gồm các biểu thức: 3+1, 3-2, 1+1, 2+3. Sau khi tính toán, dãy số đó sẽ là 4, 1, 2, 5. Nhân sư yêu cầu người chơi sắp xếp từ bé đến lớn. Nhân sư sẽ hỏi: Số thứ nhất là số nào? Câu trả lời đúng là số 1. Nếu người chơi trả lời sai, trò chơi sẽ kết thúc. Nếu người chơi trả lời đúng, nhân sư sẽ tiếp tục hỏi: Số thứ hai là số nào? Câu trả lời đúng là 2. Nếu người chơi trả lời sai, trò chơi sẽ kết thúc. Nếu người chơi trả lời đúng, nhân sư sẽ tiếp tục hỏi số thứ ba. Trò chơi tiếp tục như thế đến số cuối cùng. Nếu người chơi trả lời đúng hết thì người chơi sẽ chiến thắng.
Luật chơi tương tự với trường hợp sắp xếp từ lớn đến bé.
- Thuật toán:
Chúng ta sẽ tạo một thuật toán đơn giản để có thể mô phỏng trò chơi này. Chúng ta sẽ sử dụng hai mảng. Một mảng lưu các biểu thức dưới dạng chuỗi. Mảng còn lại lưu kết quả các biểu thức đó. Ví dụ: Mảng lưu dãy các biểu thức: [‘3+1’, ‘3-2’, ‘1+1’, ‘2+3’]. Sau khi tính toán, mảng còn lại sẽ lưu kết quả dãy số đó sẽ là [4, 1, 2, 5]. Ở đây, mục đích của mảng gồm các chuỗi là dùng để in ra màn hình cho người chơi. Mảng kết quả gồm các số sẽ dùng để sắp xếp.
Trong luật chơi, nhân sư sẽ hỏi lần lượt các số theo thứ tự từ bé đến lớn (hoặc từ lớn đến bé). Vì vậy, chúng ta có thể tìm số bé nhất (hoặc lớn nhất) trong mảng. Qua mỗi lần nhân sư hỏi, chúng ta sẽ bỏ số bé nhất (hoặc lớn nhất) ra khỏi mảng, và tiếp tục tìm số bé nhất (hoặc lớn nhất) của mảng mới đến khi mảng không còn phần tử nào.
Ví dụ: Dãy gồm các biểu thức: 3+1, 3-2, 1+1, 2+3. Sau khi tính toán, dãy kết quả sẽ là 4, 1, 2, 5. Nhân sư yêu cầu người chơi sắp xếp từ bé đến lớn.
- Ở lượt thứ nhất, số bé nhất là 1. Sau lượt thứ nhất, chúng ta sẽ bỏ số 1 ra khỏi mảng. Mảng mới sẽ gồm 3 số là 4, 2, 5.
- Ở lượt thứ hai, số bé nhất là 2. Sau lượt thứ hai, chúng ta sẽ bỏ số 2 ra khỏi mảng. Mảng mới sẽ gồm 2 số là 4, 5.
- Ở lượt thứ ba, số bé nhất là 4. Sau lượt thứ ba, chúng ta sẽ bỏ số 4 ra khỏi mảng.
- Mảng mới sẽ còn lại số 5. Số 5 là số cuối cùng. Như vậy, chúng ta đã gián tiếp sắp xếp dãy số ban đầu từ bé đến lớn.
3. Code:
Bước 1: Viết hàm giới thiệu game
Trước tiên, chúng ta sẽ tạo một hàm sử dụng câu lệnh print() để in ra màn hình luật chơi cũng như giới thiệu về game:
def intro():
print('''
---
NUMBER SORTING ++
---
RULE: Nhiệm vụ của trò chơi là sắp xếp 1 dãy số lộn xộn theo thứ tự từ bé đến lớn hoặc từ lớn đến bé.
Người chơi sẽ được chọn sắp xếp bao nhiêu số trong dãy số
Đặc biệt: Các số trong dãy sẽ được cho dưới dạng các biểu thức cộng trừ, đòi hỏi chúng ta cần kĩ năng tính toán cực cao nữa đó!
''')
Ở bài số 2, chúng ta đã biết về kiểu dữ liệu chuỗi (string). Từ trước đến nay, ta đều nhận thấy dữ liệu string phải ở trong cùng 1 dòng bắt đầu và kết thúc với dấu “”. Tuy nhiên, nếu ta sử dụng ”’ ”’ (3 dấu ‘), dữ liệu chuỗi có thể gồm nhiều dòng khác nhau (multi-line string).
Bước 2: Viết câu lệnh tương tác với người dùng ở đầu game
Tương tự như dự án “Nhà thám hiểm và cánh cửa bí mật”, chúng ta sẽ tạo một vòng lặp while để hỏi người chơi muốn tiếp tục trò chơi hay dừng lại. Đồng thời chúng ta sẽ in ra luật chơi bằng cách gọi hàm intro đã viết ở bước 1. Chúng ta lưu ý để gọi hàm intro, chúng ta chỉ cần dùng intro() vì hàm không return gì cả. Chúng ta cũng sẽ tạo một biến để hỏi người chơi muốn sắp xếp bao nhiêu số bằng câu lệnh input.
condition = True
while condition == True:
intro()
number_guest = int(input("Bạn muốn sắp xếp bao nhiêu số nhỉ? >> "))
again = input('Bạn muốn chơi tiếp không? [Y/N]')
if again == 'N':
condition = False
Bước 3: Viết hàm tạo dãy số ngẫu nhiên
Trò chơi sẽ gồm bốn loại biểu thức: a+b, a-b, a+b-c, a-b+c. a, b, c là các số nguyên ngẫu nhiên từ 1 đến 60. Chúng ta sẽ sử dụng câu lệnh random.randint(1,60) tương tự như dự án “Nhà thám hiểm và cánh cửa bí mật”. Mỗi biểu thức trong dãy số sẽ được chọn ngẫu nhiên từ bốn loại biểu thức bằng câu lệnh random.choice tương tự như dự án “Câu chuyện ngẫu nhiên”.
Chúng ta sẽ sử dụng hai mảng raw_list1 và raw_list2. Mảng raw_list1 lưu biểu thức dưới dạng chuỗi và mảng raw_list2 lưu kết quả của biểu thức. Ở bài số 3, chúng ta đã biết câu lệnh append dùng để lưu dữ liệu vào mảng. Ngoài ra để đổi số thành chuỗi chúng ta sẽ sử dụng hàm str. Để kết nối hai chuỗi, chúng ta sẽ sử dụng phép toán +. Ngoài ra chúng ta cũng không muốn các số trong dãy số lặp lại nên sẽ dùng câu lệnh not in để kiểm tra. “Not in” có nghĩa là không ở trong cái gì đó.
Chúng ta sẽ tạo hai mảng trống rawlist1 và rawlist2. Để dãy số có đủ số mà người chơi muốn sắp xếp, chúng ta sẽ sử dụng vòng lặp while và biến đếm i. Chúng ta sẽ đặt tên cho hàm tạo dãy số ngẫu nhiên là prep. Hàm nhận vào số biểu thức người chơi muốn sắp xếp và trả về hai mảng:
def prep(number_sort):
rawlist1 = []
rawlist2 = []
i = 0
while i < number_sort:
a = random.randint(1,60)
b = random.randint(1,60)
c = random.randint(1,60)
options = ["a+b", "a-b", "a+b-c", "a-b+c"]
option = random.choice(options)
if option == 'a+b' and a+b not in rawlist1:
rawlist1.append(str(a)+ ' + '+ str(b))
rawlist2.append(a+b)
elif option == 'a-b' and a-b not in rawlist2:
rawlist1.append(str(a)+ ' - '+ str(b))
rawlist2.append(a-b)
elif option == 'a+b-c' and a+b-c not in rawlist2:
rawlist1.append(str(a) + "+" + str(b) + "-" + str(c))
rawlist2.append(a+b-c)
elif option == 'a-b+c' and a-b+c not in rawlist2:
rawlist1.append(str(a) + "-" + str(b) + "+" + str(c))
rawlist2.append(a-b+c)
i = i + 1
return rawlist1, rawlist2
Bước 4: Viết hàm trả về số bé nhất (hoặc lớn nhất)
Chúng ta sẽ sử dụng hai hàm có sẵn ở trong Python. Hàm min dùng để tìm số bé nhất trong mảng và hàm max để tìm số lớn nhất trong mảng. Chúng ta sẽ đặt tên hàm cần viết là sorting. Hàm nhận vào mảng (dãy số) và kiểu sắp xếp. Kiểu sắp xếp nhận một trong hai giá trị: 0 (sắp xếp từ bé đến lớn) hoặc 1 (sắp xếp từ lớn đến bé). Hàm trả về số bé nhất (hoặc lớn nhất) tương ứng với cách sắp xếp.
def sorting(arr, sort_type):
if sort_type == 0:
return min(arr)
else:
return max(arr)
Bước 5: Hoàn thiện code
Sau khi hỏi người chơi muốn sắp xếp bao nhiêu số, chúng ta sẽ chọn ngẫu nhiên cách sắp xếp bằng sử dụng câu lệnh random.randint(0,1). Nếu kết quả là 0 thì sắp xếp từ bé đến lớn. Nếu kết quả là 1 thì sắp xếp từ lớn đến bé.
Chúng ta sẽ gọi hàm prep để tạo dãy số ngẫu nhiên đã viết ở bước 2. Chúng ta sẽ in ra màn hình mảng gồm các biểu thức cần sắp xếp và cách thức sắp xếp.
import random
condition = True
while condition == True:
intro()
number_guest = int(input('Bạn muốn sắp xếp bao nhiêu số ? >>'))
sort_type = random.randint(0,1)
raw_list1, raw_list2 = prep(number_guest)
if sort_type == 0:
print('Sắp xếp dãy số theo thứ tự từ bé đến lớn: ' + str(raw_list1))
else:
print('Sắp xếp dãy số theo thứ tự từ lớn đến bé: ' + str(raw_list1))
again = input('Bạn có muốn chơi tiếp không? [Y/N]')
if again == 'N':
condition = False
Chúng ta sẽ tạo một vòng lặp while với biến đếm counter để đi qua số lượt nhân sư sẽ hỏi người chơi (bằng với số phần tử của mảng). Với mỗi lượt hỏi, chúng ta sẽ thực hiện ba công việc:
- Tìm số bé nhất (hoặc lớn nhất) trong mảng.
- Hỏi người chơi xem số tiếp theo trong dãy sau khi được sắp xếp là số nào. Kiểm tra đúng hay sai. Nếu đúng thực hiện bước tiếp theo. Nếu sai thoát khỏi vòng lặp.
- Bỏ số tìm được ở công việc đầu tiên ra khỏi mảng.
Để tìm số lớn nhất (bé nhất), chúng ta sử dụng hàm đã viết ở bước 3. Chúng ta sử dụng câu lệnh điều kiện giống như thuật toán Cánh cửa bí mật ở bài số 2 để kiểm tra người chơi có nhập đúng số không. Để bỏ một số ra khỏi mảng, chúng ta sẽ sử dụng hàm remove:
turn = len(raw_list2)
counter = 0
while counter < turn:
number = sorting(raw_list2, sort_type)
guess = int(input('Sau khi sắp xếp, số ở vị trí số '+ str(counter + 1) + ' là: >>'))
if guess == int(number):
if counter == turn - 1:
print('Chúc mừng chiến thắng')
else:
print('Đúng rồi! Tiếp tục nào!')
else:
print('Bạn đã thua, câu trả lời là ' + str(number))
break
raw_list2.remove(number)
counter = counter + 1
4. Tada!!!
Như vậy chúng ta đã hoàn thành xong một game rất thú vị đúng không nào. Các bạn học sinh đã thành công áp dụng kiến thức về hàm đã học ở bài số 4 để viết một thuật toán sắp xếp một dãy số. Ngoài ra, chúng ta cũng biết thêm một số hàm mới có sẵn trong Python giúp chúng ta code thuận tiện hơn
Chương trình Python hoàn chỉnh của game sẽ là:
# -*- coding: utf-8 -*-
import random
def intro():
print('''
---
NUMBER SORTING ++
---
RULE: Nhiệm vụ của trò chơi là sắp xếp 1 dãy số lộn xộn theo thứ tự từ bé đến lớn hoặc từ lớn đến bé.
Người chơi sẽ được chọn sắp xếp bao nhiêu số trong dãy số
Đặc biệt: Các số trong dãy sẽ được cho dưới dạng các biểu thức cộng trừ, đòi hỏi chúng ta cần kĩ năng tính toán cực cao nữa đó!
''')
def prep(number_sort):
rawlist1 = []
rawlist2 = []
i = 0
while i < number_sort:
a = random.randint(1,60)
b = random.randint(1,60)
c = random.randint(1,60)
options = ["a+b", "a-b", "a+b-c", "a-b+c"]
option = random.choice(options)
if option == 'a+b' and a+b not in rawlist1:
rawlist1.append(str(a)+ ' + '+ str(b))
rawlist2.append(a+b)
elif option == 'a-b' and a-b not in rawlist2:
rawlist1.append(str(a)+ ' - '+ str(b))
rawlist2.append(a-b)
elif option == 'a+b-c' and a+b-c not in rawlist2:
rawlist1.append(str(a) + "+" + str(b) + "-" + str(c))
rawlist2.append(a+b-c)
elif option == 'a-b+c' and a-b+c not in rawlist2:
rawlist1.append(str(a) + "-" + str(b) + "+" + str(c))
rawlist2.append(a-b+c)
i = i + 1
return rawlist1, rawlist2
def sorting(arr, sort_type):
if sort_type == 0:
return min(arr)
else:
return max(arr)
condition = True
while condition == True:
intro()
number_guest = int(input('Bạn muốn sắp xếp bao nhiêu số ? >>'))
sort_type = random.randint(0,1)
raw_list1, raw_list2 = prep(number_guest)
if sort_type == 0:
print('Sắp xếp dãy số theo thứ tự từ bé đến lớn: ' + str(raw_list1))
else:
print('Sắp xếp dãy số theo thứ tự từ lớn đến bé: ' + str(raw_list1))
turn = len(raw_list2)
counter = 0
while counter < turn:
number = sorting(raw_list2, sort_type)
guess = int(input('Sau khi sắp xếp, số ở vị trí số '+ str(counter + 1) + ' là: >>'))
if guess == int(number):
if counter == turn - 1:
print('Chúc mừng chiến thắng')
else:
print('Đúng rồi! Tiếp tục nào!')
else:
print('Bạn đã thua, câu trả lời là ' + str(number))
break
raw_list2.remove(number)
counter = counter + 1
again = input('Bạn có muốn chơi tiếp không? [Y/N]')
if again == 'N':
condition = False
Các bạn học sinh hãy tự do sáng tạo theo những ý tưởng của riêng mình. Chúng ta có rất nhiều cách để cải tiến game khác lạ hơn. Thầy cô gợi ý các bạn có thể sắp xếp dãy số bằng hàm có sẵn trong Python là sorted. Sắp xếp dãy số trước khi hỏi người chơi sẽ giúp chương trình chúng ta chạy nhanh hơn. Ngoài ra, các bạn có thể thêm vào những loại biểu thức khác nhau, và thêm phép tính nhân, chia. Các bạn học sinh hãy thử tạo nên dự án của riêng mình và chia sẻ game của mình trên STEAMese Profile nhé!
— — —
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