Tải bản đầy đủ (.doc) (25 trang)

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

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (273.99 KB, 25 trang )

Đồ án môn học:Cấu trúc dữ liệu và thuật toán

GVHD:Lê Quý Lộc

Ngày nay, Công nghệ thông tin đã trở thành một ngành khoa học cực kỳ quan
trọng trong cuộc sống hiện đại, đóng góp to lớn vào việc nâng cao nâng suất, hiệu
quả công việc cho các ngành nghề khác. Có thể nói, mọi ngành khoa học khác đều
cần đến sự trợ giúp của máy vi tính. Do đó, việc học tập và nghiên cứu về tin học
cũng trở nên hết sức cần thiết và tất yếu đối với mọi người.
Học kỳ vừa qua, chúng em dã được tiếp cận và tìm hiểu về môn Cấu trúc dữ
liệu và thuật toán. Đây là một môn học quan trọng đối với các sinh viên khoa
Công nghệ thông tin. Nó là cơ sở vững chắc để chúng ta 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.
Trong học kỳ này, chúng em đã được giao thực hiện Đồ án Cấu trúc dữ liệu
và thuật toán để tìm hiểu sâu thêm về môn học này và ứng dụng vào các bài toán
cụ thể. Và đề tài chúng em thực hiện là: “Trò chơi NIM”.
Trong quá trình thực hiện đồ án chắc chắn khó tránh khỏi các sai sót, vậy rất
mong sự đóng góp ý kiến của các thầy, cô giáo trong khoa. Và chúng em xin chân
thành gửi lời cảm ơn chân thành đến các thầy, cô trong khoa, đặc biệt là 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 hiện : 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 dữ liệu và 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, mỗi đống có một số viên sỏi. Hai người chơi
luân phiên nhau chơi như sau: Đến lượt người nào, người đó tùy chọn một đống
sỏi để bốc, và bốc ra một số viên sỏi (ít nhất 1 viên hoặc nhiều nhất là hết các viên
sỏi trong đống đã chọn). Ai bốc cuối cùng là thua. Lập chương trình tổ chức chơi
giữa người và máy tính theo các yêu cầu:
a. Số đống sỏi lúc đầu được nhập từ bàn phím
b. Số lượng viên sỏi trong mỗi đống được sinh ngẫu nhiên
c.
Máy sẽ gieo xu để xác định người hay máy đi trước
d.
Có thông báo số lượng trong mỗi đống trước và sau mỗi lượt đi
e. Thông báo kết quả cuối cùng

II.

Cấu trúc dữ liệu:


Với yêu cầu đề tài như trên, cấu trúc dữ liệu được sử dụng là Danh sách liên
kết đơn như sau:
struct stone_pile
{
int
stone;
stone_pile *next;
};
typedef stone_pile *list;
list root = NULL;
Trong đó có các trường:
- stone : kiểu số nguyên, để chỉ số sỏi có trong mỗi đống sỏi
- next : con trỏ kiểu stone_pile, để lưu địa chỉ của đống sỏi kế tiếp
- list : là kiểu con trỏ dùng để chỉ đến 1 phần tử kiểu stone_pile
- root : là con trỏ kiểu list chỉ đến đống sỏi đầu tiên

SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long
Lớp : 06T4

Trang:2


Đồ án môn học:Cấu trúc dữ liệu và thuật toán

III.

GVHD:Lê Quý Lộc

Thuật toán cài đặt:


Trò chơi NIM là 1 trò chơi theo lượt giữa 2 đấu thủ,trong đó lượt đi đầu tiên
được xác định bằng cách gieo đồng xu hoặc gieo xúc xắc. Trò chơi gồm có 2 thể
thức chơi:
1. Normal game: người bốc viên sỏi cuối cùng là người chiến thắng
2. Misère game: người bốc viên sỏi cuối cùng là người thua
( Source: )
Vì vậy, đề tài này sẽ được thực hiện theo thể thức Misère game. Nhưng trước
tiên chúng ta sẽ đề cập tới thể thức Normal game.
III.1.

Thuật toán Normal game:

1. Một số nguyên tắc của thuật toán:
Có một lớp trò chơi có 2 người chơi thỏa mãn nguyên tắc sau:
Tồn tại một thế có tính chất T sao cho với mọi cách đi đều dẫn đến một thế
không có tính chất T mà ta kí hiệu là NT = NOT (T) và từ NT luôn luôn tìm
được một cách đi để dẫn đến một thế có tính chất T.
Nếu thế thắng chung cuộc có tính chất T thì ai gặp phải thế đó sẽ thua, do đó
ta phải tìm mọi cách "nhường " thế có tính chất T cho đối phương.
Tính chất T nói trên được gọi là bất biến của trò chơi. Khi chung cuộc mọi
đống sỏi đều hết cho nên S = 0.
Giả sử ta có n đống sỏi. Gọi ai là số sỏi trong đống thứ i; i=1…n
Ta lấy tổng loại trừ của các ai
S= a1 ⊕ a2 ⊕ ... ⊕ an.
Ta sẽ chứng minh rằng bất biến (tính chất T) của trò chơi NIM chính là S = 0.
Ta sẽ sử dụng một số tính chất sau đây của phép XOR:
• Tính chất 1: a ⊕ b = 0 khi và chỉ khi 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 ⊕ 0 = a

Chú thích: ⊕ là 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 dữ liệu và thuật toán

GVHD:Lê Quý Lộc

Ta thừa nhận định lý sau:
• Định lý: Nếu S<>0 thì tồn tại một ai thỏa mãn ai ⊕ S < ai
Ta minh họa định lý trên qua ví dụ sau. Giả sử n = 3 và
a1 = 9 = 10012
a2 = 8 = 10002
a3 = 3 = 00112
S = 2 = 00102
Ta có: a1 ⊕ S = 11 > 9 = a2
a2 ⊕ S = 10 > 8 = a2
a3 ⊕ S = 1 < 3 = a3
Vậy a3 chính là số tìm được theo định lý trên.
Nhận xét: Nếu S = 0 và có ít nhất một đống sỏi với số sỏi khác 0 thì với mọi cách
đi ta luôn luôn có tổng loại trừ của các đống sỏi là một số khác 0.
Chứng minh nhận xét trên:
Thật vậy, không làm mất tính tổng quát ta giả sử rằng đống sỏi được chọn để
bốc là a1.
Giả sử rằng sau khi bốc đống a1 ta còn lại b1 viên sỏi.
Có thế coi việc bốc sỏi là thay đống a1 bằng b1, vì a1 ⊕ a1= 0 nên tổng loại

trừ thu được sau khi bốc sẽ là:
P = b1 ⊕ (a2 ⊕ ... ⊕ an)
Nếu P = 0 thì
b1 = (a2 ⊕ ... ⊕ an) = 0 ⊕ (a2 ⊕ ... ⊕ an)
= (a1 ⊕ a1) ⊕ (a2 ⊕ ... ⊕ an)
= a1 ⊕ (a1 ⊕ a2 ⊕ ... ⊕ an) = a1 ⊕ S.
Vì S = 0 nên b1 = a1 ⊕ 0 = a1.
Điều này chứng tỏ không viên sỏi nào được bốc tại đống a1, trái với luật chơi.
Vậy sau khi bốc ta phải có P<>0
Hệ quả: Gọi S và P lần lượt là tổng loại trừ của các đống sỏi trước và sau
một bước đi. Ta có, nếu S<>0 thì có một cách đi để P = 0.
Thật vậy, theo định lý trên ta tìm được một số ai để (ai ⊕ S)< ai.
Đặt bi = ai - (ai ⊕ S).
Ta bốc bi viên sỏi từ đống ai, đống này sẽ còn (ai ⊕ S) viên.
Khi đó P = (ai ⊕ S) ⊕ (ai ⊕ S) = 0  đpcm.
Từ nhận xét và hệ quả nói trên ta suy ra: S = 0 chính là bất biến của 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 dữ liệu và thuật toán

GVHD:Lê Quý Lộc

2. Thuật toán Normal game:
Thủ tục NIM - Trò chơi NIM với m đống sỏi gồm các bước sau:

1. Kiểm tra giá trị hợp lệ của m
2. Khởi trị;
2a. Sinh ngẫu nhiên các giá trị ai>=1, i=1..n.
2b. Gieo xu để xác định ai đi trước, người hay máy
3. Chơi theo sơ đồ sau:
Repeat
If Ban then Bandi
Else Maydi;
Ban:= NOT Ban;
Xem;
Until Thua;
4. Thông báo kết quả thắng - thua giữa người và máy.
Trong đó thủ tục Maydi được triển khai theo sơ đồ đối thủ thông minh trình bày
sau đây. Nước đi của đối thủ thông minh khi đó sẽ bao gồm hai bước sau:
Tính S = a1 ⊕ a2 ⊕ a3 ⊕ ... ⊕ an
1.
Nếu S <> 0: thực hiện các bước sau:
2.
2a. Duyệt các đống sỏi để tìm đống ai thỏa điều kiện (ai ⊕ S)< ai
2b. Bốc ai - (ai ⊕ S) viên từ đống ai tìm được. Số sỏi còn lại của đống này
sẽ là ( ai ⊕ S).
Nếu S = 0: chọn đống lớn để bốc 1 viên cốt làm cho đối phương khó phát
hiện nguy cơ thua của ta.
III.2.

Thuật toán Misère game:

Trước khi nêu ra thuật toán chúng ta xét 1 ví dụ minh hoạ sau:
Giả sử có 3 đống sỏi với số sỏi lần lượt là 3, 4 và 5 viên sỏi. Với thể thức
người bốc cuối cùng là thua (Misère game) thì chiến thuật để thắng là:

A B C Nim-sum
3
1
1
1
1
0

4
4
4
2
2
2

5
5
3
3
2
2

0102=210
0002=010
1102=610
0002=010
0012=110
0002=010

Tôi lấy 2 viên từ đống A,và nim-sum = 0, vậy tôi sẽ thắng

Bạn lấy 2 viên từ đống C
Tôi lấy 2 viên từ đống B
Bạn lấy 1 viên từ đống C
Tôi lấy 1 viên từ đống A
Bạn lấy 1 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 dữ liệu và thuật toán

GVHD:Lê Quý Lộc

A B C Nim-sum
0 2 1 0112=310 Trong chiến thuật Normal game tôi sẽ lấy 1 viên từ đống B để
có 1 số chẵn các đống có 1 viên sỏi. Nhưng trong chiến thuật
Misère game tôi sẽ lấy 2 viên từ đống B để có 1 số lẻ các
đống có 1 viên sỏi.
0 0 1 0012=110 Bạn lấy 1 viên từ đống C, và bạn thua.
( Dịch từ trang: )
Từ ví dụ trên ta có thể rút ra thuật toán Misère game gồm các bước sau:
1. Repeat
1a. Với mỗi bước đi 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 thì các nước đi được thực hiện
theo thuật toán Normal game
Until Trường hợp đặc biệt
2. Trường hợp đặc biệt: có 1 số đống sỏi chỉ có 1 viên và 1 đống có nhiều hơn 1

viên
2a. Kiểm tra số đống sỏi hiện tại
2b. If số đống sỏi lẻ
Để lại 1 viên trong đống có số sỏi > 1
Else
Bốc hết trong đống có số sỏi > 1

SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long
Lớp : 06T4

Trang:6


Đồ án môn học:Cấu trúc dữ liệu và thuật toán

IV.

GVHD:Lê Quý Lộc

Chương trình :

Chương trình được cài đặt bằng ngôn ngữ C, được biên dịch bằng 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 <stdio.h>

#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <dos.h>
//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 ra
//so soi lon nhat trong 1 dong
//mau cua bang
//mau cua so
//mau cua so 0
//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 dữ liệu và thuật toán

do {
write("\n Nhap so dong soi muon choi: ",2);
scanf("%d", &m);
} while (m<=0 || 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 ra 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 ra dong co 0 vien soi
temp->next = NULL;
root = temp;
cur = root;
for (i=1; i//tao cac dong tiep theo
{

temp = new stone_pile;
temp->stone = 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 dữ liệu và thuật toán

GVHD:Lê Quý Lộc

void display_table(list root)
{
int i = 1, x1 = 5, x2 = 13, y = 6 ;
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; i<k; i++) tmp = tmp->next;
if (tmp->stone) return 1;
else return 0;
}
/*=============================================*/
void player(list &root)
{
int k, n, i;
list tmp = root;
do
{
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 dữ liệu và thuật toán

GVHD:Lê Quý Lộc

scanf("%d",&k);
} while (k<=0 || k > piles_at_fisrt || check_stone(root, k)= =0);
for(i=1;i<k; i++) tmp = tmp->next;
do
{
gotoxy(30,9);
printf(" Va so soi muon boc:
");
gotoxy(51,9);
scanf("%d", &n);
} while (n<=0 || 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 0
{
int i=0, i1=0; //bien dem so dong 1
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 dữ liệu và 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 ra 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 1 vien trong dong do
else
//neu so dong hien tai la chan
take = tmp->stone;
// thi boc het dong do
}
else {
s = nimsum(root);
i=1;
if (s)
//nimsum != 0
{
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 dữ liệu và thuật toán

GVHD:Lê Quý Lộc

i++;
}
take = tmp->stone - (tmp->stone ^ s);
}
else
// nimsum == 0
{
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 != 0
{
while((tmp->stone ^ s) >= tmp->stone)
{
tmp= tmp->next;
i++;
}
take = tmp->stone - (tmp->stone ^ s);
tmp->stone -= take;
}
else
// nimsum == 0
{
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 dữ liệu và 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; i<5; i++)
{
cprintf(".");
sleep(1);
}
k =random(6);
return(k%2);
}
/*=============================================*/
void start_game()
{
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(" (=.=) Ban duoc di truoc!!!",11);

else write(" (^_^) Computer di truoc!!!",14);
gotoxy(30,9);
printf(" Press any key to continue...");
getch();
}
/*=============================================*/
int end_game(list root)
{
list tmp;
tmp = root;
while(tmp != NULL && tmp->stone = =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 dữ liệu và thuật toán

GVHD:Lê Quý Lộc

/*=============================================*/
void misere_game()
{
int end;
start_game();
do

{
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();
do
{
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 dữ liệu và 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();
do
{
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 do 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 1 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 dữ liệu và thuật toán

GVHD:Lê Quý Lộc

{
int i;
gotoxy(x1,y1);
putch(201);
for(i=x1+1;i<=x2-1;putch(205),i++);
putch(187);
gotoxy(x1,y2);
putch(200);
for(i=x1+1;i<=x2-1;putch(205),i++);
putch(188);
for(i=y1+1;i<=y2-1;i++)
{
gotoxy(x1,i);
putch(186);
gotoxy(x2,i);

putch(186);
}
}
/*============================================*/
void welcome_scr()
{
char ch;
do
{
clrscr();
textcolor(YELLOW);
box(29,6,53,14);
gotoxy(36,9);
write(" WELCOME TO",10);
//10 = LIGHTGREEN
gotoxy(37,11);
write(" NIM GAME ",10);
gotoxy(29,23);
write(" Author: Ha Long & Phu Duy ",9); //9 = LIGHTBLUE
gotoxy(36,24);
write(" version 1.0 ",11);
//11 = LIGHTCYAN
gotoxy(33,25);
write(" Copyright 11/2008 ",11);
gotoxy(28,17);
printf(" Press ENTER to start game ");
ch=getch();
}while(ch!=0x0D);
}
SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long

Lớp : 06T4

Trang:16


Đồ án môn học:Cấu trúc dữ liệu và thuật toán

GVHD:Lê Quý Lộc

/*=============================================*/
int mainmenu()
{
int k;
do {
clrscr();
title(0);
printf("\n\n\t");
textcolor(14);
//yellow
cprintf(" Main menu:");
textcolor(11);
//lightcyan
printf("\n\t\t");
cprintf("\n1. One player"); printf("\n\t\t");
cprintf("\n2. Two players"); printf("\n\t\t");
cprintf("\n3. Guide");
printf("\n\t\t");
cprintf("\n0. Exit game"); printf("\n\t\t");
printf("\n\t Choose: "); scanf("%d",&k);
} while (k<0 || k>3);

return k;
}
/*==============================================*/
int play_mode()
// chon che do choi
{
int t;
do
{
clrscr();
title(0);
printf("\n\n\t");
write(" Choose a play mode:",14);
//14 = yellow
printf("\n\t\t");
write("\n1. Misere mode ",11); printf("\n\t\t"); //11 = lightcyan
write("\n2. Normal mode ",11); printf("\n\t\t");
write("\n0. Back",11);
printf("\n\t\t");
printf("\n\t Choose: "); scanf("%d",&t);
} while (t<0 || t>2);
return t;
}
/*==============================================*/
void help()
// muc huong dan nguoi choi
{
char ch[256];
SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long
Lớp : 06T4


Trang:17


Đồ án môn học:Cấu trúc dữ liệu và thuật toán

GVHD:Lê Quý Lộc

FILE *fp;
fp = fopen("help.txt","r");
// doc file huong dan
clrscr();
title(3);
while (!feof(fp))
{
fgets(ch,70,fp);
printf("%s",ch);
}
fclose(fp);
write("\n\r\n Press any key to return main menu...",6);
getch();
}
/*==============================================*/
void main()
{
int cmd , mode;
welcome_scr();
do
{
cmd = mainmenu();

switch (cmd) {
case 1:
mode = play_mode();
if(mode = = 1) misere_game();
else if (mode = = 2) normal_game();
break;
case 2:
mode = play_mode();
if (mode) two_player(mode);
break;
case 3:
help();
break;
case 0: break;
}
} while (cmd);
}

SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long
Lớp : 06T4

Trang:18


Đồ án môn học:Cấu trúc dữ liệu và thuật toán

V.

GVHD:Lê Quý Lộc


Kết quả:
1. Màn hình chào:

2. Màn hình chọn:

SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long
Lớp : 06T4

Trang:19


Đồ án môn học:Cấu trúc dữ liệu và thuật toán

GVHD:Lê Quý Lộc

3. Màn hình chọn thể thức:

4. Nhập số đống sỏi:

SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long
Lớp : 06T4

Trang:20


Đồ án môn học:Cấu trúc dữ liệu và thuật toán

GVHD:Lê Quý Lộc

5. Đợi máy xác định ai được đi trước:


6. Bắt đầu chơi:

SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long
Lớp : 06T4

Trang:21


Đồ án môn học:Cấu trúc dữ liệu và thuật toán

GVHD:Lê Quý Lộc

7. Lượt máy đi:

8. Kết thúc:

SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long
Lớp : 06T4

Trang:22


Đồ án môn học:Cấu trúc dữ liệu và thuật toán

GVHD:Lê Quý Lộc

9. Hướng dẫn:

SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long

Lớp : 06T4

Trang:23


Đồ án môn học:Cấu trúc dữ liệu và thuật toán

GVHD:Lê Quý Lộc

Nhận xét, đánh giá:
-

1. Ưu điểm:
Chương trình chạy ổn định, tương đối nhanh, không mắc lỗi.
Chương trình có giao diện thân thiện với người dùng, gần với một trò chơi
hơn là một bài toán, nên người sử dụng sẽ có hứng thú với chương trình.

-

2. Khuyết điểm:
Bố cục của chương trình còn tương đối lộn xộn, hơi rườm rà.
Chưa xây dựng được giao diện người dùng sử dụng chuột trên màn hình ở
chế độ đồ họa, chỉ mới thực hiện lệnh trên màn hình ở chế độ văn bản.

LỜI KẾT:
Trong quá trình thực hiện đồ án, chúng em đã rút được nhiều kinh nghiệm
bổ ích cho chuyên ngành của mình, đặc biệt là kỹ năng làm việc theo nhóm. Công
việc chỉ được thực hiên tốt nhất khi có sự cố gắng của cả tập thể. Ngoài ra, sau khi
thực hiện xong đồ án này thì kiến thức lập trình của chúng em cũng được củng cố
và bổ sung nhiều.

Với khả năng còn hạn chế của mình, nên đồ án của chúng em chắc còn
nhiều thiếu sót. Rất mong được sự góp ý chân thành của quý thầy, cô. Chúng em
xin chân thành cảm ơn !

***  ***

SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long
Lớp : 06T4

Trang:24


Đồ án môn học:Cấu trúc dữ liệu và thuật toán

GVHD:Lê Quý Lộc

MỤC LỤC
1
I. Giới thiệu đề tài:.....................................................................................................2
II. Cấu trúc dữ liệu:....................................................................................................2
III. Thuật toán cài đặt:................................................................................................3
III.1. Thuật toán Normal game:.............................................................................3
1. Một số nguyên tắc của thuật toán:.............................................................................3
2. Thuật toán Normal game:..........................................................................................5

III.2. Thuật toán Misère game:..............................................................................5
IV. Chương trình :......................................................................................................7
V. Kết quả:...............................................................................................................19
Nhận xét, đánh giá:.................................................................................................24
1. Ưu điểm:...........................................................................................................24

2. Khuyết điểm:....................................................................................................24
LỜI KẾT:................................................................................................................24
MỤC LỤC...............................................................................................................25

SVTH: Nguyễn Phú Duy - Cao Đình Hạ Long
Lớp : 06T4

Trang:25


×