博弈和α、β裁剪

考虑棋类游戏作为一个人机博弈模型,采用机器学习中对于棋盘学习的方法,给每个棋盘位置的好坏进行一个打分,几个概念:

极大极小策略:能使计算机获胜的位置,打分为1,平局是0,计算机负是-1,显然计算机要尽量让每一步的得分极大,人要让每一步的得分极小

终端位置:若某个位置能直接决定结果,那么这个位置叫做终端位置,若一个位置不是终端位置,那么该位置的值通过递归假设双方的最优棋步决定

后继位置:P的后继位置是从P走一步棋可以到达的位置,若在某个位置P计算机要开始走,那么递归计算所有后继位置的值,计算机选择最大值的一步走棋

代码如下:

/* 博弈 */
/* 计算机选择一步 */
void FindCompMove(BoardType Board, int * BestMove, int *Value)
{
    int Dc, i, Response;

    /* 若棋盘满了,那么是平局 */
    if (FullBoard(Board))
        *Value = Draw;
    /* 若走一步计算机直接赢,那么标记计算机赢 */
    else if (ImmediateCompWin(Board, BestMove))
        *Value = CompWin;
    else
    {
        /* 赋初始值为最小值,递归后续的所有格子,找更大的值用来更新 */
        *Value = CompLoss;
        for (i = 1; i <= 9; i++)
        {
            if (IsEmpty(Board, i))
            {
                /* 这3行是回溯的核心,先占位,递归,然后释放资源 */
                Place(Board, i, Comp);
                FindHumanMove(Board, &Dc, $Response);
                Unplace(Board, i);

                if (Response > *Value)
                {
                    *Value = Response;
                    *BestMove = i;
                }
            }
        }
    }
}

/* 人选择一步 */
void FindHumanMove(BoardType Board, int *BestMove, int *Value)
{
    int Dc, i, Response;
    if (FullBoard(Board))
        *Value = Draw;
    else if (ImmdiateHumanWin(Board, BestMove))
        *Value = CompLoss;
    else
    {
        *Value = CompWin;
        for (i = 1; i <= 9; i++)
        {
            if (IsEmpty(Board, i))
            {
                Place(Board, i);
                FindHumanMove(Board, &Dc, &Response);
                Unplace(Board, i);

                if (Response < *Value)
                {
                    *Value = Response;
                    *BestMove = i;
                }
            }
        }
    }
}

α、β裁剪:

是对博弈树的改进,如下图:

在这个博弈树中,第一层MAX表示在子节点中选择最大的,依次类推,在第一层的递归中,第一个儿子节点求值为44,递归第二个儿子,在第二个儿子内部递归调用其所有儿子,得到第一个儿子节点值为40,这个时候,它剩下的儿子都不需要处理了,因为它在所有儿子中选择最小的,最终选出来的值一定比40小,而根节点选择儿子中最大的,第一个儿子已经有44了,这个时候第二个儿子比40小,意味着它一定不会被选择,这就是α裁剪,另一种不需要处理MIN的对称情况,就是β裁剪,合称α、β裁剪,代码如下:

/* α、β裁剪 */
void FindCompMove(BoardType Board, int *BestMove, int *Value, int Alpha, int Beta)
{
    int Dc, i, Response;
    if (FullBoard(Board))
        *Value = Draw;
    else if (ImmediateCompWin(Board, BestMove))
        *Value = CompWin;
    else
    {
        *Value = Alpha;
        for (i = 1; i <= 9; i++)
        {
            Place(Board, i);
            FindHumanMove(Board, &Dc, &Response, *Value, Beta);
            Unplace(Board, i);

            if (Response > *Value)
            {
                *Value = Response;
                *BestMove = i;
            }
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值