Bài giảng Lập trình nâng cao: Hàm cung cấp cho người học các kiến thức: Đoán số (guess it), chuyển hóa vấn đề thành chương trình, kỹ thuật sinh số ngẫu nhiên, kỹ thuật vòng lặp, điều kiện vòng lặp, kỹ thuật mô-đun hóa chương trình bằng hàm.
Trang 1Game: Guess It
2 - Hàm
https://github.com/tqlong/advprogram
Trang 2Nội dung
Trang 3Đoán số: Luật chơi
Tìm kiếm nhị phân (Binary Search)
Trang 4Đoán số: Chương trình
từ 1 đến 100
○ Nếu đúng, người chơi thắng cuộc Nếu sai, máy sẽ trả lời con số người chơi đoán lớn hơn hay nhỏ hơn con số của máy để người chơi tiếp tục đoán số
- B)
Trang 6Nội dung
● Game: Đoán số (Guess It)
Trang 7Mô tả thành các bước (bằng lời)
Trang 8Mô tả thành các bước (gần máy)
Nếu người chơi đoán sai Quay lại B2
Nếu người chơi đoán đúng Chuyển tới B5
Trang 9Chương trình (mã giả, gần máy)
randomNumber = generateRandomNumber(); // B1 while (true) {
Trang 11void printAnswer(int number, int randomNumber)
Viết chương trình như kể một câu chuyện
● Tên biến = cụm danh từ
● Tên hàm = cụm động từ
Trang 12● Tiếng Anh là ngôn ngữ của Công nghệ thông tin (IT - Information Technology):
○ Từ khoá ngôn ngữ lập trình
○ Tài liệu, sách vở tiếng Anh nhiều
○ Tìm kiếm trên Internet; Trao đổi với người các nước (không chỉ Anh, Mỹ, Úc)
đưa “app” của mình lên Internet
Sao lại tiếng Anh ? Khó thế :(
Trang 13in t g etP layerG uess();
void p rin tA nsw er(in t num ber, in t random N um ber);
in t m ain() {
in t random N um ber = generateRandom N um ber();
in t num ber;
d o { num ber = getPlayerG uess();
printAnsw er(num ber, random N um ber);
} w h ile (num ber != random N um ber);
return ; }
Trang 14Nội dung
● Game: Đoán số (Guess It)
Trang 15Máy tính nghĩ số
○ Tìm kiếm Google: “C++ random”
○ Hàm rand() trong <cstdlib>
○ Hằng RAND_MAX
v1 = rand() % 100; // v1 in the rang e 0 to 99 v2 = rand () % 100 + 1; // v2 in the rang e 1 to 100 v3 = rand () % 30 + 1985; // v3 in the rang e 1985- 2014
int rand om N um b er = rand() % 100 +
1;
Trang 16in t g etP layerG uess();
void p rin tA nsw er(in t num ber, in t random N um ber);
in t m ain() {
in t random N um ber = generateRandom N um ber();
in t num ber;
d o { num ber = getPlayerG uess();
printAnsw er(num ber, random N um ber);
} w h ile (num ber != random N um ber);
return ; }
int generateR and om N um b er()
{
return rand() % 100 + 1;
}
Trang 17Nhập con số người chơi đoán
int num ber;
cout < < endl < < "Enter your num ber: "; cin > > num ber;
Trang 18Guess It 1.1
in t m ain() {
in t random N um ber = generateRandom N um ber();
in t num ber;
d o { num ber = getPlayerG uess();
printAnsw er(num ber, random N um ber);
} w h ile (num ber != random N um ber);
return ; }
int getP layerG uess()
{
int num ber;
cout < < endl < < "Enter your num ber betw een 1 and 100: "; cin > > num ber;
return num ber;
}
Trang 19Máy tính chọn câu trả lời
if (num ber > random N um ber) {
cout < < "Your num ber is too big." < < endl;
} else if (num ber < random N um ber) {
cout < < "Your num ber is too sm all." < < endl; } else {
cout < < "Congratulation! You w in." < < endl;
}
Trang 20Guess It 1.1
in t m ain() {
in t random N um ber = generateRandom N um ber();
in t num ber;
d o { num ber = getPlayerG uess();
printAnsw er(num ber, random N um ber);
} w h ile (num ber != random N um ber);
return ; }
void p rintA nsw er(int num ber, int random N um ber)
{
if (num ber > random N um ber) {
cout < < "Your num ber is too big." < < endl;
} else if (num ber < random N um ber) {
cout < < "Your num ber is too sm all." < < endl;
} else {
cout < < "Congratulation! You w in." < < endl;
}
}
Trang 21cout < < "Congratulation! You w in." < < endl; }
}
Trang 22Lặp lại (Game loop)
Trang 23Kết quả
C:\softw are\cygw in64\hom e\doe\advprogram \lec2-guessit\G uessIt.exe
Enter your num ber betw een 1 and 100: 50
Your num ber is too big.
Enter your num ber betw een 1 and 100: 25
Your num ber is too sm all.
Enter your num ber betw een 1 and 100: 42
Congratulation! You w in.
Trang 24Thực hành
10000 - 2 x 100 - 2 x 99 - …
tùy theo số lần người chơi đoán
○ Hỏi người chơi có muốn chơi tiếp không ?
○ Gợi ý: đưa toàn bộ mã trong hàm main() vào một hàm playGuessIt()
Trang 25Cho phép chơi nhiều ván
máy “nghĩ” lại cùng một con số
● Khởi tạo “hạt giống” cho hàm rand() bằng thời gian bắt đầu chạy chương trình
○ Lưu ý: chỉ cần gọi srand() một lần.
● Mỗi lần chạy, chương trình dùng một hạt giống khác nhau : thời gian hiện hành
Trang 26Tổng kết
○ Mô-đun hóa bằng hàm
○ Truyền tham số bằng giá trị
○ Không thể thiếu tiếng Anh
Trang 27Máy chơi Guess It
○ Người làm chủ trò, nghĩ số từ 1 đến 100
○ Máy đoán số
○ Người “thông báo” cho máy giá trị máy đoán lớn hơn, nhỏ hơn hay đúng bằng giá trị cần tìm
○ Đoán ngẫu nhiên
○ Đoán tuần tự từ 1 đến 100 (hoặc ngược lại)
○ Đoán “đại” một số, nhận trả lời của người chơi để phán đoán lần sau nên đoán thế nào
Trang 28Thuật toán chung
B1: select a number X in [1, 100]B2: ask for host’s answer on XB3: if X is right, exit (win)
else goto B1
Trang 29Thuật toán chung
int X, answ er;
tùy thuộc vào hàm selectNumber() mà
ta có các cách đoán (thuật toán đoán)
cin > > answ er;
return answ er;
}
Trang 30Đoán ngẫu nhiên (may rủi)
int selectN um ber(int low , int high)
Trang 31Tìm kiếm tuần tự (chắc ăn)
int selectN um b er(int low , int high)
Trang 32Đoán đại rồi chỉnh khoảng tin cậy
int selectN um ber(int low , int high)
X = selectN um ber(low , high);
answ er = getH ostAnsw er(X);
if (answ er = = '> ') high = X-1; // X lớn hơn nên gia ảm high
if (answ er = = '< ') low = X+ 1; // X nho ả hơn nên tăng low
so với lần lặp trước
→ giống tìm kiếm
tuần tự (không may)
Trang 33Cải tiến khoảng tin cậy
○ Chọn số X là điểm giữa khoảng [low, high]
○ Mỗi lần đoán (sai), kích thước khoảng tin cậy giảm ít nhất 1 nửa
○ Số lần đoán tối đa ≈ log2100 = 7
Trang 34Thuật toán chia đôi
int selectN um ber(int low , int high)
X = selectN um ber(low , high);
answ er = getH ostAnsw er(X);
if (answ er = = '> ') high = X-1; // X lớn hơn nên gia ảm high
if (answ er = = '< ') low = X+ 1; // X nho ả hơn nên tăng low
} w hile (answ er != '= ');
chắc chắn giảm kích thước khoảng tin cậy ít nhất một nửa