1. Trang chủ
  2. » Luận Văn - Báo Cáo

XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)

26 709 1

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 26
Dung lượng 1,53 MB

Nội dung

Hình 2.2 Biểu đồ trình tự bắt đầu chơi gameHình 2.3 Biểu đồ trình tự tự động chơi game Hình 2.4 Biểu đồ trình tự thêm ảnh Hình 2.5 Biểu đồ trình tự cài đặt game Hình 2.6 Bài toán mô tả h

Trang 1

Hình 2.2 Biểu đồ trình tự bắt đầu chơi game

Hình 2.3 Biểu đồ trình tự tự động chơi game

Hình 2.4 Biểu đồ trình tự thêm ảnh

Hình 2.5 Biểu đồ trình tự cài đặt game

Hình 2.6 Bài toán mô tả hàm ước lượng Heuristic

Hình 3.1 Giao diện chính của chương trình

Hình 3.2 Các chức năng chính của chương trình

Hình 3.3 Giao diện bắt đầu chơi game

Hình3.4 : Giao diện thiết lập độ khó cho trò chơi

Hình 3.5 : Giao diện game khi Win

Hình 3.6 : Giao diện hỏi người chơi có muốn Autorun không

Hình 3.7 : Giao diện khi game đang tự động chơi

Hình 3.8 : Giao diện Add Image

Hình 3.9 : Giao diện cài đặt trò chơi

Hình 3.10 : Giao diện hướng dẫn cho người chơi

Trang 2

TÓM TẮT ĐỀ TÀI

Java là một ngôn ngữ lập trình dạng lập trình hướng đối tượng(OOP) Khác với phần lớn ngôn ngữ lập trình thông thường, thay vì biêndịch mã nguồn thành mã máy hoặc thông dịch mã nguồn khi chạy, Javađược thiết kế để biên dịch mã nguồn thành bytecode, bytecode sau đó sẽđược môi trường thực thi (runtime environment) chạy Bằng cách này,Java thường chạy chậm hơn những ngôn ngữ lập trình thông dịch khácnhư C++, Python, Perl, PHP, C#

Ngôn ngữ lập trình Java được giới thiệu vào năm 1990 Sau đókhông lâu, ngôn ngữ này được sử dụng rộng rãi và phổ biến đối với cáclập trình viên chuyên nghiệp cũng như các nhà phát triển phần mềm

Để hiểu rõ hơn về Java nhóm chúng em đã tìm hiểu và xây dựng

một chương trình đơn giản là “Game Xếp Hình” Hay còn được gọi là

Puzzle, có nghĩa là câu đố, đây là trò chơi thuộc thể loại game trí tuệ Tròchơi này cũng giống như các trò chơi xếp hình, đầu tiên với kích thướctrò chơi là 9 ô, trạng thái ban đầu được khởi tạo ngẫu nhiên Nhiệm vụcủa người chơi là xếp 8 chữ số sao cho đạt được trạng thái win cho nhưsau:

Trang 3

Người chơi cố gắng xếp 8 ô về trạng thái win càng nhanh càng tốt vàcàng dùng ít lần dịch chuyển càng tốt.

Nội dung báo cáo “Game Xếp Hình” bao gồm:

1.1 Giới thiệu về ngôn ngữ Java:

Java là một ngôn ngữ lập trình được Sun Microsystems giới thiệu vàotháng 6 năm 1995 Từ đó, nó đã trở thành một công cụ lập trình của cáclập trình viên chuyên nghiệp Java được xây dựng trên nền tảng của C vàC++, do vậy nó sử dụng các cú pháp của C và các đặc trưng hướng đốitượng của C++

Vào năm 1991, một nhóm các kỹ sư của Sun Microsystems có ý địnhthiết kế một ngôn ngữ lập trình để điều khiển các thiết bị điện tử như tivi,máy giặt, lò nướng,… Mặc dù C và C++ có khả năng làm việc này nhưngtrình biên dịch lại phụ thuộc vào từng loại CPU

Trình biên dịch thường phải tốn nhiều thời gian để xây dựng nên rấtđắt, vì vậy để mỗi loại CPU có một trình biên dịch riêng là rất tốn kém

Do đó nhu cầu thực tế đòi hỏi một ngôn ngữ chạy nhanh, gọn, hiệu quả

và độc lập thiết bị tức là có thể chạy trên nhiều loại CPU khác nhau, dướicác môi trường khác nhau “Oak” đã ra đời và vào năm 1995 được đổi tênthành Java Mặc dù mục tiêu ban đầu không phải cho Internet nhưng dođặc trưng không phụ thuộc thiết bị nên Java đã trở thành ngôn ngữ lậptrình cho Internet

1.2 Một số tính chất của ngôn ngữ Java:

Java là ngôn ngữ lập trình được phát triển từ ngôn ngữ lập trình C/C++ Nó kế thừa, phát huy các thế mạnh của ngôn ngữ C/C++ và lược bỏ đicác cú pháp phức tạp của C/C++ Ngôn ngữ lập trình Java có một số đặc

Trang 4

trưng tiêu biểu: đơn giản, hướng đối tượng, độc lập phần cứng và hệ điềuhành, mạnh mẽ, bảo mật, phân tán, đa luồng và linh động.

1.2.1 Đơn giản:

Những người thiết kế mong muốn phát triển một ngôn ngữ dễ học

và quen thuộc với đa số người lập trình Do vậy Java loại bỏ các đặctrưng phức tạp của C và C++ như:

- Loại bỏ thao tác con trỏ, thao tác định nghĩa chồng toán tử

- Không cho phép đa kế thừa mà sử dụng các giao diện

- Không sử dụng lệnh “goto” cũng như file header (.h)

- Loại bỏ cấu trúc “struct” và “union”

1.2.2 Hướng đối tượng:

Java là ngôn ngữ lập trình thuần hướng đối tượng, mọi chươngtrình viết trên Java đều phải được xây dựng trên các đối tượng Nếu trongC/C++ ta có thể tạo ra các hàm (chương trình con không gắn với đốitượng nào) thì trong Java ta chỉ có thể tạo ra các phương thức (chươngtrình con gắn liền với một lớp cụ thể) Trong Java không cho phép các đốitượng có tính năng đa kế thừa mà được thay thế bằng các giao diện(interface)

1.2.3 Độc lập phần cứng và hệ điều hành:

Đối với các ngôn ngữ lập trình truyền thống như C/C++, phươngpháp biên dịch được thực hiện như sau :

Hình 1.1: Các biên dịch chương trình hệ thống

Trang 5

Với mỗi nền phần cứng khác nhau, có một trình biên dịch khác nhau để biên dịch mã nguồn chương trình cho phù hợp với nền phần cứng

ấy Do vậy, khi chạy trên một nền phần cứng khác bắt buộc phải biên dịchlại mã nguồn

Đối với các chương trình viết bằng Java, trình biên dịch Javac sẽbiên dịch mã nguồn thành dạng bytecode Sau đó, khi chạy chương trìnhtrên các nền phần cứng khác nhau, máy ảo Java dùng trình thông dịchJava để chuyển mã bytecode thành dạng chạy được trên các nền phầncứng tương ứng Do vậy, khi thay đổi nền phần cứng, không phải biêndịch lại mã nguồn Java

Hình 1.2: Biên dịch hệ thống java

1.2.4 Mạnh mẽ:

Java là ngôn ngữ yêu cầu chặt chẽ về kiểu dữ liệu

- Kiểu dữ liệu phải khai báo tường minh

- Java không sử dụng con trỏ và các phép toán con trỏ

- Java kiểm tra tất cả các truy nhập đến mảng, chuỗi khi thực thi để đảmbảo rằng các truy nhập đó không ra ngoài giới hạn kích thước

Trang 6

- Trong các môi trường lập trình truyền thống, lập trình viên phải tựmình cấp phát bộ nhớ, trước khi chương trình kết thúc thì phải tự giảiphóng bộ nhớ đã cấp Vấn đề có thể nảy sinh khi lập trình viên quêngiải phóng bộ nhớ đã xin cấp trước đó Trong chương trình Java, lậptrình viên không phải bận tâm đến việc cấp phát bộ nhớ Quá trình cấpphát, giải phóng được thực hiện tự động, nhờ dịch vụ thu nhặt nhữngđối tượng không còn sử dụng nữa (garbage collection).

- Cơ chế bẫy lỗi của Java giúp đơn giản hóa quá trình xử lý lỗi và hồiphục sau lỗi

- Ở mức thứ hai, trình biên dịch kiểm soát để đảm bảo mã là an toàn, vàtuân theo các nguyên tắc của Java

- Mức thứ ba được đảm bảo bởi trình thông dịch chúng kiểm soát xembytecode có đảm bảo các quy tắc an toàn trước khi thực thi không

- Mức thứ tư kiểm soát việc nạp các lớp vào bộ nhớ để giám sát việc viphạm giới hạn truy xuất trước khi nạp vào hệ thống

1.2.6 Phân tán:

Java được thiết kế để hỗ trợ các ứng dụng chạy trên mạng bằng cáclớp mạng (java.net) Hơn nữa, Java hỗ trợ nhiều nền chạy khác nhau nênchúng được sử dụng rộng rãi như là công cụ phát triển trên Internet - nơi

sử dụng nhiều nền khác nhau

1.2.7 Đa luồng

Chương trình Java cung cấp giải pháp đa luồng (Multithreading) đểthực thi các công việc đồng thời Chúng cũng cung cấp giải pháp đồng bộ

Trang 7

giữa các luồng Đặc tính hỗ trợ đa luồng này cho phép xây dựng các ứngdụng trên mạng chạy hiệu quả.

1.2.8 Linh động

Java được thiết kế như một ngôn ngữ động để đáp ứng cho nhữngmôi trường mở Các chương trình Java chứa rất nhiều thông tin thực thinhằm kiểm soát và truy nhập đối tượng lúc chạỵ Điều này cho phép khảnăng liên kết mã động

2. Quá trình xây dựng chương trình:

2.1 Xác định yêu cầu:

2.1.1 Yêu cầu chức năng:

Game xếp hình (hay còn gọi là Puzzle) là một trò chơi điều khiển các khối trượt trong một khung được đánh số thứ tự ngẫu nhiên với một ô bị thiếu Nhiệm vụ của chúng ta là trượt các khối Các khối trượt là những con số hoặc hình ảnh sao cho kết quả được dãy số sắp xếp tăng hoặc giảmdần, hoặc các hình được ghép lại từ các miếng nhỏ thành hình ban đầu

2.1.2 Yêu cầu phi chức năng:

Giao diện game đơn giản, thân thiện và dễ sử dụng với người chơi

2.2 Thiết kế chương trình:

2.2.1 Biểu đồ Usecase:

Hình 2.1 Biểu đồ Usecase

2.2.2 Biểu đồ trình tự:

Trang 8

2.2.2.1 Biểu đồ trình tự New game:

Hình 2.2 Biểu đồ trình tự bắt đầu chơi game

2.2.2.2 Biểu đồ trình tự Solve:

Trang 9

Hình 2.3 Biểu đồ trình tự tự động chơi game

Trang 10

2.2.2.3 Biểu đồ trình tự Add image:

Hình 2.4 Biểu đồ trình tự thêm ảnh

2.2.2.4 Biểu đồ trình tự Tool:

Hình 2.5 Biểu đồ trình tự cài đặt game

Trang 11

2.2.3 Thiết kế thuật toán :

Để giải quyết vấn đề liên quan đến tìm đường đi và đồ thị thì A* là một giải thuật tìm kiếm thường được sử dụng Ta chọn nó không chỉ vì tính hiệu quả mà còn vì rất dễ dàng để hiểu và cài đặt

Ta rất dễ thấy là mỗi trạng thái của bảng số là một hoán vị của ma trận (m

x n) phần tử ( với m là cạnh), như vậy không gian trạng thái của nó là (m

x n)! Với 8-puzzle là 9! = 362880 (m = 3) và 15-puzzle là 16! =

20922789888000 ( m = 4) Ta có thể khi tăng m lên 1 đơn vị thì không gian trạng thái tăng lên rất nhanh, nên với m>3 thì rất ít khi được áp dụng

Để áp dụng thuật toán A* vào giải bài toán này, ta cần một hàm heuristic h để ước lượng giá trị của mỗi trạng thái của bảng số Có một sốcách ta đã biết tới như tính dựa vào khoảng cách sai lệch của các ô số với

vị trí đúng, hoặc đếm xem có bao nhiêu ô sai vị trí Ở đây ta chọn cách tính tổng số ô sai lệch của các ô số so với vị trí đúng của nó

Thuật toán tìm kiếm A* được mô tả qua thủ tục sau:

Procedure A *

Begin Đặt trạng thái đầu vào ds L;

While true do Begin

If ds L rỗng then Begin

Thông báo thất bại;

Kết thúc;

End;

u <- trạng thái đầu;

If u ≡ đích then

Trang 12

Begin Thông báo thành công;

Kết thúc;

End;

For mỗi v kề u do Begin

Giao diện chính gồm các chức năng:

- Chức năng New game: hiển thị ra màn hình có các chức năng như

sau: Chọn kích thước ảnh có thể là 3x3,4x4,5x5 , chọn kiểu ảnh là ảnh và số hoặc ảnh số, chọn ước lượng heuristic1,2,3 Sau đó start game

Dữ liệu đầu vào là ảnh mẫu bất kì, được chia làm 9 ô bị xáo trộn và

đã được thiết lập kiểu ảnh, size ảnh Dữ liệu đầu ra là thông báo thắng, ảnh sau khi được sắp xếp hoàn chỉnh giống với hình ban đầu đã cho

Hàm ước lượng Heuristic đơn giản nhất sẽ đếm số ô sai khác so

với trạng thái đích trong từng trạng thái Trạng thái có số ô sai khác ít

nhất sẽ gần đích hơn và là trạng thái tốt nhất để kiếm tra kế tiếp

Trang 13

Hình 2.6 Bài toán mô tả hàm ước lượng Heuristic

Hàm đánh giá f sẽ bao gồm tổng của hai phần:

3. f(n) = g(n) + h(n)

Trong đó g(n) đo chiều dài thực từ trạng thái n bất kỳ về trạng thái xuất phát và h(n) là ước lượng heuristic cho khoảng cách từ trạng thái n đến trạng thái đích

- Chức năng Solve ( tự giải quyết game ):

Sau khi ấn nút Solve ở màn hình new game Giao diện hiện ra sẽ hỏi người chơi bạn có muốn tự động chơi game hay không Khi người chơi ấn Yes, ở bảng thông báo đã hiện ra kết quả được tính sẵn Sau đó game sẽ tự động chơi với ước lượng và số bước đi ngắn nhất trong thời gian sớm nhất đã được thiết lập sẵn từ trước

Dữ liệu đầu vào là ảnh mẫu bất kì, được chia làm 9 ô bị xáo trộn và

đã được thiết lập kiểu ảnh, size ảnh Dữ liệu đầu ra là thông báo thắng, ảnh sau khi được sắp xếp hoàn chỉnh giống với hình ban đầu đã cho

Trang 14

2.2.4.2 Giao diện Add Image:

Chức năng thêm ảnh Có thể tải ảnh từ máy tính của bạn vào giao diện game để thực hiện trò chơi

Đầu vào là một bức ảnh bất kỳ trên hệ thống Đầu ra là bức ảnh tải lên đã được hệ thống xử lý

2.2.4.3 Giao diện Option:

Chức năng của giao diện giúp người chơi có thể cài đặt thêm cho game, ví dụ như tắt bật nhạc trong game, chọn màu cho bức ảnh, chọn độ khó của trò chơi

2.2.4.4 Giao diện Help:

Hướng dẫn cách chơi game

3 KẾT QUẢ:

3.1 Chương trình hoàn chỉnh:

Giao diện chương trình lúc ban đầu hình vẽ:

Trang 15

Hình 3.1 Giao diện chính của chương trình

Để bắt đầu chơi, người chơi phải click menu File, khi đó 1 menu sổxuống như hình vẽ:

Trang 16

Hình 3.2 Các chức năng chính của chương trình

Tiếp theo chọn New Game để bắt đầu chơi.

Khi đó trên giao diện chương trình ta sẽ thấy các mảnh ghép sẽ được sắp xếp xáo trộn với nhau như hình vẽ:

Trang 17

Hình 3.3 Giao diện bắt đầu chơi game

Và nhiệm vụ của người chơi lúc này là phải sắp xếp lại tấc cả cácmảnh ghép để được bức ảnh như cũ

Trước khi chơi game, người chơi có thể thiết lập độ khó cho tròchơi nếu muốn như sau:

Trang 18

Hình 3.4 : Giao diện thiết lập độ khó cho trò chơi

Sau đó bắt đầu chơi:

Trang 19

Hình 3.5 : Giao diện game khi Win.

Sau khi hoàn thành trò chơi trên giao diện sẽ hiển thị thông báo bạn đã

thắng và hiển thị thời gian và số bước bạn đã đạt được, sau đó người chơi có hai nút chọn chơi lại hoặc thoát.

Giao diện Solve : Tự động chơi game.

Với những thiết lập đã được chọn ban đầu Người chơi ấn Solve giao diệnhiện ra sẽ hỏi người chơi có muốn tự động chơi game không, người chơichọn Yes hoặc No

Trang 20

Hình 3.6 : Giao diện hỏi người chơi có muốn Autorun không.

Khi người chơi chọn Yes, trên màn hình chính sẽ hiện thông báokết quả thắng đã được tính sẵn, game đang tự động chơi

Trang 21

Hình 3.7 : Giao diện khi game đang tự động chơi

Chức năng Edit: Add Image

Người chơi có thể chọn ảnh bất kỳ từ máy tính để tải vào game nhưhình dưới đây:

Trang 22

Hình 3.8 : Giao diện Add Image.

Chức năng Tool: Option

Trang 23

Hình 3.9 : Giao diện cài đặt trò chơi.

Chức năng Help

Trang 24

Hình 3.10 : Giao diện hướng dẫn cho người chơi.

3.2 Các khó khăn gặp phải và cách giải quyết:

Do thời gian còn hạn chế, bài làm lại gồm các thành viên trong nhómcùng làm nên rất khó để đồng nhất các ý kiến của các thành viên Cácthành viên trong nhóm lại xa nhau nên việc liên lạc trao đổi bài còn gặpnhiều khó khăn Việc tiếp cận với một ngôn ngữ mới cũng gặp rất nhiềukhó khăn về cú pháp và câu lệnh

Vượt qua những khó khăn trên, nhóm chúng em đã tích cực trao đổibài với nhau qua mail, điện thoại để tìm cách giải quyết bài toán Cácthành viên cũng ý thức được và đã tìm hiểu những vấn đề còn vướng mắcqua sách vở và các tài liệu lưu trữ trên internet

KẾT LUẬN Mục tiêu đã hoàn thành

- Đã xây dựng được một chương trình game gồm có các chức năng cơbản : Bắt đầu chơi, Tạo độ khó của trò chơi, Tự động giải quyết đượctrò chơi

- Đã tìm hiểu được rõ thêm về Java

Các thiếu xót cần bổ sung

Trang 25

- Chương trình game còn đang sơ sài, game mới chỉ chơi được mộtngười, còn chưa lưu được game và chưa có hệ thống tính điểm, lưuthành tích cao nhất.

- Giao diện game còn đơn giản và chưa thật sự bắt mắt

Khả năng ứng dụng và hướng phát triển

- Trong thời gian tới có thể nghiên cứu và phát triển game để có thể đưavào chơi trên máy điện thoại di động

Trang 26

TÀI LIỆU THAM KHẢO

[1] Ngô Công Thắng; Bài giảng Lập trình Java

[2] Phạm Quang Dũng Bài giảng lập trình Java Trường ĐH Nông Nghiệp

Hà Nội 2009

[3] Bài giảng Java căn bản

[4] Java cơ sở Trường ĐH Công Nghiệp Nà Nội

Ngày đăng: 04/08/2020, 00:50

HÌNH ẢNH LIÊN QUAN

Hình 1.1: Các biên dịch chương trình hệ thống - XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)
Hình 1.1 Các biên dịch chương trình hệ thống (Trang 4)
Hình 1.2: Biên dịch hệ thống java - XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)
Hình 1.2 Biên dịch hệ thống java (Trang 5)
Game xếp hình (hay còn gọi là Puzzle) là một trò chơi điều khiển các khối trượt trong một khung được đánh số thứ tự ngẫu nhiên với một ô bị  thiếu - XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)
ame xếp hình (hay còn gọi là Puzzle) là một trò chơi điều khiển các khối trượt trong một khung được đánh số thứ tự ngẫu nhiên với một ô bị thiếu (Trang 7)
Hình 2.2 Biểu đồ trình tự bắt đầu chơi game - XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)
Hình 2.2 Biểu đồ trình tự bắt đầu chơi game (Trang 8)
Hình 2.3 Biểu đồ trình tự tự động chơi game - XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)
Hình 2.3 Biểu đồ trình tự tự động chơi game (Trang 9)
Hình 2.4 Biểu đồ trình tự thêm ảnh - XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)
Hình 2.4 Biểu đồ trình tự thêm ảnh (Trang 10)
Hình 2.5 Biểu đồ trình tự cài đặt game - XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)
Hình 2.5 Biểu đồ trình tự cài đặt game (Trang 10)
Hình 2.6 Bài toán mô tả hàm ước lượng Heuristic - XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)
Hình 2.6 Bài toán mô tả hàm ước lượng Heuristic (Trang 13)
Hình 3.1 Giao diện chính của chương trình - XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)
Hình 3.1 Giao diện chính của chương trình (Trang 15)
Hình 3.2 Các chức năng chính của chương trình - XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)
Hình 3.2 Các chức năng chính của chương trình (Trang 16)
Hình 3.3 Giao diện bắt đầu chơi game - XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)
Hình 3.3 Giao diện bắt đầu chơi game (Trang 17)
Hình3.4 : Giao diện thiết lập độ khó cho trò chơi - XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)
Hình 3.4 Giao diện thiết lập độ khó cho trò chơi (Trang 18)
Hình 3.5 : Giao diện game khi Win. - XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)
Hình 3.5 Giao diện game khi Win (Trang 19)
Hình 3.6 : Giao diện hỏi người chơi có muốn Autorun không. - XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)
Hình 3.6 Giao diện hỏi người chơi có muốn Autorun không (Trang 20)
Hình 3.7 : Giao diện khi game đang tự động chơi - XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)
Hình 3.7 Giao diện khi game đang tự động chơi (Trang 21)
Hình 3.8 : Giao diện Add Image. - XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)
Hình 3.8 Giao diện Add Image (Trang 22)
Hình 3.9 : Giao diện cài đặt trò chơi. - XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)
Hình 3.9 Giao diện cài đặt trò chơi (Trang 23)
Hình 3.10 : Giao diện hướng dẫn cho người chơi. - XÂY DỰNG CHƯƠNG TRÌNH GAME xếp HÌNH (PUZZLE)
Hình 3.10 Giao diện hướng dẫn cho người chơi (Trang 24)

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w