五子棋之极大极小

本文介绍了如何使用极大极小值搜索解决五子棋博弈问题。通过搜索树的有限深度,评估每一步棋的优劣。棋盘状态存储在二维数组中,利用getpoint()函数减少无效运算,评价函数考虑连珠数量和位置。主要函数包括判断胜负、评分、获取评分、评价、max_min和min_max等,实现电脑智能决策。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

总述:五子棋问题可以化为一个博弈问题。从开始落子到最后赢,输或和的每一步落子构成了一个解,而解空间就是一个树。解就是这个树中的一条路径,只不过这个解空间的是由电脑和人的共同选择构成的。我们可以使用极大极小值搜索来解决这个博弈问题,假设每一步人和电脑都落子在最优上。但是搜索整个树是不现实的,16*16!的指数级,所以我们只回溯3步。

将棋盘的棋子存储在Pos[16][16]的数组上
对于电脑来说每下一步棋,就是找到对自己最有利,即评价函数最大的一步,下一层根据博弈的基础,对电脑越不利即是对人越有利,即找到评价函数最小的一步。
16*16的棋盘上有一些位置是不会去落子的,我们可以通过一个getpoint()得到需要下的点,即以该点为中心,7*7的范围内有子的位置,通过这种方法可以减少运算量。
评价函数即为下完一步之后,电脑与人形成的连成三个,四个,五个等等的评分和之差。评分时,需要对棋盘进行扫描,我采用的是将二维的棋盘转化至一维的数组上,通过简单的函数就可以对横边,竖边,斜边进行计分操作。每一层之间的积分我为它们增加了一个权重,加强了下面几层的对于这一层的影响,通过这种方法可以使一些我们熟悉的定式及对于空格的判断更加准确。

主要数据结构:
pos[16][16]一个16*16的棋盘,用于记录当前情况下,棋盘的情况
~~~用于存储每一个需要用到的点,包括可进行落子的位置,当前评分最高的位置。最后进行落子时,可通过随机进行取结果。
~~存储具体的某一个点。

主要函数:
1.bool judge(int i1,int i2);判断下完当前步骤之后,是否赢得了胜利。

bool judge(int i1,int i2){
    //横排 
    for(int i=(i1-4>0?i1-4:0);i<=(i1+4>16?11:i1);i++){
        if(pos[i][i2]==pos[i+1][i2]&&pos[i+1][i2]==pos[i+2][i2]&&pos[i+2][i2]==pos[i+3][i2]&&pos[i+3][i2]==pos[i+4][i2])
            return true;
    }
    //竖排 
    for(int j=(i2-4>0?i2-4:0);j<=(i2+4>16?11:i2);j++){
        if(pos[i1][j]==pos[i1][j+1]&&pos[i1][j+1]==pos[i1][j+2]&&pos[i1][j+2]==pos[i1][j+3]&&pos[i1][j+3]==pos[i1][j+4])
            return true;
    }
    //正斜线
    int i=i1-4;
    int j=i2-4;
    while(i<0||j<0){
        i++;
        j++;
    }
    for(;i<=(i1+4>16?11:i1)&&j<=(i2+4>16?11:i2);i++,j++){
        if(pos[i][j]==pos[i+1][j+1]&&pos[i+1][j+1]==pos[i+2][j+2]&&pos[i+2][j+2]==pos[i+3][j+3]&&pos[i+3][j+3]==pos[i+4][j+4])
            return true;
    }
    //反斜线
    i=i1+4;
    j=i2-4;
    while(j<0||i>15){
        j++;
        i--;
    } 
    for(;i>=0&&j<=(i2+4>16?11:i2);i--,j++){
        if(pos[i][j]==pos[i-1][j+1]&&pos[i-1][j+1]==pos[i-2][j+2]&&pos[i-2][j+2]==pos[i-3][j+3]&&pos[i-3][j+3]==pos[i-4][j+4])
            return true;
    }
    return false;
}

2. int scoretable(int number,int empty);计分板详细情况如下
连成五个 100000
连成四个,没有端点被堵 10000
连成四个,一个端点被堵 2000
连成三个,没有端点被堵 1500(可以使连成两个没有被堵的三个比连成被堵的四个更有优势)
连成三个,一个端点被堵 100
连成两个,没有端点被堵 100
连成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值