?? xiaqi.c
字號:
//習題1.5
//
// 前提己方先下子,呵呵
#include "stdio.h"
#include "string.h"
int b[9][9]={0}; //t[number of state][number of zuobiao]
double Vtrain[9]={0.0};
//初始化線性函數
//x0自己有威脅的獨立棋子數目,x1對方,
//x2自己有威脅的連子數目,x3對方
//w[5]系數
double w[5]={6,6,6,6,6}; //初始化系數,這里的系數初始化為6
int x[4]={0,0,0,0};
main()
{
void Performance();
int Critic();
void Generalizer();
int Xiaqi();
int Count=0; //表征訓練次數
double rate=0.0;
int i,j;
int p;
for (Count=5;Count<=500;Count=Count+5)
{
rate=0;
for (j=0;j<5;j++)
w[j]=6;
for (i=0;i<Count;i++)
{
Performance();
p=Critic();
Generalizer(p);
//printf("%d-->",i);
//for (j=0;j<5;j++)
// printf("%lf ",w[j]);
rate=rate+Xiaqi();
//printf("\n");
}
rate=rate/Count;
printf("%lf\n",rate);
}
}
#include "math.h"
void Performance()
{
int getX(); //獲得x值
int i,j,m;
int qizi=1; //1 or -1
int best=0;
double v,Vmax;
//初始化棋盤
for (i=0;i<9;i++)
for (j=0;j<9;j++)
b[i][j]=0;
for (i=0;i<9;i++)
{
Vmax=-99999; //這里設置了一個"足夠小"的Value
if (i!=0) //新的一步需要先copy前一步的棋局
for (m=0;m<9;m++)
b[i][m]=b[i-1][m];
for (j=0;j<9;j++)
{
if (b[i][j]==0)
{
b[i][j]=qizi;
if (getX(b[i],qizi)==1)
{
v=w[0]*x[0]+w[1]*x[1]+w[2]*x[2]+w[3]*x[3]+w[4];
if (Vmax<v)
{
Vmax=v;
best=j;
}
}
else
{
b[i][j]=qizi;
goto end;
}
b[i][j]=0;
}
}
b[i][best]=qizi;
if (qizi==1)
qizi=-1;
else
qizi=1;
}
end: qizi=0;
}
//int型的函數,返回可供給訓練的棋局數量-1,即訓練樣例個數-1
int Critic()
{
int i,p;
int getX();
for (i=0;i<9;i++)
Vtrain[i]=0.0;
for (i=0;i<4;i++)
{
p=2*i;
if (getX(b[p+1],1)==1)
{
if (getX(b[p+2],1)==1)
Vtrain[p]=w[0]*x[0]+w[1]*x[1]+w[2]*x[2]+w[3]*x[3]+w[4];
else
{
Vtrain[p]=getX(b[p+2],1);
return (i);
}
}
else
{
Vtrain[p]=getX(b[p+2],1);
return(i);
}
}
return (i-1);
}
//countB獲得訓練樣例的(個數-1)
void Generalizer(int countB)
{
int getX(); //獲得x值
int i,j;
int xx;
double V1,V2=0,Vx;
for (i=0;i<=countB;i++)
{
V1=Vtrain[2*i];
xx=getX(b[2*i],1);
V2=w[0]*x[0]+w[1]*x[1]+w[2]*x[2]+w[3]*x[3]+w[4];
Vx=V1-V2;
for (j=0;j<4;j++)
{
//printf("%d:%lf->",j,w[j]);
w[j]=w[j]+0.05*Vx*x[j]; //這里序數取作0.05
//printf("%lf\n",w[j]);
}
}
}
//獲得棋盤當前狀態,即更新x[]
int getX(int bb[9],int n)
{
int sum;
int i;
int result=1;
for (i=0;i<4;i++)
x[i]=0;
for (i=0;i<=6;i=i+3)
{
sum=bb[i]+bb[i+1]+bb[i+2];
if (sum==3)
result=100;
else if (sum==-3)
result=-100;
else if (sum==2)
x[2]++;
else if (sum==-2)
x[3]++;
else if (sum==1 && (bb[i]==0 || bb[i+1]==0))
x[0]++;
else if (sum==-1 && (bb[i]==0 || bb[i+1]==0))
x[1]++;
}
for (i=0;i<=2;i++)
{
sum=bb[i]+bb[i+3]+bb[i+6];
if (sum==3)
result=100;
else if (sum==-3)
result=-100;
else if (sum==2)
x[2]++;
else if (sum==-2)
x[3]++;
else if (sum==1 && (bb[i]==0 || bb[i+3]==0))
x[0]++;
else if (sum==-1 && (bb[i]==0 || bb[i+3]==0))
x[1]++;
}
sum=bb[0]+bb[4]+bb[8];
if (sum==3)
result=100;
else if (sum==-3)
result=-100;
else if (sum==2)
x[2]++;
else if (sum==-2)
x[3]++;
else if (sum==1 && (bb[0]==0 || bb[4]==0))
x[0]++;
else if (sum==-1 && (bb[0]==0 || bb[4]==0))
x[1]++;
sum=bb[2]+bb[4]+bb[6];
if (sum==3)
result=100;
else if (sum==-3)
result=-100;
else if (sum==2)
x[2]++;
else if (sum==-2)
x[3]++;
else if (sum==1 && (bb[2]==0 || bb[4]==0))
x[0]++;
else if (sum==-1 && (bb[2]==0 || bb[4]==0))
x[1]++;
if (n==-1)
{
sum=x[0]; x[0]=x[1]; x[1]=sum;
sum=x[2]; x[2]=x[3]; x[3]=sum;
}
return (result);
}
//和固定函數wp[]對弈的過程
#include "math.h"
int Xiaqi()
{
int getX(); //獲得x值
int i,j,m;
int qizi=1; //1 or -1
int best=0;
double v,Vmax;
//double wp[5]={5.538570,-15.946661,19.276676,-19.876809,6.000000};
double wp[5]={6,-5,9,2,66}; //定義的固定函數,對弈的對手
//初始化棋盤
for (i=0;i<9;i++)
for (j=0;j<9;j++)
b[i][j]=0;
for (i=0;i<9;i++) //最多可能進行九步
{
Vmax=-99999;
if (i!=0)
for (m=0;m<9;m++)
b[i][m]=b[i-1][m];
for (j=0;j<9;j++) //一步最多要搜索9個位置
{
if (b[i][j]==0)
{
b[i][j]=qizi;
if (getX(b[i],qizi)==1)
{
if (qizi==1)
v=w[0]*x[0]+w[1]*x[1]+w[2]*x[2]+w[3]*x[3]+w[4];
else
v=wp[0]*x[0]+wp[1]*x[1]+wp[2]*x[2]+wp[3]*x[3]+wp[4];
if (Vmax<v)
{
Vmax=v;
best=j;
}
}
else
{
b[i][j]=qizi;
if (qizi==1)
{
//printf("You win!\n");
return (1);
}
else
{
//printf("You lose!\n");
return (0);
}
}
b[i][j]=0;
}
}
b[i][best]=qizi;
if (qizi==1)
qizi=-1;
else
qizi=1;
}
//printf(":-)!\n");
return (0);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -