m0_72810171 2022-12-14 13:05 采纳率: 77.8%
浏览 71
已结题

阿尔法贝塔剪枝,人工智能五子棋

电脑 总是选择第一个位置,不知道为什么,想请会剪枝算法的老哥帮我看看

#include<stdio.h>
#include<stdlib.h>
struct repo* repo1 = NULL;
int* AI(int[320][320],int X,int Y);
void PushRepo(struct repo**, int, int, int);
void ChangeRepo(struct repo*,int,int,int);
void DeleteRepo(struct repo**, int, int);
int evaluate(int pawn[320][320], int xPos, int yPos);
int Getmaxinit(int pawn[320][320], int xPos,int yPos,int alpha,int beta);
int Getmininit(int pawn[320][320], int xPos,int yPos,int alpha,int beta);

int Getmax1(int pawn[320][320], struct repo* repo, int xPos, int yPos, int alpha, int beta);
int Getmin1(int pawn[320][320], struct repo* repo, int xPos, int yPos, int alpha, int beta);
int Getmax2(int pawn[320][320], struct repo* repo, int xPos, int yPos, int alpha, int beta);
int Getmin2(int pawn[320][320], struct repo* repo, int xPos, int yPos, int alpha, int beta);

//构建一个仓库储存每层每个空位的价值,以便尽早剪枝,由于需要频繁删改,所以使用链表
struct repo {
    int xPos;
    int yPos;
    int value;
    struct repo* next;
};

int* AI(int pawn[320][320],int X,int Y)
{
    int AIresult[2];//返回值
    int left = 20;//棋盘位置
    int right = 300;
    int bottom = 300;
    int top = 20;
    int width = 20;
    int value = 0;
    int alpha = -999999;
    int beta = 10000;
    
    struct repo* current=NULL;
    

//根节点,第零层
//第一次调用AI函数时初始化仓库
    if (repo1 == NULL)
    {
        int flag = -1;
        int i = 160;
        int j = 160;
        int counttest = 1;
        if (pawn[i][j] == 0)//对空白位置打分
        {
            value = Getmaxinit(pawn, i, j, alpha, beta);
            PushRepo(&repo1, i, j, value);
            if (value > alpha)
            {
                alpha = value;
                AIresult[0] = i;
                AIresult[1] = j;
            }
        }
        for (int count = 1; count < 15; count++)//从棋盘中间开始遍历
        {
            for (int m = 0; m < count; m++)
            {
                j += (flag * width);
                counttest++;
                if (pawn[i][j] == 0)//对空白位置打分
                {
                    value = Getmaxinit(pawn, i, j, alpha, beta);
                    PushRepo(&repo1, i, j, value);
                    if (value > alpha)
                    {
                        alpha = value;
                        AIresult[0] = i;
                        AIresult[1] = j;
                    }
                }
            }
            for (int m = 0; m < count; m++)
            {
                i += (flag * width);
                
                if (pawn[i][j] == 0)//对空白位置打分
                {
                    value = Getmaxinit(pawn, i, j, alpha, beta);
                    PushRepo(&repo1, i, j, value);
                    if (value > alpha)
                    {
                        alpha = value;
                        AIresult[0] = i;
                        AIresult[1] = j;
                    }
                }
    }
            flag *= -1;


        }
        for (int i = 300, j = 280; j > 0; j -= 20)
        {
            if (pawn[i][j] == 0)//对空白位置打分
            {
                value = Getmaxinit(pawn, i, j, alpha, beta);
                PushRepo(&repo1, i, j, value);
                if (value > alpha)
                {
                    alpha = value;
                    AIresult[0] = i;
                    AIresult[1] = j;
                }
            }
        }
        
        
    }
    else {
        DeleteRepo(&repo1,X,Y);//删除玩家下过的位置
        current = repo1;
        while (current != NULL)
        {
            value=Getmax1(pawn,repo1,current->xPos,current->yPos,alpha,beta);
            ChangeRepo(repo1,current->xPos,current->yPos,current->value);//更新仓库
            if (value > current->value)
            {
                alpha = value;
                AIresult[0] = current->xPos;
                AIresult[1] = current->yPos;
            }
            current = current->next;
        }
    }
    DeleteRepo(&repo1,AIresult[0],AIresult[1]);

    


    
return AIresult;
}
int Getmaxinit(int pawn[320][320], int xPos, int yPos, int alpha, int beta)
{
    pawn[xPos][yPos] = 1;
    int left = 20;//棋盘位置
    int right = 300;
    int bottom = 300;
    int top = 20;
    int width = 20;
    int value;
    int flag = -1;
    int i = 160;
    int j = 160;
    if (pawn[i][j] == 0)
    {
        value = Getmininit(pawn, i, j, alpha, beta);
        if (value > alpha)
        {
            alpha = value;
        }
        if (alpha >= beta)
        {
            goto OK;
        }
    }

    
    for (int count = 1; count < 15; count++)
    {
        for (int m = 0; m < count; m++)
        {
            j += (flag * width);
            if (pawn[i][j] == 0)
            {
                value = Getmininit(pawn, i, j, alpha, beta);
                if (value > alpha)
                {
                    alpha = value;
                }
                if (alpha >= beta)
                {
                    goto OK;
                }
            }
        }
        for (int m = 0; m < count; m++)
        {
            i += (flag * width);
            if (pawn[i][j] == 0)
            {
                value = Getmininit(pawn, i, j, alpha, beta);
                if (value > alpha)
                {
                    alpha = value;
                }
                if (alpha >= beta)
                {
                    goto OK;
                }
            }
        }
        flag *= -1;
        
     }
    for (int i = 300, j = 280; j > 0; j -= 20)
    {
        if (pawn[i][j] == 0)
        {
            value = Getmininit(pawn, i, j, alpha, beta);
            if (value > alpha)
            {
                alpha = value;
            }
            if (alpha >= beta)
            {
                goto OK;
            }
        }
    }
        
    

OK:
    pawn[xPos][yPos] = 0;
    return alpha;
}
int Getmininit(int pawn[320][320], int xPos, int yPos, int alpha, int beta)
{
    pawn[xPos][yPos] = -1;
    int left = 20;//棋盘位置
    int right = 300;
    int bottom = 300;
    int top = 20;
    int width = 20;
    int value;
    int i = 300;
    int j = 300;
    int flag = -1;
    for (int count = 1; count < 15; count++)
    {
        for (int m = 0; m < count; m++)
        {
            j += (flag * width);
            value = evaluate(pawn, i, j);
            if (value < beta)
            {
                beta = value;
            }
            if (alpha >= beta)
            {
                goto OK;
            }
        }
        for (int count = 1; count < 16; count++)
        {
            i += (flag * width);
            value = evaluate(pawn, i, j);
            if (value < beta)
            {
                beta = value;
            }
            if (alpha >= beta)
            {
                goto OK;
            }
        }
        flag *= -1;
        

    }
    for (int i = 300, j = 280; j > 0; j -= 20)
    {
        value = evaluate(pawn, i, j);
        if (value < beta)
        {
            beta = value;
        }
        if (alpha >= beta)
        {
            goto OK;
        }
    }
OK:


    pawn[xPos][yPos] = 0;
    return beta;
}
int Getmax1(int pawn[320][320], struct repo* repo, int xPos, int yPos, int alpha, int beta)
{
    pawn[xPos][yPos] = 1;
    struct repo* current=repo;
    int left = 20;//棋盘位置
    int right = 320;
    int bottom = 320;
    int top = 20;
    int width = 20;
    int value;
    while(current!=NULL)
    {
        value=Getmin1(pawn, repo, current->xPos, current->yPos,  alpha, beta);
        if (value > alpha)
        {
            alpha = value;
        }
        if (alpha >= beta)
        {
            goto OK;
        }
        current = current->next;
    }
OK:
    pawn[xPos][yPos] = 0;
    return alpha;

}
int Getmin1(int pawn[320][320], struct repo* repo, int xPos, int yPos, int alpha, int beta)
{
    pawn[xPos][yPos] = -1;
    struct repo* current = repo;
    int left = 20;//棋盘位置
    int right = 320;
    int bottom = 320;
    int top = 20;
    int width = 20;
    int value;
    while (current != NULL)
    {
        value = Getmax2(pawn, repo, current->xPos, current->yPos, alpha, beta);
        if (value < alpha)
        {
            beta = value;
        }
        if (alpha >= beta)
        {
            goto OK;
        }
        current = current->next;
    }
OK:
    pawn[xPos][yPos] = 0;
    return beta;
}
int Getmax2(int pawn[320][320], struct repo* repo, int xPos, int yPos, int alpha, int beta)
{
    pawn[xPos][yPos] = 1;
    struct repo* current = repo;
    int left = 20;//棋盘位置
    int right = 320;
    int bottom = 320;
    int top = 20;
    int width = 20;
    int value;
    while (current != NULL)
    {
        value = Getmin2(pawn, repo, current->xPos, current->yPos, alpha, beta);
        if (value > alpha)
        {
            alpha = value;
        }
        if (alpha >= beta)
        {
            goto OK;
        }
        current = current->next;
    }
OK:
    pawn[xPos][yPos] = 0;
    return alpha;

}
int Getmin2(int pawn[320][320], struct repo* repo, int xPos, int yPos, int alpha, int beta)
{
    pawn[xPos][yPos] = -1;
    struct repo* current = repo;
    int left = 20;//棋盘位置
    int right = 320;
    int bottom = 320;
    int top = 20;
    int width = 20;
    int value;
    while (current != NULL)
    {
        value = evaluate(pawn, current->xPos, current->yPos);
        if (value < alpha)
        {
            beta = value;
        }
        if (alpha >= beta)
        {
            goto OK;
        }
        current = current->next;
    }
OK:
    pawn[xPos][yPos] = 0;
    return beta;
}














void PushRepo(struct repo** repo, int xPos, int yPos, int value)
{
    struct repo* new=NULL;
    struct repo* previous=NULL;
    struct repo* current=*repo;
    new = (struct repo*)malloc(sizeof(struct repo));
    new->xPos = xPos;
    new->yPos = yPos;
    new->value = value;
    while (current != NULL && value < current->value)
    {
        previous = current;
        current = current->next;
    }
    new->next = current;
    if (previous == NULL)
    {
        *repo = new;
    }
    else {
        previous->next = new;
    }
}
void ChangeRepo(struct repo* repo,int xPos,int yPos,int value)
{
    struct repo* temp=repo;
    while (temp != NULL)
    {
        if (temp->xPos == xPos && temp->yPos)
        {
            temp->value = value;
            break;
        }
        temp = temp->next;
    }
}

void DeleteRepo(struct repo** repo, int xPos, int yPos)
{
    struct repo* temp = *repo;
    struct repo* previous = NULL;
    while (temp != NULL)
    {

        if (temp->xPos == xPos && temp->yPos == yPos)
        {
            break;
        }
        previous = temp;
        temp = temp->next;
    }
    if (previous == NULL)
    {

        *repo = temp->next;
    }
    else 
    {

        previous->next =temp->next;
    }
}

  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 12月22日
    • 创建了问题 12月14日

    悬赏问题

    • ¥15 视频编码 十六进制问题
    • ¥15 Xsheii7我安装这个文件的时候跳出来另一个文件已锁定文件的无一部分进程无法访问。这个该怎么解决
    • ¥15 unity terrain打包后地形错位,跟建筑不在同一个位置,怎么办
    • ¥15 FileNotFoundError 解决方案
    • ¥15 uniapp实现如下图的图表功能
    • ¥15 u-subsection如何修改相邻两个节点样式
    • ¥30 vs2010开发 WFP(windows filtering platform)
    • ¥15 服务端控制goose报文控制块的发布问题
    • ¥15 学习指导与未来导向啊
    • ¥15 求多普勒频移瞬时表达式