前天发表的一片《人民币大写转化函数(C#版)》的随笔效果还不错,在大家的热烈讨论中我也学到了不少知识。现在把我最近刚完成的一个五子棋程序共享给大家希望能同样达到抛砖引玉的效果。
该五子棋程序是参照2004年11期《开发高手》上的五子棋开发专题改进的。现在的1.0.0版只有人机对战的部分。整个程序共有4个主要的类:Chessboard类用来绘制棋盘,控制下棋等操作;Computer类主要是电脑人工智能方面;Rule类用来判断输赢的规则方面;Stone类用来绘制棋子。
基本思路:电脑下子时先检查未落子点的权值,在权值最高的位置下棋。如果要提高人工智能,可用探索回溯的方法多搜索几步,在比较那点权值最高。
检查m,n点的权值的方法:
关于如何让电脑下的棋子闪动几秒的方法我还没有想到,希望大家帮忙想想。如有Bug也请大家多多指出。
不多说了大家下源码自己看吧:FiveStones(v1.0.0).rar
版本:FiveStones(v1.0.1).rar(将最后一步棋上标示了小三角)
该五子棋程序是参照2004年11期《开发高手》上的五子棋开发专题改进的。现在的1.0.0版只有人机对战的部分。整个程序共有4个主要的类:Chessboard类用来绘制棋盘,控制下棋等操作;Computer类主要是电脑人工智能方面;Rule类用来判断输赢的规则方面;Stone类用来绘制棋子。
基本思路:电脑下子时先检查未落子点的权值,在权值最高的位置下棋。如果要提高人工智能,可用探索回溯的方法多搜索几步,在比较那点权值最高。
检查m,n点的权值的方法:
private int Check(int m, int n, int[,] arrchessboard)
{
int qz = 0;
//找自己的取胜点(1000)
int w1 = 100000;
//找对手的取胜点(80)
int w2 = 50000;
//找自己的三个相连的点(60)
int w3 = 10000;
//找对手的三个相连的点(40)
int w4 = 5000;
//找自己的两个相连的点(20)
int w5 = 1000;
//找对手的两个相连的点(10)
int w6 = 500;
//找自己的相连的点(5)
int w7 = 100;
//找对方的相连的点(5)
int w8 = 50;
//找自己的失败点
int w9 = -1000000;
int[] arrf = new int[4];
//如果该位置下我方的子
if (mflag)
{
//我方黑子
arrchessboard[m,n] = 0;
}
else
{
//我方白子
arrchessboard[m,n] = 1;
}
arrf[0] = Rule.Xnum(m,n,arrchessboard);
arrf[1] = Rule.Ynum(m,n,arrchessboard);
arrf[2] = Rule.YXnum(m,n,arrchessboard);
arrf[3] = Rule.XYnum(m,n,arrchessboard);
//中心点权值加1
if (m==7 && n==7){qz+=1;}
for (int i=0;i<4;i++)
{
if (Math.Abs(arrf[i]) == 5)
{
qz += w1;
}
if (arrf[i] == 4)
{
qz += w3;
}
if (arrf[i] == 3)
{
qz += w5;
}
if (arrf[i] == 2)
{
qz += w7;
}
//如果我方为黑棋,还要检查失败点
if (mflag)
{
if (Rule.IsFail(arrf, arrchessboard[m,n])>0)
{
qz += w9;
}
}
}
//如果该位置下对方的子
if (mflag)
{
//对方白子
arrchessboard[m,n] = 1;
}
else
{
//对方黑子
arrchessboard[m,n] = 0;
}
arrf[0] = Rule.Xnum(m,n,arrchessboard);
arrf[1] = Rule.Ynum(m,n,arrchessboard);
arrf[2] = Rule.YXnum(m,n,arrchessboard);
arrf[3] = Rule.XYnum(m,n,arrchessboard);
for (int i=0;i<4;i++)
{
if (Math.Abs(arrf[i]) == 5)
{
qz += w2;
}
if (arrf[i] == 4)
{
qz += w4;
}
if (arrf[i] == 3)
{
qz += w6;
}
if (arrf[i] == 2)
{
qz += w8;
}
}
//数组好像是引用传递,探测完后恢复到默认值
arrchessboard[m,n] = 2;
return qz;
}
{
int qz = 0;
//找自己的取胜点(1000)
int w1 = 100000;
//找对手的取胜点(80)
int w2 = 50000;
//找自己的三个相连的点(60)
int w3 = 10000;
//找对手的三个相连的点(40)
int w4 = 5000;
//找自己的两个相连的点(20)
int w5 = 1000;
//找对手的两个相连的点(10)
int w6 = 500;
//找自己的相连的点(5)
int w7 = 100;
//找对方的相连的点(5)
int w8 = 50;
//找自己的失败点
int w9 = -1000000;
int[] arrf = new int[4];
//如果该位置下我方的子
if (mflag)
{
//我方黑子
arrchessboard[m,n] = 0;
}
else
{
//我方白子
arrchessboard[m,n] = 1;
}
arrf[0] = Rule.Xnum(m,n,arrchessboard);
arrf[1] = Rule.Ynum(m,n,arrchessboard);
arrf[2] = Rule.YXnum(m,n,arrchessboard);
arrf[3] = Rule.XYnum(m,n,arrchessboard);
//中心点权值加1
if (m==7 && n==7){qz+=1;}
for (int i=0;i<4;i++)
{
if (Math.Abs(arrf[i]) == 5)
{
qz += w1;
}
if (arrf[i] == 4)
{
qz += w3;
}
if (arrf[i] == 3)
{
qz += w5;
}
if (arrf[i] == 2)
{
qz += w7;
}
//如果我方为黑棋,还要检查失败点
if (mflag)
{
if (Rule.IsFail(arrf, arrchessboard[m,n])>0)
{
qz += w9;
}
}
}
//如果该位置下对方的子
if (mflag)
{
//对方白子
arrchessboard[m,n] = 1;
}
else
{
//对方黑子
arrchessboard[m,n] = 0;
}
arrf[0] = Rule.Xnum(m,n,arrchessboard);
arrf[1] = Rule.Ynum(m,n,arrchessboard);
arrf[2] = Rule.YXnum(m,n,arrchessboard);
arrf[3] = Rule.XYnum(m,n,arrchessboard);
for (int i=0;i<4;i++)
{
if (Math.Abs(arrf[i]) == 5)
{
qz += w2;
}
if (arrf[i] == 4)
{
qz += w4;
}
if (arrf[i] == 3)
{
qz += w6;
}
if (arrf[i] == 2)
{
qz += w8;
}
}
//数组好像是引用传递,探测完后恢复到默认值
arrchessboard[m,n] = 2;
return qz;
}
关于如何让电脑下的棋子闪动几秒的方法我还没有想到,希望大家帮忙想想。如有Bug也请大家多多指出。
不多说了大家下源码自己看吧:FiveStones(v1.0.0).rar
版本:FiveStones(v1.0.1).rar(将最后一步棋上标示了小三角)
==========================================
作者:二十四画生
转载请注明来源于博客园——二十四画生的Blog,并保留有原文链接。