1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Đồ án Cấu trúc dữ liệu và thuật toán - Trò chơi NIM

25 2,3K 13

Đ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 25
Dung lượng 271 KB

Nội dung

Đồ án môn học:Cấu trúc liệu thuật toán GVHD:Lê Quý Lộc Ngày nay, Công nghệ thông tin trở thành ngành khoa học quan trọng sống đại, đóng góp to lớn vào việc nâng cao nâng suất, hiệu công việc cho ngành nghề khác Có thể nói, ngành khoa học khác cần đến trợ giúp máy vi tính Do đó, việc học tập nghiên cứu tin học trở nên cần thiết tất yếu người Học kỳ vừa qua, chúng em dã tiếp cận tìm hiểu môn Cấu trúc liệu thuật toán Đây môn học quan trọng sinh viên khoa Công nghệ thông tin Nó sở vững để giải số toán, đồng thời cung cấp cho hiểu biết giải thuật tác động lên liệu, cách tổ chức liệu để giải toán cho hiệu tối ưu Trong học kỳ này, chúng em giao thực Đồ án Cấu trúc liệu thuật toán để tìm hiểu sâu thêm môn học ứng dụng vào toán cụ thể Và đề tài chúng em thực là: “Trò chơi NIM” Trong trình thực đồ án chắn khó tránh khỏi sai sót, mong đóng góp ý kiến thầy, cô giáo khoa Và chúng em xin chân thành gửi lời cảm ơn chân thành đến thầy, cô khoa, đặc biệt thầy Lê Quý Lộc tận tình hướng dẫn, tạo điều kiện cho chúng em hoàn thành đề tài Chúng em xin chân thành cảm ơn ! Giảng viên hướng dẫn: Lê Quý Lộc Sinh viên thực : Nguyễn Phú Duy Cao Đình Hạ Long Lớp : 06T4 SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long Lớp : 06T4 Trang:1 Đồ án môn học:Cấu trúc liệu thuật toán I GVHD:Lê Quý Lộc Giới thiệu đề tài: Đề 15: Trò chơi NIM: Có n đống sỏi, đống có số viên sỏi Hai người chơi luân phiên chơi sau: Đến lượt người nào, người tùy chọn đống sỏi để bốc, bốc số viên sỏi (ít viên nhiều hết viên sỏi đống chọn) Ai bốc cuối thua Lập chương trình tổ chức chơi người máy tính theo yêu cầu: a Số đống sỏi lúc đầu nhập từ bàn phím b Số lượng viên sỏi đống sinh ngẫu nhiên c Máy gieo xu để xác định người hay máy trước d Có thông báo số lượng đống trước sau lượt e Thông báo kết cuối II Cấu trúc liệu: Với yêu cầu đề tài trên, cấu trúc liệu sử dụng Danh sách liên kết đơn sau: struct stone_pile { int stone; stone_pile *next; }; typedef stone_pile *list; list root = NULL; Trong có trường: - stone : kiểu số nguyên, để số sỏi có đống sỏi - next : trỏ kiểu stone_pile, để lưu địa đống sỏi - list : kiểu trỏ dùng để đến phần tử kiểu stone_pile - root : trỏ kiểu list đến đống sỏi SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long Lớp : 06T4 Trang:2 Đồ án môn học:Cấu trúc liệu thuật toán III GVHD:Lê Quý Lộc Thuật toán cài đặt: Trò chơi NIM trò chơi theo lượt đấu thủ,trong lượt xác định cách gieo đồng xu gieo xúc xắc Trò chơi gồm thức chơi: Normal game: người bốc viên sỏi cuối người chiến thắng Misère game: người bốc viên sỏi cuối người thua ( Source: http://en.wikipedia.org/wiki/Nim_Game ) Vì vậy, đề tài thực theo thể thức Misère game Nhưng trước tiên đề cập tới thể thức Normal game III.1 Thuật toán Normal game: Một số nguyên tắc thuật toán: Có lớp trò chơi có người chơi thỏa mãn nguyên tắc sau: Tồn có tính chất T cho với cách dẫn đến tính chất T mà ta kí hiệu NT = NOT (T) từ NT luôn tìm cách để dẫn đến có tính chất T Nếu thắng chung có tính chất T gặp phải thua, ta phải tìm cách "nhường " có tính chất T cho đối phương Tính chất T nói gọi bất biến trò chơi Khi chung đống sỏi hết S = Giả sử ta có n đống sỏi Gọi số sỏi đống thứ i; i=1…n Ta lấy tổng loại trừ S= a1 ⊕ a2 ⊕ ⊕ an Ta chứng minh bất biến (tính chất T) trò chơi NIM S = Ta sử dụng số tính chất sau phép XOR: • Tính chất 1: a ⊕ b = a = b (suy từ định nghĩa) • Tính chất 2: a ⊕ b = b ⊕ a (Tính giao hoán) • Tính chất 3: (a ⊕ b) ⊕ c = a ⊕ (b ⊕ c) (Tính kết hợp) • Tính chất 4: a ⊕ = a Chú thích: ⊕ kí hiệu phép XOR SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long Lớp : 06T4 Trang:3 Đồ án môn học:Cấu trúc liệu thuật toán GVHD:Lê Quý Lộc Ta thừa nhận định lý sau: • Định lý: Nếu S0 tồn thỏa mãn ⊕ S < Ta minh họa định lý qua ví dụ sau Giả sử n = a1 = = 10012 a2 = = 10002 a3 = = 00112 S = = 00102 Ta có: a1 ⊕ S = 11 > = a2 a2 ⊕ S = 10 > = a2 a3 ⊕ S = < = a3 Vậy a3 số tìm theo định lý Nhận xét: Nếu S = có đống sỏi với số sỏi khác với cách ta luôn có tổng loại trừ đống sỏi số khác Chứng minh nhận xét trên: Thật vậy, không làm tính tổng quát ta giả sử đống sỏi chọn để bốc a1 Giả sử sau bốc đống a1 ta lại b1 viên sỏi Có coi việc bốc sỏi thay đống a1 b1, a1 ⊕ a1= nên tổng loại trừ thu sau bốc là: P = b1 ⊕ (a2 ⊕ ⊕ an) Nếu P = b1 = (a2 ⊕ ⊕ an) = ⊕ (a2 ⊕ ⊕ an) = (a1 ⊕ a1) ⊕ (a2 ⊕ ⊕ an) = a1 ⊕ (a1 ⊕ a2 ⊕ ⊕ an) = a1 ⊕ S Vì S = nên b1 = a1 ⊕ = a1 Điều chứng tỏ không viên sỏi bốc đống a1, trái với luật chơi Vậy sau bốc ta phải có P0 Hệ quả: Gọi S P tổng loại trừ đống sỏi trước sau bước Ta có, S0 có cách để P = Thật vậy, theo định lý ta tìm số để (ai ⊕ S)< Đặt bi = - (ai ⊕ S) Ta bốc bi viên sỏi từ đống ai, đống (ai ⊕ S) viên Khi P = (ai ⊕ S) ⊕ (ai ⊕ S) =  đpcm Từ nhận xét hệ nói ta suy ra: S = bất biến trò chơi NIM SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long Lớp : 06T4 Trang:4 Đồ án môn học:Cấu trúc liệu thuật toán GVHD:Lê Quý Lộc Thuật toán Normal game: Thủ tục NIM - Trò chơi NIM với m đống sỏi gồm bước sau: Kiểm tra giá trị hợp lệ m Khởi trị; 2a Sinh ngẫu nhiên giá trị ai>=1, i=1 n 2b Gieo xu để xác định trước, người hay máy Chơi theo sơ đồ sau: Repeat If Ban then Bandi Else Maydi; Ban:= NOT Ban; Xem; Until Thua; Thông báo kết thắng - thua người máy Trong thủ tục Maydi triển khai theo sơ đồ đối thủ thông minh trình bày sau Nước đối thủ thông minh bao gồm hai bước sau: Tính S = a1 ⊕ a2 ⊕ a3 ⊕ ⊕ an Nếu S 0: thực bước sau: 2a Duyệt đống sỏi để tìm đống thỏa điều kiện (ai ⊕ S)< 2b Bốc - (ai ⊕ S) viên từ đống tìm Số sỏi lại đống ( ⊕ S) Nếu S = 0: chọn đống lớn để bốc viên cốt làm cho đối phương khó phát nguy thua ta III.2 Thuật toán Misère game: Trước nêu thuật toán xét ví dụ minh hoạ sau: Giả sử có đống sỏi với số sỏi 3, viên sỏi Với thể thức người bốc cuối thua (Misère game) chiến thuật để thắng là: A B C Nim-sum 1 1 4 2 5 3 2 0102=210 0002=010 1102=610 0002=010 0012=110 0002=010 Tôi lấy viên từ đống A,và nim-sum = 0, thắng Bạn lấy viên từ đống C Tôi lấy viên từ đống B Bạn lấy viên từ đống C Tôi lấy viên từ đống A Bạn lấy viên từ đống C SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long Lớp : 06T4 Trang:5 Đồ án môn học:Cấu trúc liệu thuật toán GVHD:Lê Quý Lộc A B C Nim-sum 0112=310 Trong chiến thuật Normal game lấy viên từ đống B để có số chẵn đống có viên sỏi Nhưng chiến thuật Misère game lấy viên từ đống B để có số lẻ đống có viên sỏi 0 0012=110 Bạn lấy viên từ đống C, bạn thua ( Dịch từ trang: http://en.wikipedia.org/wiki/Nim_Game#Mathematical_theory ) Từ ví dụ ta rút thuật toán Misère game gồm bước sau: Repeat 1a Với bước kiểm tra xem có rơi vào trường hợp đặc biệt chưa 1b Nếu chưa rơi vào trường hợp đặc biệt nước thực theo thuật toán Normal game Until Trường hợp đặc biệt Trường hợp đặc biệt: có số đống sỏi có viên đống có nhiều viên 2a Kiểm tra số đống sỏi 2b If số đống sỏi lẻ Để lại viên đống có số sỏi > Else Bốc hết đống có số sỏi > SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long Lớp : 06T4 Trang:6 Đồ án môn học:Cấu trúc liệu thuật toán IV GVHD:Lê Quý Lộc Chương trình : Chương trình cài đặt ngôn ngữ C, biên dịch trình biên dịch Borland C 5.02 /* - Chuong trinh Tro choi NIM - Compiler: Borland C 5.02 - Written by: Ha Long & Phu Duy */ /*=============================================*/ #include #include #include #include #include //Khai bao cac bien toan cuc const int maxpile = 10; const int maxstone = 30; const int khungcl = 10; const int socl = 14 ; const int zerocl = 12; int status; int piles_at_fisrt, piles_at_pre; // so dong lon nhat co the tao //so soi lon nhat dong //mau cua bang //mau cua so //mau cua so //luot di, =0->may di||A di, =1->nguoi di||B di //so dong ban dau va so dong hien tai //Khai bao cau truc du lieu struct stone_pile { int stone; // stone = soi stone_pile *next; }; typedef stone_pile *list; list root = NULL; /*=============================================*/ void write(char *s, int c) { textcolor(c); cprintf("%s",s); } /*=============================================*/ void put_piles(int &m) // ham nhap vao so dong soi { SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long Lớp : 06T4 Trang:7 Đồ án môn học:Cấu trúc liệu thuật toán { write("\n Nhap so dong soi muon choi: ",2); scanf("%d", &m); } while (m maxpile); GVHD:Lê Quý Lộc //2 = GREEN } /*============================================*/ void title(int i) { clrscr(); gotoxy(34,2); write("NIM GAME",13); gotoxy(43,2); switch (i) { case 1: write("- MISERE",13); break; case 2: write("- NORMAL",13); break; case 3: write("- GUIDE",13); break; default: break; } } /*=============================================*/ void create(list &root, int n) //tao n dong soi voi so soi ngau nhien { list cur, temp; int i; temp = new stone_pile; //tao dong dau tien temp->stone = random(maxstone)+1; //de tranh tao dong co vien soi temp->next = NULL; root = temp; cur = root; for (i=1; istone = random(maxstone)+1; temp->next = NULL; cur->next = temp; cur = temp; } } /*===========================================*/ SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long Lớp : 06T4 Trang:8 Đồ án môn học:Cấu trúc liệu thuật toán GVHD:Lê Quý Lộc void display_table(list root) { int i = 1, x1 = 5, x2 = 13, y = ; list cur; cur = root; textcolor(khungcl); printf("\n"); cprintf(" + + +"); printf("\n"); cprintf(" | Dong | So soi |"); printf("\n"); cprintf(" + + +"); while (cur != NULL) { textcolor(khungcl); gotoxy(1, y); cprintf(" | | |"); printf("\n"); cprintf(" + + +"); if (cur->stone = =0) textcolor(zerocl); else textcolor(socl); gotoxy(x1, y); cprintf("%2d", i); gotoxy(x2, y); cprintf("%2d", cur->stone); i++; y +=2; cur = cur->next; } } /*===========================================*/ int check_stone(list root, int k) //kiem tra dong muon boc co hop le ko { int i; list tmp = root; for(i=1; inext; if (tmp->stone) return 1; else return 0; } /*=============================================*/ void player(list &root) { int k, n, i; list tmp = root; { gotoxy(30,7); printf(" Moi ban chon dong : "); gotoxy(51,7); SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long Lớp : 06T4 Trang:9 Đồ án môn học:Cấu trúc liệu thuật toán GVHD:Lê Quý Lộc scanf("%d",&k); } while (k piles_at_fisrt || check_stone(root, k)= =0); for(i=1;inext; { gotoxy(30,9); printf(" Va so soi muon boc: "); gotoxy(51,9); scanf("%d", &n); } while (n tmp->stone); tmp->stone = tmp->stone - n; if (tmp->stone = =0) piles_at_pre ; //neu boc het thi giam so dong soi } /*=============================================*/ int nimsum(list root) { int s; list cur = root; s = cur->stone; while (cur->next !=NULL) { cur = cur->next; s = s ^ cur->stone; } return s; } /*=============================================*/ int special_case(list root) //kiem tra truong hop dac biet //neu dung tra ve vi tri dong co soi >1 ; neu sai tra ve { int i=0, i1=0; //bien dem so dong int pos; // bien chi vi tri dong soi hien tai list cur; cur = root; while (cur!=NULL) { if(cur->stone = =1) i1++; else if (cur->stone >1) pos = i+1; cur= cur->next; i++; } SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long Lớp : 06T4 Trang:10 Đồ án môn học:Cấu trúc liệu thuật toán GVHD:Lê Quý Lộc if (i1= = (piles_at_pre-1)) return pos; else return 0; } /*=============================================*/ int pile_max(list root, list &max) //tim dong co so soi lon nhat { list cur; int imax, i; max = root; imax=1; //vi tri cua dong max cur = root->next; i = 2; while(cur !=NULL) { if (cur->stone > max->stone) { max = cur; imax =i;} cur = cur->next; i ++; } return imax; } /*=============================================*/ void misere_stragety(list &root) //chien thuat misere cua may' { list tmp = root; int take, s, i; i=special_case(root); //vi tri cua dong co nhieu vien soi if (i) { //roi vao truong hop dac biet for(int j=1; j< i; j++) tmp = tmp->next; if(piles_at_pre%2) //neu so dong soi hien tai la le? take = tmp->stone -1; // thi de lai vien dong else //neu so dong hien tai la chan take = tmp->stone; // thi boc het dong } else { s = nimsum(root); i=1; if (s) //nimsum != { while((tmp->stone ^ s) >= tmp->stone) { tmp= tmp->next; SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long Lớp : 06T4 Trang:11 Đồ án môn học:Cấu trúc liệu thuật toán GVHD:Lê Quý Lộc i++; } take = tmp->stone - (tmp->stone ^ s); } else // nimsum == { i = pile_max(root, tmp); take = random(tmp->stone)+1; } } tmp->stone -= take; if (tmp->stone= =0) piles_at_pre ; gotoxy(30,7); printf(" Computer boc %d vien o dong %d.", take,i); getch(); } /*=============================================*/ void normal_stragety(list &root) //chien thuat normal cua may' { list tmp = root; int take, s, i; // take = so soi muon boc di s = nimsum(root); i=1; if (s) //nimsum != { while((tmp->stone ^ s) >= tmp->stone) { tmp= tmp->next; i++; } take = tmp->stone - (tmp->stone ^ s); tmp->stone -= take; } else // nimsum == { i = pile_max(root, tmp); take = random(tmp->stone)+1; tmp->stone -=take; } gotoxy(30,7); printf(" Computer boc %d vien o dong %d.", take,i); SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long Lớp : 06T4 Trang:12 Đồ án môn học:Cấu trúc liệu thuật toán GVHD:Lê Quý Lộc getch(); } /*=============================================*/ int gieoxucxac() { int k,i; clrscr(); gotoxy(30,5); write(" Xin cho may gieo xuc xac: ",2); for(i=0; istone = =0) tmp = tmp->next; if (tmp = = NULL) return 1; else return 0; } SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long Lớp : 06T4 Trang:13 Đồ án môn học:Cấu trúc liệu thuật toán GVHD:Lê Quý Lộc /*=============================================*/ void misere_game() { int end; start_game(); { title(1); display_table(root); if (status) player(root); else misere_stragety(root); end = end_game(root); if (!end) status = !status; } while (!end); clrscr(); title(1); display_table(root); gotoxy(33,7); if (status) write(" Sorry! You lose!!!",12); // nguoi boc cuoi cung => thua else write(" Congratulation! You win!!!",11); //may boc cuoi cung thi may // thua => nguoi thang getch(); } /*============================================*/ void normal_game() { int end; start_game(); { title(2); display_table(root); if (status) player(root); else normal_stragety(root); end = end_game(root); if (!end) status = !status; } while (!end); clrscr(); title(2); display_table(root); gotoxy(33,7); if(status) write(" Congratulation! You win!!!",11); //neu nguoi boc cuoi thi SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long Lớp : 06T4 Trang:14 Đồ án môn học:Cấu trúc liệu thuật toán else write(" Sorry! You lose!!!",12); getch(); GVHD:Lê Quý Lộc nguoi thang //neu nguoi boc cuoi thi nguoi thua } /*============================================*/ void two_player(int mode) { int end; clrscr(); put_piles(piles_at_fisrt); randomize(); //khoi dong bo tao so ngau nhien create(root, piles_at_fisrt); piles_at_pre = piles_at_fisrt; status = gieoxucxac(); gotoxy(30,7); if (status) write(" B duoc di truoc",14); else write(" A duoc di truoc",11); getch(); { title(mode); display_table(root); gotoxy(27,5); if (status= =0) write("Luot cua A :",11); else write("Luot cua B :",14); player(root); end = end_game(root); if(!end) status= !status; } while (!end); clrscr(); title(mode); display_table(root); if (mode= =1) //che misere status = !status; gotoxy(33,7); if (status = =0) // nguoi A thang write(" Congratulation! Player A win!!!",11); else write(" Congratulation! Player B win!!!",14); getch(); } /*==============================================*/ void box(int x1,int y1,int x2,int y2) // ham tao hop vien quanh text SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long Lớp : 06T4 Trang:15 Đồ án môn học:Cấu trúc liệu thuật toán GVHD:Lê Quý Lộc { int i; gotoxy(x1,y1); putch(201); for(i=x1+1;i

Ngày đăng: 17/03/2017, 20:20

TỪ KHÓA LIÊN QUAN

w