Báo cáo đồ án cấu trúc dữ liệu và thuật toán. Đề tài Gelfand’s play. Bàn cờ kích thước n x n đặt chéo. Một con tốt nằm ở đỉnh dưới. Hai người lần lượt đẩy con tốt đi một nước. Không được đi lùi lại. Người đầu tiên đặt được con tốt sang đầu ngược lại là người thắng cuộc. Tìm thuật toán tối ưu cho người đi nứơc đầu tiên.
Trang 1ĐẠI HỌC ĐÀ NẴNG TRƯỜNG ĐẠI HỌC BÁCH KHOA KHOA CÔNG NGHỆ THÔNG TIN
Tel (84-511) 736 949, Fax (84-511) 842 771 Website: itf.ud.edu.vn, E-mail: cntt@edu.ud.vn
-* -
BÁO CÁO
ĐỒ ÁN CẤU TRÚC DỮ LIỆU VÀ THUẬT TOÁN
GVHD : LÊ QUÝ LỘC NHÓM : 10NH11
LỚP : 10T1 SVTH : TRẦN QUỐC HOÀN NGUYỄN TÀI ĐỨC LÀNH
Đà Nẵng, tháng 1 năm 2013
Trang 2MỤC LỤC
LỜI MỞ ĐẦU 3
ĐỀ BÀI: 4
PHÂN TÍCH VÀ THIẾT KẾ THUẬT TOÁN 5
I Phân tích bài toán 5
II Thuật toán 5
III Nhận xét 9
IV Thiết kế chương trình 9
V Các hàm sử dụng trong chương trình 10
VI Chương trình đầy đủ 11
VII Hình ảnh chạy chương trình 19
Trang 3LỜI MỞ ĐẦU
Cấu trúc dữ liệu và thuật toán là học phần rất quan trọng đối với người lập trình Môn học này được xem như nền tảng của lập trình máy tính Nó là cơ sở vững chắc để giải quyết một số bài toán, đồng thời cung cấp cho chúng ta hiểu biết về các giải thuật tác động lên dữ liệu, cũng như cách tổ chức dữ liệu để giải quyết các bài toán sao cho hiệu quả và tối ưu
Sau hai học phần lí thuyết và thực hành, chúng em nghiên cứu và thực hiện đồ án này như là một cách để cũng cố và mở rộng kiến thức Thông qua quá trình thực hiện đồ
án, chúng em đã nắm bắt được những kỹ thuật quan trọng của việc xây dựng cấu trúc
dữ liệu và cách xây dựng một thuật toán sau cho tối ưu nhất
Bài toán “Gelfand’s play” mà em nghiên cứu và trình bày trong báo cáo sau đây là một trong những ví dụ
Chúng em chân thành cảm ơn thầy Lê Quý Lộc đã giúp đỡ em thực hiện đồ án này
Và chúng em cũng rất mong sự góp ý giúp đỡ từ phía thầy để bài làm của chúng được hoàn thiện hơn
Trang 4ĐỀ BÀI:
Gelfand’s play
Bàn cờ kích thước n x n đặt chéo Một con tốt nằm ở đỉnh dưới Hai người lần lượt đẩy con tốt đi một nước Không được đi lùi lại Người đầu tiên đặt được con tốt sang đầu ngược lại là người thắng cuộc Tìm thuật toán tối ưu cho người đi nứơc đầu tiên (Gelfand’s play)
Trang 5PHÂN TÍCH VÀ THIẾT KẾ THUẬT TOÁN
I Phân tích bài toán
Các trò chơi đối kháng giữa hai người đã được hình thành từ lâu Và những người chơi luôn cố gắng tìm mọi cách để mình giành được phần thắng Khi chơi, người chơi thường cố suy nghĩ để có một nước đi tối ưu nhất Vấn đề là các trò chơi thường quá phức tạp lên không có một ai có thể đảm bảo rằng mọi nước đi của mình là tối ưu Do vậy cho đến nay, chỉ một số lượng nhỏ bài toán đó đã được giải quyết
Bài toán “Gelfand’s play” này cũng là một dạng nhỏ của trò chơi đối kháng Nó tương đối đơn giản vì chỉ có một quân cờ và một cách đi (đi qua 3 ô kề bên cạnh) Vì vậy ta có thể xác định được một nước đi trong trò chơi sẽ dẫn đến kết quả thắng, thua cho người đi nước đó Sau đây là thuật toán để giải quyết vấn đề này
II Xây dựng thuật toán
Trong các hình vẽ dưới đây, các ô trong bàn cờ được đánh số 0, 1, 2 như sau:
-Số 0: Vị trí xuất phát ban đầu
-Số 1: Vị trí mà người chơi 1 (người đi nước đầu tiên) di chuyển quân tốt đến
-Số 2: Vị trí mà người chơi 2 (người đi sau) di chuyển quân tốt đến
Để tìm thuật toán tối ưu cho người chơi 1 (khả năng thắng của người chơi 1 là cao nhất) Ta xét một số trường hợp cụ thể như sau:
1 Bàn cờ 2×2
Dễ thấy rằng người chơi đầu đi chéo và thắng
Vậy với bàn cờ kích thước 2×2 thì ta có thuật toán cho người chơi đầu tiên luôn thắng
2 Bàn cờ 3×3
Trường hợp 3.1: Nếu người chơi 1 đi chéo thì quân cờ sẽ đến kề với ô đích, người chơi 2 sẽ di chuyển quân cờ về đích và thắng Do đó người chơi 1 không đi theo cách này
Trang 62 Do đó ta không có thuật toán tối ưu cho người chơi 1 luôn thắng (chỉ có thuật toán
để người chơi 1 có khả năng thắng cao hơn)
Ta cũng cũng nhận thấy rằng, như vậy sẽ có thuật toán tối ưu chơ người
chơi 2 luôn thắng trong trường hợp bàn cờ 3×3
Trang 7Ta đã rút ra được kết luận là có thuật toán tối ưu để người chơi 2 luôn thắng trong bàn
cờ 3×3, điều này cũng tương đương với có thuật toán tối ưu để người di chuyển quân tốt đến ô 3×3 (ô được đánh số 1 trên hình vẽ) Với bàn cờ 4x4 thì người chơi 1 đi chéo trong nước đi đầu tiên, khi đó sẽ trở thành trường hợp bàn cờ 3×3 với người chơi
2 đi trước Từ kết luận ở trên thì người chơi 1 thắng
Vậy với bàn cờ 4×4 ta có thuật toán tối ưu cho người đi nước đầu tiên luôn
thắng
4 Bàn cờ 5×5
Nếu nước đi đầu tiên của người chơi 1 đi chéo thì sẽ trở thành trường hợp bàn cờ 4×4 với người chơi 2 đi trước,và người chơi 2 thắng Do đó người chơi 1 sẽ không đi chéo trong trường hợp này mà đi thẳng hoặc sang phải
Trang 9thêm số bước di chuyển nhằm tận dụng sơ hở của người chơi 2 để có được khả năng thắng cao nhất
ở trên để sau đó có nước đi phù hợp cho người chơi 1
III Nhận xét
Tại một ô của bàn cờ có tối đa 3 cách đi Với các ô nằm ở biên trên và biện phải của bàn cờ sẽ chỉ có 1 cách đi
Với bàn cờ n×n (n chẵn) thì ta có thuật toán để người chơi 1 luôn thắng
Với bàn cờ n×n (n lẻ) thì ta có thuật toán để người chơi 1 có khả năng thắng cao nhất
IV Thiết kế chương trình
1 Input:
N là kích thước của bàn cờ (bàn cờ dạng ma trận vuông
Vị trí xuất phát của quân tốt là ô góc trái phía dưới
2 Output:
Tìm đường đi tối ưu cho người chơi Ở đây ta sẽ lập trình trò chơi giữa người chơi và máy, tìm đường đi để máy luôn thắng
3 Thuật toán tìm đường đi cho máy
Ta đưa bài toán về dạng đồ thị Trong đó mỗi đỉnh v của đồ thị là một ô trong bàn cờ
Trang 10Quá trình chơi tương ứng với việc thêm các dấu mũi tên (in đậm) vào các cạnh để chuyển đồ thị về dạng có hướng với quy tắc:
- Ô xuất phát chỉ có mũi tên đi ra mà không có mũi tên đi vào
- Tại mỗi đỉnh không phải đỉnh xuất phát chỉ có một mũi tên đi vào duy nhất
- Tại mỗi đỉnh đã có mũi tên đi vào phải có và chỉ có một mũi tên đi ra
- Quá trình chơi kết thúc nếu tại một đỉnh không thể thêm dấu mũi tên phù hợp với quy tắc Tức là không thể vẽ mũi tên đi ra cho đỉnh đó
* Cấu trúc dữ liệu
-Ta có thể biểu diễn đồ thị trên bằng 2 biến toàn cục i và j Hai biến này chỉ vị trí hiện tại mà quân cờ đang đứng
-Vị trí bắt đầu i=n và j=1 Vị trí kết thúc i=1 và j=n
-Khi quân cờ đến vị trí kết thúc thì thuật toán dừng
* Thuật toán tìm đường đi cho máy
Ở đây ta xây dựng một chương trình chơi giữa máy (COM) và người sử dụng (MAN)
Để thể hiện độ tối ưu của thuật toán, ta thiết kế để máy có khả năng thắng là cao nhất
- Tại mỗi nước đi, thực hiện thao tác sau để chọn đường đi:
+ Khi n>5: Nếu i==n-j+1 thì đi chéo, nếu i<n-j+1 thì sang phải và nếu i>n-j+1 thì đi lên trước Khi N<=5 thì đối chiếu các trường hợ đặc biệt để cs nước đi phù hợp + Kết quả: máy luôn thắng với n chẵn
void play_computer(); //Lượt đi của máy
void play_player(); //Lượt đi của người chơi
void move(int k); //Di chuyển quân cờ
int kiemtra(); //Kiểm tra điều kiện thắng, nếu thắng trả
về giá trị 1
3 Các hàm đồ họa sử dụng làm giao diện trò chơi sử dụng graphics.h
Trang 11void kd_dohoa(); //Khởi động màn hình đồ họa
void kt_dohoa(); //Đóng màn hình đồ họa
void ve_banco(); //Vẽ bàn cờ
void xoa_quan_co(); //Xóa vị trí cũ của quân cờ bằng cách
hiển thị với màu trùng màu nền
void note(char *s); //Hiển thị thông báo s lên màn hình void un_note(char *s); //Xóa thông báo s đã hiện thị bằng
cách hiển thị với màu trùng với màu nền
mouse_click();//Lấy tọa độ click chuột và đổi về tọa độ
#define width 580 //do dai canh ban co
//kich thuoc man hinh do hoa
#define maxx 1360
#define maxy 700
int n,i,j,x1,y1;
//cac bien i,j danh dau vi tri hien tai cua quan co
//cac bien x1,y1 danh dau vi tri di di chuyen cua nguoi choi
char player[50]="Den luot ban, xin chon ";
char error[50]="Thao tac khong hop le! Chon lai!";
char computer[50]="May dang choi, vui long doi!";
char lose[10]="You lose!";
Trang 12char win[20]="You win!";
printf("-Nguoi thang cuoc la nguoi di chuyen quan
co den o tren cung ben phai.\n");
printf("\n\n");
//nhap khich thuoc ban co
if(n>20) printf("Kich thuoc qua lon, vui long nhap kich thuoc khac(<=20): ");
Trang 13void mouse_click() //Chuyen toa do chuot thanh toa do
dinh tren ban co
//truong hop chuot ngoai ban co
if(x<startx || x> startx+width || y<starty ||
Trang 14line(startx, starty+x*width/n, startx+width,
starty+x*width/n); //ke duong ngang
circle(tamx, tamy, width/n/3); //ve duong tron
setfillstyle(SOLID_FILL, color); //xac dinh kieu
to mau cho quan co
Trang 15floodfill(tamx, tamy, color); //to mau quan co
}
void xoa_quan_co() //Xoa vi tri cu cua quan so bang cach
to mau trung voi mau cua ban co
xoa_quan_co(); // xoa vi tri cu cua quan co truoc
khi di chuyen va hien thi vi tri moi
Trang 25-HẾT -