PDA

View Full Version : Thuật Toán Của Trò Chơi Caro.



daoson_hai
27-05-2008, 07:51
Mong mỏi các bác chỉ giúp một số thuật toán của trò chơi này. Rất mong được các bác nhiệt tình giúp đỡ vì mình đang mắc ở phần mô phỏng thuật toán vào chương trình.

Legend_VN
29-05-2008, 07:23
Bạn thực hiện bài toán theo mô hinh sau:
IF sapchienthang=1 THEN tancong;
IF baodong<>0 THEN phongthu(baodong) ELSE tancong;
******
Xây dựng hàm baodong:
-Nếu đối phương có 1 hàng 3 chưa bị chặn trả về 1 (báo động 1).
-Nếu đối phương có 1 hàng 4 chặn 1 đầu hoặc 1 hàng 4 không bị chặn nhưng bị phân cách thành 2 phần phân cách nhau bởi 1 ô trống trả về 2 (báo động 2)
-Nếu đối phương đánh vào 1 ô trống bất kì gây ra 2 lần báo động 1 hoặc 1 lần báo động 1 và 1 lần báo động 2 thì trả về 3 (báo động 3)
-Nếu đối phương đánh vào 1 ô trống bất kì gây ra nhiều hơn 1 lần báo động 3 thì trả về 4 (báo động 4)
Xây dựng hàm phongthu:
-Báo động 1: đánh vào 1 trong 2 đầu, nếu 1 trong 2 đầu trùng với hàm tấn công hoặc các hàm báo động khác thì đánh vào đầu đó, còn không thì random (hoặc đánh vào đầu gần quân mình hơn, đó là tùy ý của bạn)
-Báo động 2: chỉ có thể đánh vào 1 vị trí: với hàng 4 bị chặn 1 đầu thì đánh vào đầu còn lại, với hàng 4 không bị chặn nhưng bị phân cách thì đánh vào vị trí phân cách đó.
-Báo động 3: nếu 1 trong 5 vị trí chặn trùng với vị trí tấn công hay phòng thủ thì đánh vào vị trí đó còn nếu không thì đánh vào vị trí đối thủ sẽ đánh
-Báo động 4: dánh vào vị trí đối thủ sẽ đánh
Xây dựng hàm tancong:
-Bạn nên sử dụng một số chiến thuật tấn công dựng sẵn
-Cài này tương đối “mệt” nên xin dành lúc khác edit bổ sung :D
******
P/S: Đó chỉ là một số trường hợp báo động và phòng thủ cơ bản. Vì tôi chưa từng viết một chương trình đánh caro nên rất có thể còn một số trường hợp khác, bạn nên tự tìm và bổ sung

daoson_hai
29-05-2008, 19:00
Mình có nghe nói người ta dùng thuật toán anpha-beta hoặc min/max để làm thuật toán cho trò chơi. Nhưng mình ko có biết các thuật toán đó ra sao cả.
Bác nào biết chỉ giùm hoặc chỉ link để mình tự tìm hiểu. Mình lên mạng vào google kiếm mờ cả mắt mà chẳng thấy gì hết.
Rất cảm ơn bạn Legend_VN đã nhiệt thành giúp đỡ, mình sẽ nghiên cứu cách làm của bạn.

xuanhau
29-05-2008, 20:18
Mình có nghe nói người ta dùng thuật toán anpha-beta hoặc min/max để làm thuật toán cho trò chơi. Nhưng mình ko có biết các thuật toán đó ra sao cả.
Bác nào biết chỉ giùm hoặc chỉ link để mình tự tìm hiểu. Mình lên mạng vào google kiếm mờ cả mắt mà chẳng thấy gì hết.
Rất cảm ơn bạn Legend_VN đã nhiệt thành giúp đỡ, mình sẽ nghiên cứu cách làm của bạn.

download tài liệu tại đây http://vnoug.org/viewtopic.php?f=7&t=331

gianhut
30-05-2008, 09:01
IF sapchienthang=1 THEN tancong;
IF baodong<>0 THEN cheat;

hahaha

daoson_hai
03-06-2008, 08:36
download tài liệu tại đây http://vnoug.org/viewtopic.php?f=7&t=331

Link của bạn bị hỏng rồi. Mình phải lên google mới tìm được cuốn sách mà bạn chỉ. Hóa ra là thuật toán của nó nằm trong phần Tìm Kiếm Heuritic(hình như viết ko chuẩn)à?

thoqbk
03-06-2008, 09:58
Mình đã từng viết trò này.

Đây là 1 số cái cậu cần quan tâm khi làm:

0.Trò chơi min-max.
1.Thuật toán cắt tỉa alpha-beta
2.Khoanh vùng tìm kiếm.
3.Định giá bàn cờ.
4.Một số thứ khác nữa...

ntrongdangkhoa
13-06-2008, 12:51
Code caro chạy trên dos

#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>
#include "dos.h"
int longpro=0;
void Writesxy(int x,int y,char *ch,int col)
{
gotoxy(x,y);
textcolor(col);
cprintf("%s",ch);
}
int DemChanThu(int A[10][100],int m,int n,int x,int y,int nx,int ny,int flag)
{
int demchan=1;
int tx=x+nx,ty=y+ny;
while ((A[ty][tx]!=flag || A[ty][tx]==0)&& ty>=0 && ty<n && tx>=0 && tx<m)
{
demchan++;
tx=tx+nx;
ty=ty+ny;
}
tx=x-nx,ty=y-ny;
while ((A[ty][tx]!=flag || A[ty][tx]==0)&& ty>=0 && ty<n && tx>=0 && tx<m)
{
demchan++;
tx=tx-nx;
ty=ty-ny;
}
return demchan;
}
int DemChanCong(int A[10][100],int m,int n,int x,int y,int nx,int ny,int flag)
{
int demchan=1;
int tx=x+nx,ty=y+ny;
while ((A[ty][tx]==flag || A[ty][tx]==0)&& ty>=0 && ty<n && tx>=0 && tx<m)
{
demchan++;
tx=tx+nx;
ty=ty+ny;
}
tx=x-nx,ty=y-ny;
while ((A[ty][tx]==flag || A[ty][tx]==0)&& ty>=0 && ty<n && tx>=0 && tx<m)
{
demchan++;
tx=tx-nx;
ty=ty-ny;
}
return demchan;
}
int DemThu(int A[10][100],int m,int n,int x,int y,int nx,int ny,int flag)
{
int dem=0;
int tx=x+nx,ty=y+ny;
while (A[ty][tx]!=flag && A[ty][tx]!=0 && ty>=0 && ty<n && tx>=0 && tx<m)
{
dem=dem+2;
tx=tx+nx;
ty=ty+ny;
}
if (A[ty][tx]==0 && ty>=0 && ty<n && tx>=0 && tx<m)
{
dem=dem+1;
}
tx=x-nx,ty=y-ny;
while (A[ty][tx]!=flag && A[ty][tx]!=0 && ty>=0 && ty<n && tx>=0 && tx<m)
{
dem=dem+2;
tx=tx-nx;
ty=ty-ny;
}
if (A[ty][tx]==0 && ty>=0 && ty<n && tx>=0 && tx<m)
{
dem=dem+1;
}
return dem;
}
int DemCong(int A[100][100],int m,int n,int x,int y,int nx,int ny,int flag)
{
int dem=0;
int tx=x+nx,ty=y+ny;
while (A[ty][tx]==flag && ty>=0 && ty<n && tx>=0 && tx<m)
{
dem=dem+2;
tx=tx+nx;
ty=ty+ny;
}
if (A[ty][tx]==0 && ty>=0 && ty<n && tx>=0 && tx<m)
{
dem=dem+1;
}
tx=x-nx,ty=y-ny;
while (A[ty][tx]==flag && ty>=0 && ty<n && tx>=0 && tx<m)
{
dem=dem+2;
tx=tx-nx;
ty=ty-ny;
}
if (A[ty][tx]==0 && ty>=0 && ty<n && tx>=0 && tx<m)
{
dem=dem+1;
}
return dem;
}
float mu4(int n)
{
long T=1;
for (int i=1;i<n/2;i++)
{
T=T*4;
}
if (n%2!=0)
{
T=T*2;
}
return T;
}
float ValueThu(int A[100][100],int m,int n,int x,int y,int flag)
{
int dem;
long S;
dem=DemThu(A,m,n,x,y, 1, 0,flag);
if (DemChanThu(A,m,n,x,y, 1, 0,flag)<5)
{
dem=dem-4;
}
if (dem>=9)
{
dem=dem+4;
}
S=mu4(dem);
dem=DemThu(A,m,n,x,y, 0, 1,flag);
if (DemChanThu(A,m,n,x,y, 0, 1,flag)<5)
{
dem=dem-4;
}
if (dem>=9)
{
dem=dem+4;
}
S=S+mu4(dem);
dem=DemThu(A,m,n,x,y, 1, 1,flag);
if (DemChanThu(A,m,n,x,y, 1, 1,flag)<5)
{
dem=dem-4;
}
if (dem>=9)
{
dem=dem+4;
}
S=S+mu4(dem);
dem=DemThu(A,m,n,x,y, 1,-1,flag);
if (DemChanThu(A,m,n,x,y, 1, -1,flag)<5)
{
dem=dem-4;
}
if (dem>=9)
{
dem=dem+4;
}
S=S+mu4(dem);
return S;
}
float ValueCong(int A[100][100],int m,int n,int x,int y,int flag)
{
int dem;
long S;
dem=DemCong(A,m,n,x,y, 1, 0,flag);
if (DemChanCong(A,m,n,x,y, 1, 0,flag)<25)
{
dem=dem-4;
}
if (dem>=9)
{
dem=dem+4;
}
S=mu4(dem);
dem=DemCong(A,m,n,x,y, 0, 1,flag);
if (DemChanCong(A,m,n,x,y, 0, 1,flag)<5)
{
dem=dem-4;
}
if (dem>=9)
{
dem=dem+4;
}
S=S+mu4(dem);
dem=DemCong(A,m,n,x,y, 1, 1,flag);
if (DemChanCong(A,m,n,x,y, 1, 1,flag)<5)
{
dem=dem-4;
}
if (dem>=9)
{
dem=dem+4;
}
S=S+mu4(dem);
dem=DemCong(A,m,n,x,y, 1,-1,flag);
if (DemChanCong(A,m,n,x,y, 1, -1,flag)<5)
{
dem=dem-4;
}
if (dem>=9)
{
dem=dem+4;
}
S=S+mu4(dem);
return S;
}
int CapDo(long A)
{
return int (log(A)/log(4));
}
void ComPlay(int A[100][100],int m,int n,int flag)
{
if (longpro==0)
{
int cx,cy;
int i,j;
int a=0;
for (i=0;i<n;i++)
{
for (j=0;j<m;j++)
{
if (A[i][j]!=0)
{
if (j>m/2)
cx=j-1;
else
cx=j+1;
if (i>n/2)
cy=i-1;
else
cy=i+1;
A[cy][cx]=flag;
longpro=1;
a=1;
break;
}
if (a==1)
{
break;
}
}
}
if (a==0)
{
A[n/2-1][m/2-1]=flag;
longpro=1;
}
}
else
{
int Cx,Cy;
int i,j;
unsigned long Cv,Ctv;
for (i=0;i<n;i++)
{
for (j=0;j<m;j++)
{
if (A[i][j]==0)
{
Cx=j;
Cy=i;
Cv=ValueCong(A,m,n,j,i,flag);
Ctv=ValueThu(A,m,n,j,i,flag);
break;
}
}
}
int Tx,Ty;
unsigned long Tv,Tcv;
for (i=0;i<n;i++)
{
for (j=0;j<m;j++)
{
if (A[i][j]==0)
{
Tx=j;Ty=i;
Tv=ValueThu(A,m,n,j,i,flag);
Tcv=ValueCong(A,m,n,j,i,flag);
break;
}
}
}
for (i=0;i<n;i++)
{
for (j=0;j<m;j++)
{
if (A[i][j]==0)
{
unsigned long Nc=ValueCong(A,m,n,j,i,flag);
unsigned long Ntv=ValueThu(A,m,n,j,i,flag);
if(( CapDo(Cv)==CapDo(Nc) && CapDo(Ctv)<CapDo(Ntv) )||(Cv<Nc))
{
Cv=Nc;
Cx=j;
Cy=i;
Ctv=Ntv;
}
unsigned long Nt=ValueThu(A,m,n,j,i,flag);
unsigned long Ncv=ValueThu(A,m,n,j,i,flag);
if(( CapDo(Tv)==CapDo(Nt) && CapDo(Tcv)<CapDo(Ncv) )||(Tv<Nt))
{
Tv=Nt;
Tx=j;
Ty=i;
Tcv=Ncv;
}
}
}
}
if (CapDo(Tv)>CapDo(Cv))
{
A[Ty][Tx]=flag;
}
else
{
A[Cy][Cx]=flag;
}
}
}
void BanCo(int m,int n)
{
Writesxy(1,1,"Ú",7);
Writesxy(m*2+2,1,"Ä¿",7);
Writesxy(1,n+2,"À",7);
Writesxy(m*2+2,n+2,"ÄÙ",7);
for (int i=1;i<=m;i++)
{
Writesxy(i*2,1,"ÄÂ",7);
}
for (i=1;i<=m;i++)
{
Writesxy(i*2,n+2,"ÄÁ",7);
}
for (i=2;i<=n+1;i++)
{
Writesxy(1,i,"Ã",7);
}
for (i=2;i<=n+1;i++)
{
Writesxy(2*m+2,i,"Ä´",7);
}
for (i=1;i<=m;i++)
{
for (int j=2;j<=n+1;j++)
{
Writesxy(i*2,j,"ÄÅ",7);
}
}
gotoxy(1+m/2*2,1+(n/2));
}
/*
ÚÄÂÄ¿
ÃÄÅÄ´
ÀÄÁÄÙ
*/
void ManPlay(int A[100][100],int m,int n,int& x,int& y,char& ch)
{
do
{
gotoxy(x*2+3,y+2);
ch=getch();
switch (ch)
{
case 72:if (y>0) { y--;} break;
case
80:if (y<n-1) { y++;} break;
case 75:if (x>0) { x--;} break;
case 77:if (x<m-1) { x++;} break;
case 27:exit(0);break;
}
}
while ((ch!=32 || A[y][x]!=0) && ch!=27);
A[y][x]=2;
}
void ConCo(int A[100][100],int m,int n)
{
for (int i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
if (A[i][j]==1)
{
Writesxy(j*2+3,i+2,"O",12);
}
if (A[i][j]==2)
{
Writesxy(j*2+3,i+2,"X",14);
}
}
}
}
void main()
{
int m=30,n=20;
int x=m/2;
int y=n/2;
char ch;
int A[100][100]={0};
textmode(3);
clrscr();
BanCo(m,n);
do
{
ManPlay(A,m,n,x,y,ch);
ConCo(A,m,n);
ComPlay(A,m,n,1);
ConCo(A,m,n);
}
while (ch!=27);
getch();
}

daoson_hai
24-06-2008, 09:15
Hay quá, đúng thứ mình đang cần, cảm ơn bác ntrongdangkhoa rất nhiều. Tiện đây mình cũng xin hỏi các bác 1 câu rằng :
2.Khoanh vùng tìm kiếm.
3.Định giá bàn cờ.
Là cái gì? nó có ý nghĩa như thế nào?

onglaodanhca
17-07-2008, 11:02
Cái này nó liên quan nhiều đến AI, vì vậy bạn nên đọc một số tài liệu liên quan.

thanhsoros
17-07-2008, 11:06
Nhớ lại cái trò đánh cờ caro mà đánh mãi mới thắng được 1 ván nếu gặp phải game do cao thủ lập trình biên soạn lol

tri_cuong
17-07-2008, 16:59
Bạn nên xem giải thuật, sau đó xem trí tuệ nhân tạo là được rồi

SpectreHaunt
17-07-2008, 18:15
Về thuật toán thì hầu như các trò chơi kiểu này đều dùng Alpha-Beta (còn gọi là Min/Max). Khó nhất là viết hàm định giá thế nào và các cải tiến đặc thù. Đây chính là điểm khác biệt giữa các chương trình chơi cờ caro.

root1984
21-09-2008, 15:18
2.Khoanh vùng tìm kiếm.

Là tìm kiếm nước đi của COM trong một số nước giới hạn nhằm làm giảm độ phúc tạp của thuật toán. Giúp tìm kiếm nhanh hơn:

VD: trong cờ caro thì chỉ cần khoanh vùng +3 -> +5 xung quanh các nước đang đi

3.Định giá bàn cờ.
Easy
VD Trong cờ tướng một con Tốt khi qua sông sẽ được lượng giá cao hơn(nôm na là giá trị của nó cao hơn). Việc định giá bàn cờ là đánh giá tổng thể điểm của bàn cờ sau một nước đi.

ngoc47th
15-10-2008, 11:33
Bạn nào có thuật toán của bài toán "Tổ chức hội nghị" có thể share cho mình với.
Đề của bài đó là: "Có m đại biểu, n buổi hội nghị chuyên đề. mỗi đại biểu có thể đăng ký từ 1 đến n buổi hội nghị. Tổ chức các buổi hội nghị sao cho được nhiều tham gia nhất và số buổi là ít nhất. Một buổi hội nghị phải có hơn 10%người đăng ký thì mới được tổ chức."
Các bạn hãy cố gắng giúp mình với. Mình phải nộp bài gấp cho thầy. Cảm ơn các bạn.
Địa chỉ của mình là: ngoc47th@gmail.com

duydaichampion
02-12-2008, 00:35
cảm ơn ban ntrongdangkhoa rat nhiều

hacker_pool
05-05-2010, 18:36
Có bạn nào có thuật toán đánh cờ caro giữa người - máy, máy - máy, người - người (một trong 3 cái cũng dc) ko?

Nếu có code viết = aglets thì càng tốt :)

Thanks

tad1243567
09-10-2011, 18:16
Bac ntrongdanghoa oi, bác nói lên y tưởng sơ sơ của thuật toan+ chức năng các hàm, chứ bác để code ko, đọc mỏi cả mắt mà ko hiểu gi hết.

ebookfinder
09-10-2011, 20:48
objective = alpha*lợi_thế + (1-alpha)*bất_thế --> max

lợi_thế và bất_thế được giải bằng branched_and_bound starting at length=3; estimated and approximated using search and heuristic methods.