你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 图形图象处理与游戏编程
用Java实现五子棋人机博弈(四)
 

然后,要用它来复制当前棋局。具体代码如下:

    private void copyChessboard(int[][] chess){

     //复制当前棋盘

     for(int i=0;i<Model.MaxlineY;i++)

         for(int j=0;j<Model.MaxlineX;j++)

            curChess[i][j]=chess[i][j];

}

第二步:记录当前落子点。具体代码如下:

private int ci,cj; //纪录当前落子的位置

    private void copychessLocation(int i,int j){

     //纪录当前落子的位置

     ci=i;cj=j;

}

第三步:记录下棋方ID。具体代码如下:

private int nameID;//纪录当前下棋方

最后,定义一个函数,把它们全部包含进来,具体代码如下:

    public void loadInfo(int[][] chess,int i,int j){

     //下载相关信息到算法类

     copyChessboard(chess);

     copychessLocation(i,j);

     nameID=2;

    }

至此,棋局的基本信息已经有了,下一步要利用它来实现电脑智能。

3)实现电脑智能。

上文已经提到,这是本文的重点。希望读者细细看之。

①定义权值(玩家黑子)

例:黑白白空50  //黑代表黑子,即玩家落的子;白代表白子,即电脑落的子;空代表空子,即在该位置上还未落子;黑白白空代表棋盘上某条线上连续4点所构成的一种格局;50代表在棋盘上某条线上构成上述格局时应赋予的权值

黑白白空       50

空白白空       100

黑白白白空     500

空白白白空     1000

黑白白白白空   5000

空白白白白空   10000

白白白白白     100000

代码实现如下:

    //定义suanfa类的权值常量

    private final int Q2O=50;

    private final int Q2=100;

    private final int Q3O=500;

    private final int Q3=1000;

    private final int Q4O=5000;

    private final int Q4=10000;

    private final int Q5=100000;

 

②计算权值

权值定义好后,就可以用来计算棋盘上各个点的权值了。经分析,棋盘上某个点的权值有四部分构成,分别是此点在水平方向上的权值,此点在垂直方向上的权值,此点在45度方向上的权值,此点在135度方向上的权值。所以,必须先求出这四个方向上的权值,然后再将它们进行相加便得到这个点的权值了。

代码实现如下:

    private int getQuan(int i,int j){ //i,j记录当前假定的落子点

     //求当前位置的权值

        int q=0;

        q+=getQuan0(i,j); //得到水平方向上的权值,下面类似

        q+=getQuan90(i,j);

        q+=getQuan135(i,j);

        q+=getQuan45(i,j);

        return q;

    }

可以看到,getQuan(i,j)有两个形参ij,它们是用来记录棋盘上某点的位置,即curChess[i][j]

大概思路已经理出来了,下面将具体讨论getQuan0(i,j)的求法。其它三个函数getQuan90(i,j)getQuan135(i,j)getQuan45(i,j)getQuan0(i,j)大同小异,请读者自分析之。

getQuan0(i,j)是求i,j所对应的棋盘上的点在水平方向上的权值的。这里我们要考虑两种情况,一种是尽快让电脑赢,在①已经定义好了权值,只要从i,j点开始,在水平方向上向两边探索,就可以求得相应的权值qS;另一种情况是防止玩家尽快取胜。按一般思维考虑,还需要定义一些权值。稍稍思索,完全可以用在①定义的权值,只是我们需要调换角度,站在玩家的立场上考虑就可以了。也就是说,把①里的黑白子互换,其中一黑子是电脑的假定落子,权值不变。把按这种方式求出的权值作为电脑堵棋的权值qF。最后,把这两种权值相加,便得到该点在水平方向上的权值(q=qS+qF)。具体代码如下:

    private int getQuan0(int i,int j){

      //水平权值

     int samechessNumS=0;//相同棋子的个数

     int samechessNumF=0;

     int blankNumS=0;//空子的个数

     int blankNumF=0;

     int q=0,qS=0,qF=0;

    

     int[][] ij0=new int[2][2];//计算权值用的

     ij0[0][0]=ij0[0][1]=i;

     ij0[1][0]=ij0[1][1]=j;  

   

     samechessNumS=getsamechessNum0(ij0,1); //得到白子数目

     if(ij0[1][0]>=0)

         if(curChess[ij0[0][0]][ij0[1][0]]==0)

             blankNumS++;

     if(ij0[1][1]<Model.MaxlineX)

         if(curChess[ij0[0][1]][ij0[1][1]]==0)

             blankNumS++;

     qS=getQuanpart(samechessNumS,blankNumS); //得到速胜权值

     ij0[0][0]=ij0[0][1]=i;

     ij0[1][0]=ij0[1][1]=j;  

     samechessNumF=getsamechessNum0(ij0,2); //得到黑子数目

     if(ij0[1][0]>=0)

         if(curChess[ij0[0][0]][ij0[1][0]]==0)

             blankNumF++;

     if(ij0[1][1]<Model.MaxlineX)

         if(curChess[ij0[0][1]][ij0[1][1]]==0)

             blankNumF++;

     qF=getQuanpart(samechessNumF,blankNumF); //得到堵敌权值

     q=qS+qF;

     return q;

}

  推荐精品文章

·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089