You are on page 1of 19

ĐẠI HỌC KINH TẾ TP.

HỒ CHÍ MINH
TRƯỜNG CÔNG NGHỆ VÀ THIẾT KẾ
KHOA CÔNG NGHỆ THÔNG TIN KINH DOANH
BỘ MÔN CÔNG NGHỆ THÔNG TIN

BÁO CÁO ĐỒ ÁN HỌC PHẦN


CƠ SỞ LẬP TRÌNH

Đề tài: GAME GÕ CHỮ - FALLING LETTERS

GVHD: TS.GVC Lê Hữu Thanh Tùng

Nhóm thực hiện: _ 01_


Trần Viết Gia Huy (Trưởng nhóm)
Nguyễn Minh Huy
Bùi Trọng Nguyên
Nguyễn Văn Quân
Đỗ Trần Huy Vũ

TP. Hồ Chí Minh, Tháng 12/2023


MỤC LỤC
DANH MỤC HÌNH ẢNH. .....................................................................................................................3
Chương 1: GIỚI THIỆU VỀ ĐỀ TÀI ..................................................................................................4
Chương 2: CƠ SỞ LÝ THUYẾT VỀ ĐỀ TÀI .....................................................................................5
Chương 3: PHÂN TÍCH VÀ THIẾT KẾ .......................................................................................... 13
Chương 4: KẾT QUẢ ĐẠT ĐƯỢC ................................................................................................... 16
Chương 5: KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN ...................................................................... 19

2
Báo cáo đồ án học phần Cơ sở dữ liệu
DANH MỤC HÌNH ẢNH.

Hình 2.1 Sơ đồ khối lệnh if .................................................................................. 07

Hình 2.2 Sơ đồ khối lệnh if…else......................................................................... 08

Hình 2.3 Sơ đồ khối vòng lặp for ......................................................................... 09

Hình 2.4 Sơ đồ khối vòng lặp do…while ............................................................. 10

Hình 2.5 Sơ đồ khối vòng lặp while ..................................................................... 11

3
Báo cáo đồ án học phần Cơ sở dữ liệu
Chương 1: GIỚI THIỆU VỀ ĐỀ TÀI
1.1 TÊN ĐỒ ÁN
- Xây dựng game Nhập chữ tương tự game Falling Letters Typing

1.1.1 Giới thiệu đồ án


- Nhập chữ là một trò chơi máy tính thuộc thể loại gõ chữ. Trong trò chơi, người chơi
sẽ gõ các chữ cái rơi xuống theo đúng thứ tự để ghi điểm. Trò chơi có nhiều mức độ
chơi khác nhau, từ dễ đến khó, phù hợp với mọi đối tượng người chơi.

1.1.2 Lối chơi


- Nhập chữ có lối chơi đơn giản nhưng vô cùng hấp dẫn. Khi bắt đầu trò chơi, người
chơi sẽ thấy một hàng chữ cái đang rơi xuống từ trên màn hình. Người chơi cần gõ
đúng thứ tự các chữ cái này để ghi điểm. Nếu gõ sai, người chơi sẽ bị trừ điểm. Nếu để
chữ cái chạm đáy, trò chơi kết thúc.

1.1.3 Điểm mạnh


- Nhập chữ là một trò chơi gõ chữ thú vị và hấp dẫn, phù hợp với mọi đối tượng người
chơi. Trò chơi có những điểm nổi bật sau:
• Lối chơi đơn giản nhưng vô cùng hấp dẫn: Lối chơi của Nhập chữ rất đơn giản,
nhưng lại vô cùng hấp dẫn, khiến người chơi không thể rời mắt khỏi màn hình.
• Thiết kế đồ họa đẹp mắt: Nhập chữ có thiết kế đồ họa đẹp mắt, tạo cảm giác thư
giãn cho người chơi.

1.2 MỤC TIÊU


- Thiết kế hoàn chỉnh 1 game đơn giản chạy trên giao diện Console bao gồm
những thành phần sau:
+ Điểm: số điểm giành được khi người chơi trả lời đúng.
+ Thời gian: thời gian của vòng chơi.
+ Giao diện: phần tương tác với trò chơi, trình chiếu những chữ cái.

4
Báo cáo đồ án học phần Cơ sở dữ liệu
Chương 2: CƠ SỞ LÝ THUYẾT VỀ ĐỀ TÀI
1.3 NGÔN NGỮ LẬP TRÌNH: C#
1.3.1 Lý thuyết sử dụng
1.3.1.1 Cấu trúc rẽ nhánh
- Cấu trúc rẽ nhánh là một cấu trúc điều khiển trong lập trình, được sử dụng để thực
hiện một hành động nào đó dựa trên một điều kiện cụ thể

i. Lệnh if
a. Cú pháp
if (<điều kiện>) <lệnh> ;

if (<điều kiện>)
{
<lệnh 1> ;
<lệnh 2> ;

}

b. Điều kiện và lệnh


- <Điều kiện> có thể là:
+ Biến Bool
+ Biểu thức Bool
+ Biểu thức so sánh
- <Điều kiện> không thể là biến nguyên (như trong C/ C++)
- <Lệnh> có thể là:
+ Một lệnh, kết thúc bởi dấu ;
+ Một khối các lệnh đặt trong cặp {…}

5
Báo cáo đồ án học phần Cơ sở dữ liệu
Điều kiện
false

true
Lệnh

Hình 2.1 Sơ đồ khối lệnh if

i. Lệnh if…else
a. Cú pháp
if (điều kiện)
{
<lệnh 1> ;
}
else
{
<lệnh 2>
}

6
Báo cáo đồ án học phần Cơ sở dữ liệu
Điều kiện false Lệnh 2

true

Lệnh 1

Hình 2.2 Sơ đồ khối lệnh if…else

b. Lưu ý
- Từ khóa if và else phải viết ở dạng chữ thường (thường hay mắc sai sót khi viết
IF, iF, If, Else, ELSE,...)
- Điều kiện phải đặt trong cặp ngoặc tròn (….)
- Dấu chấm phẩy phải có để kết thúc 1 lệnh
- Nếu sau <điều kiện> hoặc sau else cần thực hiện nhiều lệnh thì các lệnh này bắt
buộc đặt trong cặp dấu ngoặc nhọn {…} (nếu một lệnh thì có thể bỏ qua)

1.3.1.2 Cấu trúc vòng lặp


- Vòng lặp là một cấu trúc điều khiển cho phép lặp đi lặp lại một khối lệnh
- Có thể thi hành khối lệnh một số lần cố định
- Có thể thi hành khối lệnh trong khi điều kiện đúng
- Có thể thi hành khối lệnh với mỗi phần tử trong tập hợp
- Vòng lặp mà không bao giờ dừng là vòng lặp bị “quẩn” hoặc vòng lặp vô hạn

i. Vòng lặp for


a. Cú pháp:
for (<bt khởi động>;<bt điều kiện >;<bt lặp> ) <lệnh>;

b. Mô tả:
B1 : Thi hành <bt khởi động>
B2 : Nếu <bt điều kiện> Sai thì sang B6

7
Báo cáo đồ án học phần Cơ sở dữ liệu
B3 : Thi hành <lệnh>
B4 : Thi hành <bt lặp>
B5 : Quay về B2
B6 : Thoát vòng lặp

Hình 2.3 Sơ đồ khối vòng lặp for

c. Lưu ý
- for : chữ thường
- Các bt sau for đặt trong cặp ngoặc (…)
- Các thành phần cách nhau bằng ;
- Có thể bỏ bớt bất kỳ bt thành phần nào
- <bt lặp> có thể là tăng hoặc giảm
- Nếu nhiều lệnh thì các lệnh đặt trong cặp dấu ngoặc nhọn { … }
- Trong C#, nhất quán điều kiện đúng thì lặp, sai thì thoát

ii. Lệnh do…while


a. Cú pháp:
do
{
<lệnh 1>;
<lệnh 2>;

8
Báo cáo đồ án học phần Cơ sở dữ liệu
}
while (<điều kiện>);

b. Ý nghĩa :
- Thực hiện các lệnh giữa do và while, kiểm tra nếu <điều kiện> đúng thì tiếp tục
thực hiện các lệnh, sai thì dừng.

Hình 2.4 Sơ đồ khối vòng lặp do…while

c. Lưu ý
- Từ khóa do và while là chữ thường
- Bắt buộc cặp dấu {…} giữa do và while
- <điều kiện> đặt trong cặp ngoặc (…)
- Các lệnh được thực hiện ít nhất 1 lần
- Trong thân vòng lặp (giữa do và while) có thể là lệnh break và continue
+ break: nhảy/thoát ra khỏi vòng lặp
+ Continue: quay về đầu vòng lặp

ii. Vòng lặp while


a. Cú pháp:
while (<điều kiện>)
{
<lệnh 1>;
<lệnh 2>;

}

9
Báo cáo đồ án học phần Cơ sở dữ liệu
Hình 2.5 Sơ đồ khối vòng lặp while

b. Lưu ý
- Từ khóa while là chữ thường
- <điều kiện> đặt trong cặp ngoặc (…)
- Cách dùng lệnh break và continue trong thân vòng lặp tương tự như vòng lặp
for
- Nếu sau điều kiện chỉ thực hiện 1 lệnh thì có thể bỏ cặp ngoặc nhọn {…}

1.3.1.3 Mảng
i. Mảng là gì?
- Mảng là dãy các phần tử có cùng tên, cùng kiểu.
- Thứ tự của các phần tử là cố định
- Kích thước/số phần tử của mảng là cố định

ii. Khai báo mảng 1 chiều


<kiểu DL> [ ] <tên mảng>;

a. Lưu ý
- Ngoặc vuông [] nghĩa là mảng
- Khai báo mảng số nguyên:
int [] A;

10
Báo cáo đồ án học phần Cơ sở dữ liệu
- :
Khai báo mảng chuỗi

string [] ten;

- Khai báo mảng số thực:


float [] luong;

iii. Tạo mảng


<tên mảng> = new <kiểu DL> [số p.tử]

iv. Tạo và gán giá trị cho mảng


- Tạo và gán giá trị cho mảng có thể làm đồng thời:

A = {2, 4, 6, 8, 10};
a. Lưu ý
- Toán tử new không cần thiết khi sử dụng dấu ngoặc nhọn khởi tạo mảng.

v. Làm thế nào để truy xuất phần tử mảng?


- Các phần tử trong mảng được truy xuất thông qua các chỉ số được đặt trong cặp
dấu ngoặc vuông [] (indexer)
- Mảng A có n phần tử thì khi truy xuất ta có thể viết A[i] với i = 0 --> n-1
- Chiều dài/số phần tử của mảng A là A.Length
- Phần tử đầu tiên có chỉ số là 0
- Phần tử cuối cùng có chỉ số A.Length-1

vi. Đọc dữ liệu từ bàn phím vào mảng


- Đầu tiên nhập từ bàn phím chiều dài của mảng

Console.Write("Nhap so phan tu cua mang: ");


int n = int.Parse(Console.ReadLine());
- Kế tiếp, khai báo mảng có kích thước đã nhập và nhập số liệu cho các phần tử
của mảng

int[] a = new int[n];


for (int i=0; i<n; i++)
{
a[i] = int.Parse(Console.ReadLine());
}

11
Báo cáo đồ án học phần Cơ sở dữ liệu
vii. In mảng ra màn hình
- Xử lý các phần tử của mảng
- In các phần tử ra màn hình
- Tách các phần tử bằng khoảng trắng hoặc in xuống dòng

12
Báo cáo đồ án học phần Cơ sở dữ liệu
Chương 3: PHÂN TÍCH VÀ THIẾT KẾ
4.1 Phân tích
- Trò chơi bắt đầu với việc khởi tạo các biến như tốc độ rơi (tocdo), mốc điểm để
tăng độ khó (moc), và một số biến khác. Màn hình console được thiết lập để
hiển thị các ký tự với mã UTF-8.

- Người chơi bắt đầu trò chơi bằng cách gọi hàm Menu. Trong hàm Menu, hai
luồng (thA và thB) được tạo ra để đồng thời xử lý đầu vào từ người chơi và
logic của trò chơi.

- Hàm NhanPhim chờ đợi người chơi nhấn phím. Nếu ký tự nhấn vào khớp với
ký tự rơi xuống gần nhất (Arr[currentIndexOfArr]), điểm của người chơi tăng
lên và ký tự đó biến mất khỏi màn hình. Sau đó, vị trí của ký tự được trả về
trạng thái ban đầu, và nếu đã xóa hết ký tự của cấp độ hiện tại, game sẽ chuẩn
bị cho cấp độ mới.

- Hàm LapLai chạy trong một vòng lặp vô hạn, gọi hàm HamRoiChu để giả lập
sự rơi của các ký tự từ trên xuống dưới màn hình. Trò chơi sẽ kết thúc khi cờ
ktra trở thành true, và điểm của người chơi sẽ được hiển thị trên màn hình
console.

- Hàm HamRoiChu đầu tiên tạo ngẫu nhiên các ký tự cho cấp độ chơi hiện tại, và
sau đó trong một vòng lặp, cập nhật vị trí của các ký tự để chúng rơi xuống
dưới màn hình. Nếu người chơi trả lời đúng, hàm sẽ bắt đầu lại từ đầu để chuẩn
bị cho cấp độ tiếp theo. Nếu một ký tự rơi xuống đáy màn hình, trò chơi sẽ kết
thúc.

- Cuối cùng, hàm Score cập nhật điểm của người chơi và kiểm tra nếu người chơi
đã đạt đến mốc điểm để tăng độ khó và chuyển sang cấp độ mới.

4.2 Phân tích


Biến toàn cục:
- tocdo: Tốc độ rơi của các ký tự.
- moc: Mốc điểm để tăng tốc độ và độ khó.
- i: Một hệ số nhân được sử dụng để điều chỉnh tốc độ.
- diem: Điểm của người chơi.
- ktra: Cờ kiểm tra dùng để điều khiển vòng lặp chính của trò chơi.
- right: Cờ kiểm tra xem người chơi đã trả lời đúng trong lượt chơi hiện tại chưa.
- Arr: Mảng chứa các ký tự đang rơi trong một cấp độ chơi.
- pos: Mảng lưu vị trí của từng ký tự (2 vị trí lưu 1 ký tự).
- count: Biến đại diện cho cấp độ hiện tại.
- currentIndexOfArr: Chỉ số hiện tại của mảng Arr.

Hàm Main:
- Thiết lập mã hóa xuất của console là UTF-8.
- Gọi hàm Menu để bắt đầu trò chơi.
13
Báo cáo đồ án học phần Cơ sở dữ liệu
Hàm Menu:
- Tạo và bắt đầu hai luồng (thA và thB) để xử lý đầu vào của người chơi và logic trò
chơi đồng thời.

Hàm NhanPhim:
- Lặp while cho đến khi cờ ktra được đặt thành true.
- Đọc một phím từ người chơi.
- Nếu ký tự nhập vào khớp với ký tự đang rơi ở vị trí currentIndexOfArr, cập nhật
điểm và xóa ký tự đó.
- Di chuyển vị trí của ký tự đến hàng trên đối với cấp độ hiện tại.
- Nếu đã xóa hết ký tự ở cấp độ hiện tại, đặt right thành true và cờ ktra thành false.

Hàm LapLai:
- Vòng lặp vô hạn để liên tục gọi hàm HamRoiChu và ngủ theo tốc độ.
- Khi cờ ktra trở thành true, hiển thị điểm của người chơi và kết thúc vòng lặp.

Hàm HamRoiChu:
- Thiết lập hiển thị con trỏ của console thành ẩn.
- Tạo ngẫu nhiên các ký tự cho cấp độ chơi và vị trí của chúng.
- Trong vòng lặp, vẽ các ký tự và di chuyển chúng xuống màn hình.
- Nếu right là true, bắt đầu lại từ đầu bằng cách đặt right thành false.
- Nếu một ký tự rơi xuống đáy màn hình, đặt ktra thành true để kết thúc trò chơi.

Hàm Score:
- Cập nhật điểm của người chơi.
- Nếu đạt đến mốc điểm mới, giảm tốc độ, tăng cấp độ, và tăng mốc điểm.

Hàm TongHoDem:
Hàm này được thiết kế để hiển thị thời gian đã chơi ở góc dưới bên trái của cửa sổ
console.
Một vòng lặp while kiểm tra biến ktra để xác định xem trò chơi có kết thúc chưa.
Trong vòng lặp, Console.SetCursorPosition(0, Console.WindowHeight - 1) được sử
dụng để đặt con trỏ tới góc trái dưới cùng của cửa sổ.
Sau đó, thời gian đã chơi được xuất ra màn hình với định dạng "Thời gian:
{tongThoiGianDaChoi} s".
Hàm sau đó tạm nghỉ 1 giây bằng Thread.Sleep(1000) và tăng giá trị thoiGianDaTrong
lên 1.

Hàm DongHoDem:
Hàm này có vẻ giống như hàm TongHoDem, nhưng nó được thiết kế để hiển thị thời
gian đã trôi qua từ khi bắt đầu trò chơi ở góc dưới bên phải của cửa sổ console.
Cũng sử dụng một vòng lặp while để kiểm tra biến ktra.
Console.SetCursorPosition(Console.WindowWidth - 15, Console.WindowHeight - 1)
được sử dụng để đặt con trỏ tới góc phải dưới cùng của cửa sổ.
Thời gian đã trôi qua được xuất ra màn hình với định dạng "Thời gian:
{thoiGianDaTrong} s".
14
Báo cáo đồ án học phần Cơ sở dữ liệu
Hàm tạm nghỉ 1 giây và tăng giá trị thoiGianDaTrong lên 1.

15
Báo cáo đồ án học phần Cơ sở dữ liệu
Chương 4: KẾT QUẢ ĐẠT ĐƯỢC

using System;
using System.Security.AccessControl;
using System.Text;
using System.Threading;

namespace CoSoLapTrinh_lam_game
{
class Program
{
public static int tocdo = 500, moc = 10, i = 1;
public static int diem = 0;
public static int a = 0;
public static int b = 0;
public static char s = '.';
public static bool ktra = false;
public static bool right = false;
public static char[] Arr = new char[10]; //mảng để lưu những chữ xuất
hiện trong level đang chơi
public static int[] pos = new int[20]; //mảng để lưu vị trị từng chữ, 2
vị trí trong mảng lưu 1 chữ
public static int count = 1; //biến thể hiện level
public static int currentIndexOfArr = 0; // chỉ số hiện tại của mảng Arr
static void Main(string[] args)
{
Console.OutputEncoding = Encoding.UTF8;
Menu();
}

static void Menu()


{
Thread thA, thB;
thA = new Thread(() => NhanPhim()); // cho 2 hàm chạy cùng lúc
thB = new Thread(() => LapLai());

thB.Start();
thA.Start();
}

static void NhanPhim()


{
while (!ktra) // hàm để nhấn phím và xóa phím
{
ConsoleKeyInfo keyInfo = Console.ReadKey(true);

if (keyInfo.KeyChar == Arr[currentIndexOfArr]) // so sánh ký tự


nhập vào và kí tự rơi gần đáy nhất
{

Score();
Console.SetCursorPosition(0, 0);
Console.Write($"Điểm: {diem}");
//////////////////
///biến right để kiểm tra xem, liệu lượt này đã trả lời đúng
chưa
pos[2 * currentIndexOfArr + 1] = 0; //trả vị trí của chữ đã
xóa của hàng
pos[2 * currentIndexOfArr] = 0; // trả vị trí của chữ đã xóa
của cột
Arr[currentIndexOfArr] = ' '; // xóa chữ
//currentIndexOfArr--;

16
Báo cáo đồ án học phần Cơ sở dữ liệu
if (currentIndexOfArr == 0) //khi đã xóa hết kí tự của khung
hiện tại thì sẽ hiện ra khung mới
{
right = true;
/////////////////
ktra = false;
//HamRoiChu();
}
else
{
currentIndexOfArr--; //xóa 1 chữ xong vị trí dời lên 1
hàng
}
}
}
}

static void LapLai()


{
while (true)
{
while (!ktra)
{
HamRoiChu();
Thread.Sleep(tocdo);

}
break;
}

Console.Clear();
Console.SetCursorPosition(0, 0);
Console.Write($"Điểm của bạn: {diem}");// xuất điểm khi thua
}

public static void HamRoiChu()


{
Console.CursorVisible = false;
Random r = new Random();
currentIndexOfArr = count - 1; //chuyển vị trí hiện tại thành chữ cái
thấp nhất
for (int i = 0; i < count; i++) //xuất ra chữ random có vị trí trong
mảng
{
Arr[i] = (char)r.Next(97, 122);
pos[2 * i] = r.Next(0, Console.WindowWidth);// cột bất kì
pos[2 * i + 1] = i; //hàng liên tiếp
}

while (true)
{
Console.Clear(); //clear màn hình cũ
// Console.SetCursorPosition(a, b);
// Console.Write(s);
for (int i = 0; i < count; i++) //Update vị trí các chữ đi xuống
{
Console.SetCursorPosition(pos[2 * i], pos[2 * i + 1]);
Console.Write(Arr[i]);
pos[2 * i + 1]++;
}

Console.SetCursorPosition(Console.WindowWidth - 10, 0);


Console.Write($"Điểm: {diem}");
17
Báo cáo đồ án học phần Cơ sở dữ liệu
Thread.Sleep(tocdo);
///nếu right == true, có nghĩa là đã trả lời đúng rồi thì hàm rơi
chữ sẽ bắt đầu lại từ đầu
if (right == true)
{
right = false;
break;
}
//////////////////
if (pos[2 * currentIndexOfArr + 1] >= Console.WindowHeight)// vị
trí chạm đáy thì dừng chương trình
{
ktra = true;
break;
}
}

static void Score()


{
diem++;

if (diem == moc * i)
{
tocdo -= 100;
i++;
count++;// nâng level sau mốc điểm

}
}
}
}

18
Báo cáo đồ án học phần Cơ sở dữ liệu
Chương 5: KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN
- Game có thể sử dụng chơi ngay lập tức
- Giao diện thân thiện, dễ dùng

19
Báo cáo đồ án học phần Cơ sở dữ liệu

You might also like