创意棋类游戏
·once·
·
·
个人记录
//转自:https://www.luogu.com.cn/paste/kjqt4pja
//作者:https://www.luogu.com.cn/user/85994
/*
All right!
*/
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#include<windows.h>
#include<conio.h>
using namespace std;
#define maxn 10
#define GREY 8*17
#define WHITE 255
#define BLACK 0
#define YELLOW 14*17
#define accept_ 1.1
#define space 1
#define black 2
#define white 3
#define side 0
#define MaxCal 300000000
#define relaxTime 12
#define out_of_board -1290687
#define notSet -128370
#define RIGHT 10
#define WRONG -10
#define RESET_TIMES 5
const int fx_1[4]={0,0,1,-1};
const int fx_2[4]={1,-1,0,0};
int D=0;
int calNum=0;//the number of calculation in order to relax the CP
int warn=0,turn=0;
void color(int a)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
}
string num_str(int n)
{
int m=n;
char s[20];
char ss[20];
int i=0,j=0;
if (n<0)// 处理负数
m=-m,j=1,ss[0]='-';
while(m>0)
s[i++]=m%10+'0',m/=10;
s[i]='\0';
--i;
while (i >= 0)
{
ss[j++]=s[i--];
}
ss[j]='\0';
return ss;
}
void HideCursor(void)
{
HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(handle,&CursorInfo);//获取控制台光标信息
CursorInfo.bVisible=false; //隐藏控制台光标
SetConsoleCursorInfo(handle,&CursorInfo);//设置控制台光标状态
}
void SetXY(int x, int y) {
COORD pos={x,y};
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄
SetConsoleCursorPosition(hOut,pos);//两个参数分别是指定哪个窗体,具体位置
}
inline double drand(void)
{
double d=1.0,ans=0.0;
for(int i=0;i<15;i++)
{
d*=0.5;
if(rand()%2) ans+=d;
}
return ans;
}
inline bool gl(double a)
{
if(a>=drand()) return true;
else return false;
}
inline char* str_ch(string str)
{
char* strc=new char[strlen(str.c_str())+1];
strcpy(strc,str.c_str());
return strc;
}
void Game(void);
class MAP
{
public:
int d[maxn][maxn];
bool is_white;
int White,Black;
void Set(void)
{
is_white=true,White=0,Black=0;
for(int i=0;i<maxn;i++)
for(int j=0;j<maxn;j++)
d[i][j]=space;
for(int i=0;i<maxn;i++)
d[i][0]=side,d[i][maxn-1]=side,d[maxn-1][i]=side,d[0][i]=side;
}//set a board with nothing
void draw_(void)
{
for(int i=0;i<maxn;i++)
{
for(int j=0;j<maxn;j++)
{
color(15);
if(d[i][j]==space)
{
SetXY(i+1,j+1),color(GREY),cout<<' ';
continue;
}
if(d[i][j]==white)
{
SetXY(i+1,j+1),color(WHITE),cout<<' ';
continue;
}
if(d[i][j]==black)
{
SetXY(i+1,j+1),color(BLACK),cout<<' ';
continue;
}
if(d[i][j]==side)
{
SetXY(i+1,j+1),color(YELLOW),cout<<' ';
continue;
}
}
color(15),cout<<endl;
}
}//just draw a MAP
void count_(void)
{
White=0,Black=0;
for(int i=1;i<maxn-1;i++)
for(int j=1;j<maxn-1;j++)
if(d[i][j]==white) ++White;
else if(d[i][j]==black) ++Black;
}//count the MAP,must do this after you change it
void turn(int a,int b)
{
if(d[a][b]==white) d[a][b]=black;
else d[a][b]=white;
}//turn a piece
int Change(int a,int b)
{
if(a>=maxn-1||a<1||b>=maxn-1||b<1) return WRONG;
if(d[a][b]!=space) return WRONG;
if(is_white) d[a][b]=white;
else d[a][b]=black;
is_white=!is_white;
bool t[4]={1,1,1,1};
for(int i=1;i<maxn;i++)
{
for(int j=0;j<4;j++)
if(t[j])
if(d[a+fx_1[j]*i][b+fx_2[j]*i]!=space&&d[a+fx_1[j]*i][b+fx_2[j]*i]!=side) turn(a+fx_1[j]*i,b+fx_2[j]*i);
else t[j]=false;
}
return RIGHT;
}//lay at (a,b)
void from(MAP map_)
{
for(int i=0;i<maxn;i++)
for(int j=0;j<maxn;j++)
d[i][j]=map_.d[i][j];
}//copy a MAP
int Space_() {return (maxn-2)*(maxn-2)-White-Black;}//the space number
};
string name;
void rule(void)
{
system("cls");
color(10);
printf("In the rolling chess,if you put a piece at everywhere in a ");
puts("chess board which is 8*8,it will turn all the pieces on the same line with it and next to it into a different color.");
puts("White first,and then is black's turn.Finally,who has more pieces of his own color will win.");
puts("You can play with your friend at a CP ,play with the CP or even just watching CPs' play.");
puts("'W','A','S','D' to move a piece and ' ' to lay it");
puts("When you are using Adviser,'q' to get the advice and 'l' to know your now point");
puts("To avoid copying and peace,black give white a piece.");
color(15),puts("MADE BY efX!");
printf("Now the AI is right,never do foolish things\n");
system("pause");
Game();
}
#define MIX 2
#define RATE 1
#define POINT 0
class MCTS
{
private:
double judge(MAP mp)
{
if(mp.Space_()<=7)
if(mp.White>mp.Black)
return 1.0;
else return -1.0;
return (double)(mp.White>mp.Black)*0.125+(mp.White>mp.Black?1.0:-1.0);
}
public:
double now_point;
int work_depth;
int workNum;//how many borads
int advX,advY;//advise to go
int type;
bool is_white;
/*double randSearch(MAP mp,int restDepth)
{
mp.count_();
if(restDepth==0||mp.Space_()<=1) return judge(mp);
int place[(maxn-2)*(maxn-2)][2],q=0,r=0;
for(int i=1;i<maxn-1;i++)
for(int j=1;j<maxn-1;j++)
if(mp.d[i][j]==space)
place[q][0]=i,place[q][1]=j,++q;
r=rand()%q;
mp.Change(place[r][0],place[r][1]);
return randSearch(mp,restDepth-1);
}
void MIX_WORK(MAP mp)
{
mp.count_();
if(mp.Space_()%2) mp.is_white=true;
else mp.is_white=false;
int point[(maxn-2)*(maxn-2)][3];
double count_point[(maxn-2)*(maxn-2)];
memset(count_point,0,sizeof(count_point));
int q=0,r=0;
//0.X;1.Y;2.count times
double realPoint[(maxn-2)*(maxn-2)],nowBest;
for(int i=0;i<(maxn-2)*(maxn-2);i++)
realPoint[i]=0.0;
for(int i=0;i<(maxn-2)*(maxn-2);i++)
for(int j=0;j<3;j++)
point[i][j]=0;//first set
for(int i=1;i<maxn-1;i++)
for(int j=1;j<maxn-1;j++)
if(mp.d[i][j]==space)
point[q][0]=i,point[q][1]=j,++q;
for(int i=0;i<workNum;i++)
{
r=rand()%q;
mp.Change(point[r][0],point[r][1]);
count_point[r]+=randSearch(mp,work_depth),++point[r][2];
mp.Change(point[r][0],point[r][1]);
mp.d[point[r][0]][point[r][1]]=space;
}//search the point
for(int i=0;i<q;++i)
realPoint[i]=count_point[i]/(double)(point[i][2]);
//get the mean
nowBest=realPoint[0],r=0;
if(mp.is_white)
for(int i=1;i<q;++i)
if(realPoint[i]>nowBest)
r=i,nowBest=realPoint[i];
else for(int i=1;i<q;++i)
if(realPoint[i]<nowBest)
r=i,nowBest=realPoint[i];
advX=point[r][0],advY=point[r][1];
now_point=realPoint[r];
return;
}//maybe finish*/
int RandSearch(MAP mp,int restDepth)
{
mp.count_();
if(restDepth==0||mp.Space_()<=1)
{
if(type==POINT)
return (mp.White-mp.Black);
if(type==RATE)
if(mp.White>mp.Black)
return 1;
else return 0;
if(type==MIX)
{
if(is_white)
if(mp.White>mp.Black)
return (((mp.White-mp.Black)+1)>>1);
else return ((mp.White-mp.Black)>>1)-1;
else
if(mp.White>mp.Black)
return ((mp.White-mp.Black)>>1)+1;
else return (((mp.White-mp.Black)-1)>>1);
}
}
int place[(maxn-2)*(maxn-2)][2],q=0,r=0;
for(int i=1;i<maxn-1;i++)
for(int j=1;j<maxn-1;j++)
if(mp.d[i][j]==space)
place[q][0]=i,place[q][1]=j,++q;
r=rand()%q;
mp.Change(place[r][0],place[r][1]);
return RandSearch(mp,restDepth-1);
}
void Work(MAP mp)
{
mp.count_();
if(mp.Space_()%2) mp.is_white=true,is_white=true;
else mp.is_white=false,is_white=false;
int point[(maxn-2)*(maxn-2)][4];
int q=0,r=0;
//0.X;1.Y;2.point;3.count times
double realPoint[(maxn-2)*(maxn-2)],nowBest;
for(int i=0;i<(maxn-2)*(maxn-2);i++)
realPoint[i]=0.0;
for(int i=0;i<(maxn-2)*(maxn-2);i++)
for(int j=0;j<4;j++)
point[i][j]=0;//first set
for(int i=1;i<maxn-1;i++)
for(int j=1;j<maxn-1;j++)
if(mp.d[i][j]==space)
point[q][0]=i,point[q][1]=j,++q;
for(int i=0;i<workNum;i++)
{
r=rand()%q;
mp.Change(point[r][0],point[r][1]);
point[r][2]+=RandSearch(mp,work_depth),++point[r][3];
mp.Change(point[r][0],point[r][1]);
mp.d[point[r][0]][point[r][1]]=space;
}//search the point
for(int i=0;i<q;++i)
realPoint[i]=(double)(point[i][2])/(double)(point[i][3]);
//get the mean
nowBest=realPoint[0],r=0;
if(mp.is_white)
for(int i=1;i<q;++i)
if(realPoint[i]>nowBest)
r=i,nowBest=realPoint[i];
else for(int i=1;i<q;++i)
if(realPoint[i]<nowBest)
r=i,nowBest=realPoint[i];
advX=point[r][0],advY=point[r][1];
now_point=realPoint[r];
return;
}
};
int type=0,st=0;
void Adviser(MAP &mp,MCTS mct,ofstream &fout)
{
system("cls");
printf("1.with POINT\n2.with RATE\n3.with MIX");
char ch=getch();
if(ch=='1') mct.type=POINT;
else if(ch=='2') mct.type=RATE;
else mct.type=MIX;
system("cls");
for(int i=st;i<(maxn-2)*(maxn-2)-1;i++)
{
char ch='\0';
int X=(maxn-2)/2,Y=(maxn-2)/2;
SetXY((maxn)/2-2,0),printf("turn %d",i+1);
double P[(maxn-2)*(maxn-2)],best;
int allow[(maxn-2)*(maxn-2)][2]={0},ac=0;
int p[(maxn-2)*(maxn-2)][2];
int q=0;
for(int t=1;t<maxn-1;++t)
for(int j=1;j<maxn-1;++j)
if(mp.d[t][j]==space)
p[q][0]=t,p[q][1]=j,++q;//every tile's point
while(ch!=' ')
{
memset(allow,0,sizeof(allow));
for(int j=0;j<(maxn-2)*(maxn-2);j++) P[j]=0.0;
mp.draw_();
color(15),SetXY(X+1,Y+1);
if(mp.d[X][Y]==space)
if(!mp.is_white) color(BLACK+10),putchar('X');
else color(BLACK-7),putchar('X');
else color(14),putchar('O');
ch=getch();
if(ch==' '&&mp.d[X][Y]!=space) ch='\0';
if(ch=='w'||ch=='W') {Y=((Y-1>0)?Y-1:maxn-2);continue;}
if(ch=='s'||ch=='S') {Y=((Y+1<maxn-1)?Y+1:1);continue;}
if(ch=='a'||ch=='A') {X=((X-1>0)?X-1:maxn-2);continue;}
if(ch=='d'||ch=='D') {X=((X+1<maxn-1)?X+1:1);continue;}
if(ch=='q'||ch=='Q')
{
MAP m;
m.from(mp);
m.count_();
int work_depth=mct.work_depth;
//mct.work_depth/=m.Space_();
ac=0;
for(int t=0;t<q;t++)
{
m.Change(p[t][0],p[t][1]);
if(i%2) m.d[p[t][0]][p[t][1]]=black;
else m.d[p[t][0]][p[t][1]]=white;
mct.Work(m);
//color(15);
//SetXY(0,maxn+6);
m.Change(p[t][0],p[t][1]);
m.d[p[t][0]][p[t][1]]=space;
//P[t]*=0.999;//slowly forget
P[t]+=mct.now_point;
}
best=P[0],X=p[0][0],Y=p[0][1];
for(int t=1;t<q;t++)
{
if(i%2&&P[t]<best)
{
X=p[t][0],Y=p[t][1],best=P[t];
continue;
}
if(i%2==0&&P[t]>best)
{
X=p[t][0],Y=p[t][1],best=P[t];
continue;
}
if(i%2&&P[t]*accept_<best)
{
allow[ac][0]=p[t][0],allow[ac][1]=p[t][1],ac++;
continue;
}
if(i%2==0&&P[t]>best*accept_)
{
allow[ac][0]=p[t][0],allow[ac][1]=p[t][1],ac++;
continue;
}
}
mct.work_depth=work_depth;
mp.draw_();
color(15);
SetXY(X+1,Y+1),color(13*17),putchar(' ');
for(int j=0;j<ac;j++)
{
color(15),SetXY(allow[j][0]+1,allow[j][1]+1);
color(10*17),putchar(' ');
}
getch();
//mct.Work(mp);
//SetXY(mct.advX+1,mct.advY+1),color(12*17),putchar(' '),getch();
}
if((ch=='l'||ch=='L')&&mp.d[X][Y]==space)
{
if(i%2) mp.d[X][Y]=black;
else mp.d[X][Y]=white;
mp.Change(X,Y);
mct.Work(mp);
color(15);
SetXY(0,maxn+6);
printf("this move's point: ");
SetXY(18,maxn+6),printf("%0.3f",mct.now_point);
mp.Change(X,Y),mp.d[X][Y]=space;
// system("pause");
}
}
mp.Change(X,Y);
if(i%2) mp.d[X][Y]=black;
else mp.d[X][Y]=white;
color(15);
mct.Work(mp);
if(mct.type==POINT)
SetXY(0,maxn+1),printf("now point: ");
else SetXY(0,maxn+1),printf("now rate : ");
SetXY(10,maxn+1),printf("%0.3f",mct.now_point);
mp.count_();
SetXY(2,maxn+7),printf("White: ");
SetXY(2,maxn+8),printf("Black: ");
SetXY(8,maxn+7),printf("%d",mp.White);
SetXY(8,maxn+8),printf("%d",mp.Black);
fout<<X<<' '<<Y<<endl;
SetXY(maxn/2-3,maxn+3),printf("X,Y:%d,%d",X,Y);
// mp=next_(mp,dos);
}
/*if(mp.White-mp.Black>0) printf("The White win %d pieces!\n",mp.White-mp.Black);
else if(mp.White-mp.Black<0) printf("The Black win %d pieces!\n",mp.Black-mp.White);
else cout<<"Nobody win!\n";
system("pause");*/
}
void Fight(MAP &mp,MCTS mct,ofstream &fout)
{
bool point_print=0;
printf("1.with POINT\n2.with RATE\n");
char ch=getch();
if(ch=='1') mct.type=POINT;
else if(ch=='2') mct.type=RATE;
else mct.type=MIX;
system("cls");
printf("1.White 2.Black(you are):");
cin>>D;
system("cls");
printf("Would AI print the point out(Y or N)");
ch=getch();
if(ch=='y'||ch=='Y') point_print=1;
system("cls");
for(int i=st;i<(maxn-2)*(maxn-2)-1;i++)
{
char ch='\0';
int X=(maxn-2)/2,Y=(maxn-2)/2;
SetXY((maxn)/2-2,0),printf("turn %d",i+1),mp.draw_();
if((D==1&&i%2==0)||(D!=1&&i%2))
{
SetXY((maxn)/2-2,0),printf("turn %d",i+1);
while(ch!=' ')
{
mp.draw_();
color(15),SetXY(X+1,Y+1);
if(mp.d[X][Y]==space)
if(!mp.is_white) color(BLACK+10),putchar('X');
else color(BLACK-7),putchar('X');
else color(14),putchar('O');
ch=getch();
if(ch==' '&&mp.d[X][Y]!=space) ch='\0';
if(ch=='w'||ch=='W') Y=((Y-1>0)?Y-1:maxn-2);
if(ch=='s'||ch=='S') Y=((Y+1<maxn-1)?Y+1:1);
if(ch=='a'||ch=='A') X=((X-1>0)?X-1:maxn-2);
if(ch=='d'||ch=='D') X=((X+1<maxn-1)?X+1:1);
}
}
else
{
MAP m;
m.from(mp);
int work_depth=mct.work_depth;
int workNum=mct.workNum;
//mct.work_depth/=mp.Space_(),mct.work_depth+=rand()%60;
double P[(maxn-2)*(maxn-2)],best,p_=0.0;
int p[(maxn-2)*(maxn-2)][2];
int q=0;
for(int t=1;t<maxn-1;++t)
for(int j=1;j<maxn-1;++j)
if(mp.d[t][j]==space)
p[q][0]=t,p[q][1]=j,++q;
mct.work_depth>>=RESET_TIMES;
for(int t=0;t<q;t++)
{
m.Change(p[t][0],p[t][1]);
if(i%2) m.d[p[t][0]][p[t][1]]=black;
else m.d[p[t][0]][p[t][1]]=white;
mct.Work(m);
//color(15);
//SetXY(0,maxn+6);
m.Change(p[t][0],p[t][1]);
m.d[p[t][0]][p[t][1]]=space;
P[t]+=mct.now_point;
p_+=P[t];
}
p_/=(double)q;
for(int T=0;T<RESET_TIMES;T++)
{
mct.work_depth<<=1;
for(int t=0;t<q;t++)
if(P[t]>=p_)
{
m.Change(p[t][0],p[t][1]);
if(i%2) m.d[p[t][0]][p[t][1]]=black;
else m.d[p[t][0]][p[t][1]]=white;
mct.Work(m);
//color(15);
//SetXY(0,maxn+6);
m.Change(p[t][0],p[t][1]);
m.d[p[t][0]][p[t][1]]=space;
P[t]+=mct.now_point;
}
p_=0.0;for(int t=0;t<q;t++) p_+=P[t];p_/=(double)q;
}
best=P[0],X=p[0][0],Y=p[0][1];
for(int t=1;t<q;t++)
{
if(i%2&&P[t]<best)
X=p[t][0],Y=p[t][1],best=P[t];
if(i%2==0&&P[t]>best)
X=p[t][0],Y=p[t][1],best=P[t];
}
mct.workNum=workNum;
mct.work_depth=work_depth;
mct.workNum+=256;
}
if(i%10==0) /*mct.work_depth++,*/mct.workNum+=256;
if(i==40) ++mct.work_depth;
mp.Change(X,Y);
if(i%2) mp.d[X][Y]=black;
else mp.d[X][Y]=white;
mp.draw_();
mp.count_();
color(15);
if(point_print)
{
if(mct.type==POINT)
SetXY(0,maxn+1),printf("now point: ");
else SetXY(0,maxn+1),printf("now rate : ");
SetXY(10,maxn+1),printf("%0.3f",mct.now_point);
}
SetXY(2,maxn+7),printf("White: "),SetXY(2,maxn+8),printf("Black: ");
SetXY(8,maxn+7),printf("%d",mp.White),SetXY(8,maxn+8),printf("%d",mp.Black);
SetXY(maxn/2-3,maxn+3),printf("X,Y:%d,%d",X,Y);
fout<<X<<' '<<Y<<endl;
}
/*if(mp.White-mp.Black>0) printf("The White win %d pieces!\n",mp.White-mp.Black);
else if(mp.White-mp.Black<0) printf("The Black win %d pieces!\n",mp.Black-mp.White);
else cout<<"Nobody win!\n";
system("pause");*/
}
void Watch(MAP &mp,MCTS mct,ofstream &fout)
{
system("cls");
int KIND[2];
char ch='0';
printf("1.AI_White is POINT\n2.AI_White is RATE\n3.AI_White is MIX\n");
ch=getch();
if(ch=='1') KIND[0]=POINT;
else if(ch=='2') KIND[0]=RATE;
else KIND[0]=MIX;
system("cls");
printf("1.AI_Black is POINT\n2.AI_Black is RATE\n3.AI_Black is MIX\n");
ch=getch();
if(ch=='1') KIND[1]=POINT;
else if(ch=='2') KIND[1]=RATE;
else KIND[1]=MIX;
system("cls");
mp.count_();
int moved[maxn-2][maxn-2];
memset(moved,0,sizeof(moved));
for(int i=st;i<(maxn-2)*(maxn-2)-1;i++)
{
mct.type=KIND[i%2];
SetXY((maxn)/2-2,0),printf("turn %d",i+1);
SetXY((maxn)/2-3,maxn+2),printf("space ");
SetXY((maxn)/2+3,maxn+2),printf("%d",mp.Space_());
mp.draw_();
char ch='\0';
int X=(maxn-2)/2,Y=(maxn-2)/2;
int work_depth=mct.work_depth;
//if(i%2) mct.work_depth/=mp.Space_(),mct.work_depth+=rand()%60;
double P[(maxn-2)*(maxn-2)],best;
double countNum=0.0;
int p[(maxn-2)*(maxn-2)][2];
int q=0,r;
for(int t=1;t<maxn-1;t++)
for(int j=1;j<maxn-1;j++)
{
if(moved[t-1][j-1]==0)
p[q][0]=t,p[q][1]=j,q++;
}
for(int t=0;t<q;t++) P[t]=0.0;
for(int t=0;t<q;t++)
if(mp.d[p[t][0]][p[t][1]]!=space)
{
for(int j=t+1;j<q;j++)
p[j-1][0]=p[j][0],p[j-1][1]=p[j][1];
--q;
}
MAP m;
m.from(mp);
if(type==2)
{
double p_=0.0;
m.draw_();
countNum+=1.0;
mct.work_depth>>=RESET_TIMES;
for(int t=0;t<q;t++)
{
m.Change(p[t][0],p[t][1]);
if(i%2) m.d[p[t][0]][p[t][1]]=black;
else m.d[p[t][0]][p[t][1]]=white;
mct.Work(m);
//color(15);
//SetXY(0,maxn+6);
m.Change(p[t][0],p[t][1]);
m.d[p[t][0]][p[t][1]]=space;
P[t]+=mct.now_point;
p_+=P[t];
}
p_/=(double)q;
for(int T=0;T<RESET_TIMES;T++)
{
mct.work_depth<<=1;
for(int t=0;t<q;t++)
if(P[t]>=p_)
{
m.Change(p[t][0],p[t][1]);
if(i%2) m.d[p[t][0]][p[t][1]]=black;
else m.d[p[t][0]][p[t][1]]=white;
mct.Work(m);
//color(15);
//SetXY(0,maxn+6);
m.Change(p[t][0],p[t][1]);
m.d[p[t][0]][p[t][1]]=space;
P[t]+=mct.now_point;
}
p_=0.0;for(int t=0;t<q;t++) p_+=P[t];p_/=(double)q;
}
//TRUE_WORK:;
best=P[0],X=p[0][0],Y=p[0][1];
for(int t=1;t<q;t++)
{
if(i%2&&P[t]<best)
r=t,X=p[t][0],Y=p[t][1],best=P[t]/countNum;
if(i%2==0&&P[t]>best)
r=t,X=p[t][0],Y=p[t][1],best=P[t]/countNum;
}
mct.work_depth=work_depth;
color(15);
if(mct.type==POINT)
SetXY(0,maxn+1),printf("now point: ");
else if(mct.type==RATE)
SetXY(0,maxn+1),printf("now rate : ");
else
SetXY(0,maxn+1),printf("mix rate : ");
SetXY(10,maxn+1),printf("%0.3f",best);
Sleep(500+rand()%300);
}
else
while(ch!=' ')
{
m.draw_();
if(ch=='g')
{
color(10*17);
for(int t=0;t<q;t++)
SetXY(p[t][0]+1,p[t][1]+1),putchar(' ');
ch=getch(),color(15);
continue;
}
countNum+=1.0;
double p_=0.0;
mct.work_depth>>=RESET_TIMES;
for(int t=0;t<q;t++)
{
m.Change(p[t][0],p[t][1]);
if(i%2) m.d[p[t][0]][p[t][1]]=black;
else m.d[p[t][0]][p[t][1]]=white;
mct.Work(m);
//color(15);
//SetXY(0,maxn+6);
m.Change(p[t][0],p[t][1]);
m.d[p[t][0]][p[t][1]]=space;
P[t]+=mct.now_point;
p_+=P[t];
}
p_/=(double)q;
for(int T=0;T<RESET_TIMES;T++)
{
mct.work_depth<<=1;
for(int t=0;t<q;t++)
if(P[t]>=p_)
{
m.Change(p[t][0],p[t][1]);
if(i%2) m.d[p[t][0]][p[t][1]]=black;
else m.d[p[t][0]][p[t][1]]=white;
mct.Work(m);
//color(15);
//SetXY(0,maxn+6);
m.Change(p[t][0],p[t][1]);
m.d[p[t][0]][p[t][1]]=space;
P[t]+=mct.now_point;
}
p_=0.0;for(int t=0;t<q;t++) p_+=P[t];p_/=(double)q;
}
//TRUE_WORK:;
best=P[0],X=p[0][0],Y=p[0][1];
for(int t=1;t<q;t++)
{
if(i%2&&P[t]<best)
r=t,X=p[t][0],Y=p[t][1],best=P[t]/countNum;
if(i%2==0&&P[t]>best)
r=t,X=p[t][0],Y=p[t][1],best=P[t]/countNum;
}
mct.work_depth=work_depth;
color(15);
SetXY(0,maxn+1),printf("now point: ");
SetXY(10,maxn+1),printf("%0.3f",best);
ch=getch();
}
SetXY(maxn/2-3,maxn+3),printf("X,Y:%d,%d",X,Y);
if(mp.d[X][Y]!=space)
SetXY(maxn/2-4,maxn+4),printf("not space!");
moved[X-1][Y-1]=1;
mp.Change(X,Y);
if(i%2) mp.d[X][Y]=black;
else mp.d[X][Y]=white;
mp.count_();
SetXY(2,maxn+7),printf("White: ");
SetXY(2,maxn+8),printf("Black: ");
SetXY(8,maxn+7),printf("%d",mp.White);
SetXY(8,maxn+8),printf("%d",mp.Black);
fout<<X<<' '<<Y<<endl;
}
}
void MCTS_(void)
{
st=0,type=0;
ofstream fout("last.ini");
printf("1.Read\n2.Self-work(don't need to push ' ',only if you choose Watch)\n3.Common\n");
cin>>type;
MAP mp;
mp.Set();
if(type==1)
{
printf("Put in the name:");
cin>>name;
ifstream fin(str_ch(name));
if(fin.is_open())
{
int x=0,y=0;
mp.is_white=true;
while(true)
{
fin>>x;
if(x==EOF) break;
fin>>y;
if(y==EOF) break;
mp.Change(x,y),++st;
}
}
else cout<<"打开失败!\n";
}
MCTS mct;
mct.type=POINT;
system("cls");
HideCursor();
printf("Put in work depth(can reach 6!):"),cin>>D;
if(D<2) D=2;
mct.work_depth=D;
printf("Put in work borads num(1 means 1 kilo):"),cin>>D;
if(D<1) D=1;
mct.workNum=D*1024;
printf("1.Adviser 2.Fight 3.Watch\n"),cin>>D;
if(D==1) Adviser(mp,mct,fout);
if(D==2) Fight(mp,mct,fout);
if(D==3) Watch(mp,mct,fout);
mp.count_(),mp.draw_();
SetXY(0,maxn+5);
if(mp.White-mp.Black>0) printf("The White win %d pieces!\n",mp.White-mp.Black);
else if(mp.White-mp.Black<0) printf("The Black win %d pieces!\n",mp.Black-mp.White);
else cout<<"Nobody win!\n";
system("pause"),SetXY(0,maxn+6),printf(" \n");
Game();
}
void AI_test(void)
{
system("cls");
MAP mp;
MCTS mct;
printf("Put in work depth(can reach 15!):"),cin>>D;
if(D<2) D=2;
mct.work_depth=D;//mct[1].work_depth=mct[0].work_depth;
printf("Put in work borads num(1 means 1 kilo):"),cin>>D;
if(D<1) D=1;
mct.workNum=D*1024;//ct[1].workNum=mct[0].workNum;
//mct.type=POINT,mct[1].type=RATE;
int winner=0,win_num[2]={0},N=0;
int now_color[2];
int whiteWinNum=0;
int moves[(maxn-2)*(maxn-2)][2]={0};
string savingName;
printf("How many times AIs will play:"),cin>>N;
//N=min(1000,max(1,N));
printf("Saving name:"),cin>>savingName;
int fst,sec;
printf("Which AI plays(input twice):\n1.POINT\n2.RATE\n3.MIX\n");
char ch=getch();
if(ch=='1') fst=POINT;
else if(ch=='2') fst=RATE;
else fst=MIX;
ch=getch();
if(ch=='1') sec=POINT;
else if(ch=='2') sec=RATE;
else sec=MIX;
for(int i=1;i<=N;i++)
{
ofstream fout(str_ch("Record\\"+savingName+"_"+num_str(i)+".ini"));
mp.Set();
//now_color[0]=black,now_color[1]=white;
//if(rand()%2) swap(now_color[0],now_color[1]);
//system("cls");
int KIND[2];
//printf("1.AI_White is POINT\n2.AI_White is RATE\n");
if(rand()%2) KIND[0]=fst;
else KIND[0]=sec;
system("cls");
//printf("1.AI_Black is POINT\n2.AI_Black is RATE\n");
if(KIND[0]==sec) KIND[1]=fst;
else KIND[1]=sec;
//system("cls");
mp.count_();
int moved[maxn-2][maxn-2];
memset(moved,0,sizeof(moved));
for(int i=st;i<(maxn-2)*(maxn-2)-1;i++)
{
mct.type=KIND[i%2];
//SetXY((maxn)/2-2,0),printf("turn %d",i+1);
SetXY(0,0),printf("Turn up or enjoy AI's play!");
SetXY((maxn)/2-3,maxn+2),printf("space ");
SetXY((maxn)/2+3,maxn+2),printf("%d",mp.Space_());
mp.draw_();
char ch='\0';
int X=(maxn-2)/2,Y=(maxn-2)/2;
int work_depth=mct.work_depth;
mct.work_depth/=mp.Space_();mct.work_depth+=rand()%60;
double P[(maxn-2)*(maxn-2)],best;
double countNum=0.0;
int p[(maxn-2)*(maxn-2)][2];
int q=0,r;
for(int t=1;t<maxn-1;t++)
for(int j=1;j<maxn-1;j++)
{
if(moved[t-1][j-1]==0)
p[q][0]=t,p[q][1]=j,q++;
}
for(int t=0;t<q;t++) P[t]=0.0;
for(int t=0;t<q;t++)
if(mp.d[p[t][0]][p[t][1]]!=space)
{
for(int j=t+1;j<q;j++)
p[j-1][0]=p[j][0],p[j-1][1]=p[j][1];
--q;
}
MAP m;
m.from(mp);
if(1)
{
m.draw_();
countNum+=1.0;
double p_=0.0;
mct.work_depth>>=RESET_TIMES;
for(int t=0;t<q;t++)
{
m.Change(p[t][0],p[t][1]);
if(i%2) m.d[p[t][0]][p[t][1]]=black;
else m.d[p[t][0]][p[t][1]]=white;
mct.Work(m);
//color(15);
//SetXY(0,maxn+6);
m.Change(p[t][0],p[t][1]);
m.d[p[t][0]][p[t][1]]=space;
P[t]+=mct.now_point;
p_+=P[t];
}
p_/=(double)q;
for(int T=0;T<RESET_TIMES;T++)
{
mct.work_depth<<=1;
for(int t=0;t<q;t++)
if(P[t]>=p_)
{
m.Change(p[t][0],p[t][1]);
if(i%2) m.d[p[t][0]][p[t][1]]=black;
else m.d[p[t][0]][p[t][1]]=white;
mct.Work(m);
//color(15);
//SetXY(0,maxn+6);
m.Change(p[t][0],p[t][1]);
m.d[p[t][0]][p[t][1]]=space;
P[t]+=mct.now_point;
}
p_=0.0;for(int t=0;t<q;t++) p_+=P[t];p_/=(double)q;
}
//TRUE_WORK:;
best=P[0],X=p[0][0],Y=p[0][1];
for(int t=1;t<q;t++)
{
if(i%2&&P[t]<best)
r=t,X=p[t][0],Y=p[t][1],best=P[t]/countNum;
if(i%2==0&&P[t]>best)
r=t,X=p[t][0],Y=p[t][1],best=P[t]/countNum;
}
mct.work_depth=work_depth;
color(15);
if(mct.type==POINT)
SetXY(0,maxn+1),printf("now point: ");
else if(mct.type==RATE)
SetXY(0,maxn+1),printf("now rate: ");
else SetXY(0,maxn+1),printf("mix rate: ");
SetXY(10,maxn+1),printf("%0.3f",best);
Sleep(1000+rand()%500);
}
SetXY(maxn/2-3,maxn+3),printf("X,Y:%d,%d",X,Y);
if(mp.d[X][Y]!=space)
SetXY(maxn/2-4,maxn+4),printf("not space!");
moved[X-1][Y-1]=1;
mp.Change(X,Y);
if(i%2) mp.d[X][Y]=black;
else mp.d[X][Y]=white;
mp.count_();
SetXY(2,maxn+7),printf("White: ");
SetXY(2,maxn+8),printf("Black: ");
SetXY(8,maxn+7),printf("%d",mp.White);
SetXY(8,maxn+8),printf("%d",mp.Black);
fout<<X<<' '<<Y<<endl;
}
mp.count_();
if(mp.White>mp.Black)
if(KIND[0]==fst) winner=0;
else winner=1;
else if(KIND[0]==fst) winner=1;
else winner=0;
win_num[winner]++;
Sleep(50);
if(mp.White>mp.Black) fout<<"White win "<<mp.White-mp.Black<<endl,++whiteWinNum;
else fout<<"Black win "<<mp.Black-mp.White<<endl;
/*for(int t=0;t<(maxn-2)*(maxn-2)-1;t++)
fout<<moves[t][0]<<' '<<moves[t][1]<<endl;*/
Sleep(50);
}
system("cls");
if(fst==POINT) printf("POINT win:%d\n",win_num[0]);
else if(fst==RATE) printf("RATE win:%d\n",win_num[0]);
else printf("MIX win:%d\n",win_num[0]);
if(sec==POINT) printf("POINT win:%d\n",win_num[1]);
else if(sec==RATE) printf("RATE win:%d\n",win_num[1]);
else printf("MIX win:%d\n",win_num[1]);
printf("White win:%d\nBlack win:%d\n",whiteWinNum,N-whiteWinNum);
system("pause");
}
void Game(void)
{
color(15),system("cls"),srand(time(0));
printf("1.Exit\n");
color(12),printf("2.New game\n"),color(15);
printf("3.AI test\n");
cin>>D;
if(D==1) exit(0);
if(D==2) MCTS_();
if(D==3) AI_test();
Game();
}
int main(void)
{
//for(int i=0;i<=15;i++) color(15),cout<<i,color(17*i),cout<<' '<<endl;
MAP m;
m.Set(),m.d[2][2]=white,m.d[3][3]=black,m.draw_();
HideCursor();
cout<<"1.Rule\n2.Play\n";
cin>>D;
if(D==1) rule();
if(D==2) Game();
}