黑白棋(aphabeta剪枝算法的应用)带界面

人工智能课上学了一些搜索算法以及最近学了对弈学在棋类中的应用,认识到了alpha-beta剪枝算法,实现一个简单的黑白棋的程序。源码
链接:http://pan.baidu.com/s/1i5K41z3 密码:6i5z
《黑白棋(aphabeta剪枝算法的应用)带界面》
黑白棋:
又叫翻转棋(Reversi)、奥赛罗棋(Othello)、苹果棋或反棋(Anti reversi)。黑白棋在西方和日本很流行。游戏通过相互翻转对方的棋子,最后以棋盘上谁的棋子多来判断胜负。它的游戏规则简单,因此上手很容易,但是它的变化又非常复杂。
黑白棋百度百科
黑白棋维基百科
我的黑白棋为了简单改成6*6的,关于6*6的黑白棋网上有个在线可以用我的黑白棋玩一玩由于考虑到运行时间,所以就max->min->max->min往下搜四层,当然想要搜索层数更多更智能咯
对于应用在黑白棋的算法其实还有许多,比如决策树,BP神经网之类的算法,好多。
然后关于我用到的alpha-beta剪枝算法,不是很熟悉的可以看下别人写的这个文档,里面的伪代码写的很好,而且还讲到了优化方法,比如置换表,历史表,以及学习算法的应用。链接:http://pan.baidu.com/s/1kVCsNGF 密码:kn5x
附两个重要的函数:
(1)棋翻转函数:


void CBlackWhiteDlg::TransChess(int ChessType, int y, int x)
{
    if (y<0 || x<0)return;
    int k, m, l, n;//计数器
    if (ChessType == WhiteChess)
    {
        for (k = x + 1; k < 6; k++)//水平向右方向
        {
            if (ChessBoard[y][k] == NoChess)
                break;
            if (ChessBoard[y][k] == WhiteChess)
            {
                for (l = x + 1; l < k; l++)
                {

                    SubChess(BlackChess, y, l, BlackPosition);
                    DrawChess(WhiteChess, y, l);
                }
                break;
            }

        }
        for (k = x - 1; k >= 0; k--)//水平向左方向
        {
            if (ChessBoard[y][k] == NoChess)
                break;
            if (ChessBoard[y][k] == WhiteChess)
            {
                for (l = k + 1; l < x; l++)
                {

                    SubChess(BlackChess, y, l, BlackPosition);
                    DrawChess(WhiteChess, y, l);
                }
                break;
            }

        }
        for (k = y + 1; k < 6; k++)//垂直向下方向
        {
            if (ChessBoard[k][x] == NoChess)
                break;
            if (ChessBoard[k][x] == WhiteChess)
            {
                for (l = y + 1; l < k; l++)
                {

                    SubChess(BlackChess, l, x, BlackPosition);
                    DrawChess(WhiteChess, l, x);
                }
                break;
            }

        }
        for (k = y - 1; k >= 0; k--)//垂直向上方向
        {
            if (ChessBoard[k][x] == NoChess)
                break;
            if (ChessBoard[k][x] == WhiteChess)
            {
                for (l = k + 1; l < y; l++)
                {

                    SubChess(BlackChess, l, x, BlackPosition);
                    DrawChess(WhiteChess, l, x);
                }
                break;
            }

        }

        for (k = x - 1, m = y - 1; k >= 0 && m >= 0; k--, m--)//左上角方向
        {
            if (ChessBoard[m][k] == NoChess)
                break;
            if (ChessBoard[m][k] == WhiteChess)
            {
                for (l = x - 1, n = y - 1; l>k&&n>m; l--, n--)
                {

                    SubChess(BlackChess, n, l, BlackPosition);
                    DrawChess(WhiteChess, n, l);
                }
                break;
            }
        }

        for (k = x + 1, m = y + 1; k<6 && m <6; k++, m++)//右下角方向
        {
            if (ChessBoard[m][k] == NoChess)
                break;
            if (ChessBoard[m][k] == WhiteChess)
            {
                for (l = x + 1, n = y + 1; l<k&&n<m; l++, n++)
                {

                    SubChess(BlackChess, n, l, BlackPosition);
                    DrawChess(WhiteChess, n, l);
                }
                break;
            }
        }
        for (k = x - 1, m = y + 1; k >= 0 && m <6; k--, m++)//左下角方向
        {
            if (ChessBoard[m][k] == NoChess)
                break;
            if (ChessBoard[m][k] == WhiteChess)
            {
                for (l = x - 1, n = y + 1; l>k&&n<m; l--, n++)
                {

                    SubChess(BlackChess, n, l, BlackPosition);
                    DrawChess(WhiteChess, n, l);
                }
                break;
            }
        }

        for (k = x + 1, m = y - 1; k<6 && m >= 0; k++, m--)//右上角方向
        {
            if (ChessBoard[m][k] == NoChess)
                break;
            if (ChessBoard[m][k] == WhiteChess)
            {
                for (l = x + 1, n = y - 1; l<k&&n>m; l++, n--)
                {

                    SubChess(BlackChess, n, l, BlackPosition);
                    DrawChess(WhiteChess, n, l);
                }
                break;
            }
        }

    }

    if (ChessType == BlackChess)
    {
        for (k = x + 1; k < 6; k++)//水平向右方向
        {
            if (ChessBoard[y][k] == NoChess)
                break;
            if (ChessBoard[y][k] == BlackChess)
            {
                for (l = x + 1; l < k; l++)
                {

                    SubChess(WhiteChess, y, l, WhitePosition);
                    DrawChess(BlackChess, y, l);
                }
                break;
            }

        }
        for (k = x - 1; k >= 0; k--)//水平向左方向
        {
            if (ChessBoard[y][k] == NoChess)
                break;
            if (ChessBoard[y][k] == BlackChess)
            {
                for (l = k + 1; l < x; l++)
                {

                    SubChess(WhiteChess, y, l, WhitePosition);
                    DrawChess(BlackChess, y, l);
                }
                break;
            }

        }
        for (k = y + 1; k < 6; k++)//垂直向下方向
        {
            if (ChessBoard[k][x] == NoChess)
                break;
            if (ChessBoard[k][x] == BlackChess)
            {
                for (l = y + 1; l < k; l++)
                {

                    SubChess(WhiteChess, l, x, WhitePosition);
                    DrawChess(BlackChess, l, x);
                }
                break;
            }

        }
        for (k = y - 1; k >= 0; k--)//垂直向上方向
        {
            if (ChessBoard[k][x] == NoChess)
                break;
            if (ChessBoard[k][x] == BlackChess)
            {
                for (l = k + 1; l < y; l++)
                {

                    SubChess(WhiteChess, l, x, WhitePosition);
                    DrawChess(BlackChess, l, x);
                }
                break;
            }

        }

        for (k = x - 1, m = y - 1; k >= 0 && m >= 0; k--, m--)//左上角方向
        {
            if (ChessBoard[m][k] == NoChess)
                break;
            if (ChessBoard[m][k] == BlackChess)
            {
                for (l = x - 1, n = y - 1; l>k&&n>m; l--, n--)
                {

                    SubChess(WhiteChess, n, l, WhitePosition);
                    DrawChess(BlackChess, n, l);
                }
                break;
            }
        }

        for (k = x + 1, m = y + 1; k<6 && m <6; k++, m++)//右下角方向
        {
            if (ChessBoard[m][k] == NoChess)
                break;
            if (ChessBoard[m][k] == BlackChess)
            {
                for (l = x + 1, n = y + 1; l<k&&n<m; l++, n++)
                {

                    SubChess(WhiteChess, n, l, WhitePosition);
                    DrawChess(BlackChess, n, l);
                }
                break;
            }
        }
        for (k = x - 1, m = y + 1; k >= 0 && m <6; k--, m++)//左下角方向
        {
            if (ChessBoard[m][k] == NoChess)
                break;
            if (ChessBoard[m][k] == BlackChess)
            {
                for (l = x - 1, n = y + 1; l>k&&n<m; l--, n++)
                {

                    SubChess(WhiteChess, n, l, WhitePosition);
                    DrawChess(BlackChess, n, l);
                }
                break;
            }
        }

        for (k = x + 1, m = y - 1; k<6 && m >= 0; k++, m--)//右上角方向
        {
            if (ChessBoard[m][k] == NoChess)
                break;
            if (ChessBoard[m][k] == BlackChess)
            {
                for (l = x + 1, n = y - 1; l<k&&n>m; l++, n--)
                {

                    SubChess(WhiteChess, n, l, WhitePosition);
                    DrawChess(BlackChess, n, l);
                }
                break;
            }
        }

    }
}

(2)alpha-beta剪枝


///alpha-beta搜索,max,min,max,min各两层 
void CBlackWhiteDlg::Computer(int *stepRow, int *stepColumn)
{
    int QuanMin[PositionMax];
    int alfa = QuanZhiMax, belta = QuanZhiMin;

    int i, j, l, m;//计数器
    int V;//评估值
    int ParentRow, ParentColumn, ChildRow, ChildColumn, Child_2_Row, Child_2_Column;
    int Child_3_Row, Child_3_Column;
    CChessPosition ParentWhiteCanGo[PositionMax];
    CChessPosition ChildBlackCanGo[PositionMax];
    CChessPosition Child_2_WhiteCanGo[PositionMax];
    CChessPosition Child_3_BlackCanGo[PositionMax];
    CChessPosition Child_4_WhiteCanGo[PositionMax];

    ListCanGo(WhiteChess, ParentWhiteCanGo);
    *stepRow = ParentWhiteCanGo[1].Row;
    *stepColumn = ParentWhiteCanGo[1].Column;
    //初始化


    for (i = 0; i <= ParentWhiteCanGo[0].ChessNum; i++)
    {
        QuanMin[i] = QuanZhiMin;
    }
    for (i = 1; i <= ParentWhiteCanGo[0].ChessNum; i++)
    {
        BOOL CutFlag = FALSE;

        CChessPosition ParentWhiteTrans[PositionMax];
        ParentRow = ParentWhiteCanGo[i].Row;
        ParentColumn = ParentWhiteCanGo[i].Column;
        AddChess(WhiteChess, ParentRow, ParentColumn, WhitePosition);//白棋位置上增加一个座标
        ChessBoard[ParentRow][ParentColumn] = WhiteChess;
        TransChessPredict(WhiteChess, ParentRow, ParentColumn, ParentWhiteTrans);
        ListCanGo(BlackChess, ChildBlackCanGo);
        for (j = 1; j <= ChildBlackCanGo[0].ChessNum; j++)
        {
            CChessPosition ChildBlackTrans[PositionMax];

            ChildRow = ChildBlackCanGo[j].Row;
            ChildColumn = ChildBlackCanGo[j].Column;
            AddChess(BlackChess, ChildRow, ChildColumn, BlackPosition);
            ChessBoard[ChildRow][ChildColumn] = BlackChess;
            TransChessPredict(BlackChess, ChildRow, ChildColumn, ChildBlackTrans);
            ListCanGo(WhiteChess, Child_2_WhiteCanGo);

            ///还原
            for (l = 1; l <= Child_2_WhiteCanGo[0].ChessNum; l++)
            {

                CChessPosition Child_2_WhiteTrans[PositionMax];


                Child_2_Row = Child_2_WhiteCanGo[l].Row;
                Child_2_Column = Child_2_WhiteCanGo[l].Column;

                AddChess(WhiteChess, Child_2_Row, Child_2_Column, WhitePosition);
                ChessBoard[Child_2_Row][Child_2_Column] = WhiteChess;
                TransChessPredict(WhiteChess, Child_2_Row, Child_2_Column, Child_2_WhiteTrans);
                ListCanGo(BlackChess, Child_3_BlackCanGo);

                for (m = 1; m <= Child_3_BlackCanGo[0].ChessNum; m++)
                {
                    CChessPosition Child_3_BlackTrans[PositionMax];

                    Child_3_Row = Child_3_BlackCanGo[m].Row;
                    Child_3_Column = Child_3_BlackCanGo[m].Column;
                    AddChess(BlackChess, Child_3_Row, Child_3_Column, BlackPosition);
                    ChessBoard[Child_3_Row][Child_3_Column] = BlackChess;
                    TransChessPredict(BlackChess, Child_3_Row, Child_3_Column, Child_3_BlackTrans);
                    ListCanGo(WhiteChess, Child_4_WhiteCanGo);
                    V = QuanZhi(WhitePosition, BlackPosition) + Child_4_WhiteCanGo[0].ChessNum;

                    //还原
                    BackStep(BlackChess, Child_3_Row, Child_3_Column, Child_3_BlackTrans);
                    belta = V;
                    if (V < QuanMin[i])
                        QuanMin[i] = V;

                    //发生裁剪
                    if ((i != 1) && (belta<alfa))
                    {
                        CutFlag = TRUE;
                        break;
                    }


                }

                BackStep(WhiteChess, Child_2_Row, Child_2_Column, Child_2_WhiteTrans);
                //发生裁剪
                if (CutFlag)
                    break;

            }


            BackStep(BlackChess, ChildRow, ChildColumn, ChildBlackTrans);
            //发生裁剪
            if (CutFlag)
                break;

        }
        //还原 
        BackStep(WhiteChess, ParentRow, ParentColumn, ParentWhiteTrans);
        ////如果没有发生裁剪,则保留座标
        if (!CutFlag&&QuanMin[i] != QuanZhiMin)
        {

            alfa = QuanMin[i];
            *stepRow = ParentRow;
            *stepColumn = ParentColumn;

        }



    }

    DrawChess(WhiteChess, *stepRow, *stepColumn);
    TransChess(WhiteChess, *stepRow, *stepColumn);
}

又是很粗暴,具体的其他细节可以看源码里面的BlackWhiteDlg.cpp

点赞