C++實現人機對戰圍棋(使用Leela Zero權重)-策略

策略部分就是哪個下載的權重的網絡,根據棋面黑白子狀態,輸出一些下子位置和(在該位的)勝率。

網絡輸入:

Leela Zero網絡權重輸入是:

```
1)在時間T = 0時行棋的一方
2)在時間T = -1時行棋的一方(如果T = 0則爲0)
...
8)在時間T = -7時行棋的一方(如果T <= 6則爲0)
9)時間T = 0時的另一方
10)時間T = -1時的另一方(如果T = 0則爲0)
...
16)T = -7時的另一方(如果T <= 6則爲0)
17)如果要移動黑棋則全部爲1,否則爲0
18)如果要移動白棋則全部爲1,否則爲0
```

形成18個19 x 19平面。

由黑方和白方下子序號--->生成18通道輸入數據:

void	生成18通道輸入數據(vector<int> &順序黑,
		   vector<int> &順序白,卷積層  &out)
{	
	float *d=out.data;
	int wh=out.width*out.height;


	bool b=false;//黑,白移動方
	if(順序白.size()==順序黑.size())
	{
		//黑下
		b=true;
	}

	int num=0;//步數
	int endn;//終止點
	if(b)
		endn= 順序黑.size();//終止點
	else
		endn= 順序白.size();//終止點

	//移動方8步
	while(endn>0)
	{
		if(b)
			for (int i = 0; i <endn; i++)
			{
					d[順序黑[i]]=1.0f;
			}
			
		else
			for (int i = 0; i <endn; i++)
			{
					d[順序白[i]]=1.0f;
			}
		endn--;
		num++;
		d+=wh;
		if(num==8)
			break;
	}
	while(num<8)
	{
		d+=wh;
		num++;
	}

	//非移動方8步
	num=0;//步數
	if(b)
		endn= 順序白.size();//終止點
	else
		endn= 順序黑.size();//終止點
		
	while(endn>0)
	{
		if(b)
			for (int i = 0; i <endn; i++)
			{
					d[順序白[i]]=1.0f;
			}
		else
			for (int i = 0; i <endn; i++)
			{
					d[順序黑[i]]=1.0f;
			}
		endn--;
		num++;
		d+=wh;
		if(num==8)
			break;
	}
	while(num<8)
	{
		d+=wh;
		num++;
	}

	//d+=wh*16;
	////初始黑棋下子:第17全爲1;
	if(b)
	{//黑下

		for(int i=0;i<wh;i++)
			*d++=1.f;
		//白區不變爲0
	}
	else{
		//白下
		d+=wh;//跳過黑區
		for(int i=0;i<wh;i++)
			*d++=1.f;
	}
}

模型定義:

struct go模型 //6殘差,128通道
{
	//w_input
	層數據 * conv1;//3x3卷積
	batchnorm * bn1;//正則化

	int 殘差塊數量;//6塊
	殘差塊 * 塊;

	//策略
	層數據 * p_conv1;//1x1卷積
	batchnorm * p_bn1;//正則化
	層數據 * p_ip1;//全連接卷積

	//價值
	層數據 * v_conv1;//1x1卷積
	batchnorm * v_bn1;//正則
	層數據 * v_ip1;//全連接卷積
	層數據 * v_ip2;//全連接卷積
	
	//構造函數
	go模型();

};

網絡部分和前面超分重建沒什麼區別

由策略部分輸出362個值(361(19x19) + 1手pass)

按勝率排序並返回所有的點:

void 找出最好的落點(卷積層 & d,vector<int> &前5序號)
{
	//按勝率排序並返回所有的點//只取前好的5個點不行(已有子)

	float *di=d.data;
	int size= d.width * d.height * d.depth;

	vector<float*> zp;
	int *zpIndex=new int[size];//索引數組排序用
	int *zpi=zpIndex;

	for (int i = 0; i <size; i++)
	{
			zp.push_back(di++);
			*zpi++ = i;//記錄索引
	}

	//對zp,zpIndex排序
	//快速排序;
	zsort(zp,zpIndex);//升序,勝率大的在後
	for (int i = 0; i <size; i++)
	{
			//cout<<zpIndex[size-1-i]<<","<<*(zp[size-1-i])<<endl;;
			前5序號.push_back(zpIndex[size-1-i]);//降序,勝率大的在前
	}
	//_getch();

	delete []zpIndex;  zpIndex=NULL;  

}

對戰一局圖:

 由於沒有蒙特卡羅樹搜索(因爲看不懂),官子有點弱,佔大場還是比較歷害的。

全文已結束。

下載:

人機對戰圍棋.rar

win32人機對戰圍棋(使用Leela Zero權重)程序,喜歡下圍棋的人可以一試

https://download.csdn.net/download/juebai123/11485184

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章