C Negamax Alpha-Beta搜索

C Negamax Alpha-Beta搜索,c,artificial-intelligence,C,Artificial Intelligence,我正在寻找有关实现Negamax Alpha Beta搜索算法的帮助。我的C不是最好的,但到目前为止,我已经有了一个玩游戏的工作框架,我的Alpha-Beta搜索总是返回似乎是最后找到的移动,而不是返回找到的最好的移动,这让我遇到了麻烦 下面是我的alpha-beta搜索的源文件。如果有人能帮忙,我将不胜感激。我不是在寻找像很多人担心的那样“做我的家庭作业”的人,因为我真的很感兴趣,而且我以前用其他语言实现过搜索技术 再次感谢您的帮助 致意 #include "alphabeta.h" str

我正在寻找有关实现Negamax Alpha Beta搜索算法的帮助。我的C不是最好的,但到目前为止,我已经有了一个玩游戏的工作框架,我的Alpha-Beta搜索总是返回似乎是最后找到的移动,而不是返回找到的最好的移动,这让我遇到了麻烦

下面是我的alpha-beta搜索的源文件。如果有人能帮忙,我将不胜感激。我不是在寻找像很多人担心的那样“做我的家庭作业”的人,因为我真的很感兴趣,而且我以前用其他语言实现过搜索技术

再次感谢您的帮助

致意

#include "alphabeta.h"

struct tree_node * create_root(struct tree_node * root, struct Position *pos) 
{
    root = (struct tree_node*) malloc(sizeof(struct tree_node));
    root->pos = copy(pos);
    root->first_child = NULL;
    root->next_sibling = NULL;
    root->best_move = NULL;

    return root;
}

struct tree_node * create_node(struct tree_node *node) 
{
    struct tree_node *new_node = (struct tree_node*) malloc(sizeof(struct tree_node));
    new_node->pos = copy(node->pos);
    new_node->first_child = NULL;
    new_node->next_sibling = NULL;
    new_node->best_move = NULL;

    return new_node;
}

struct tree_node * add_child(struct tree_node *parent) 
{
    if (parent->first_child == NULL) 
    {
        parent->first_child = create_node(parent);
        return parent;
    }

    // Loop through the list of existing
    // children for the next gap
    struct tree_node *ptr = NULL;
    ptr = parent->first_child;
    while (ptr->next_sibling != NULL) 
    {
        ptr = ptr->next_sibling;
    }

    // create the new child and append to the list
    ptr->next_sibling = create_node(parent);
    return ptr;
}

struct tree_node * destroy_tree(struct tree_node * root) 
{
    if (root->first_child != NULL) 
    {
        destroy_tree(root->first_child);
    }

    // loop through the siblings and delete
    struct tree_node *ptr = root->next_sibling;
    struct tree_node *ptr2 = root;
    while (ptr != NULL) 
    {
        free(ptr2);
        ptr2 = ptr;
        ptr = ptr->next_sibling;
    }

    return root;
}

int negamax(struct tree_node *node, int color, int *num_static,
        int *num_cutoff, int height, int achievable, int hope) 
{
    printf("Called negamax\n");

    // first costruct the list of moves
    struct move_list *list = NULL;
    list = moves(color, node->pos, list);
    int num_moves = size_of_list(list);

    int best_score = NEG_INF;

    if (height == 0 || num_moves == 0) 
    {
        *num_static = *num_static + 1;
        return static_evaluator(node->pos, color, num_moves);
    }
    else 
    {
        int temp = 0;
        while (list != NULL) 
        {
            // Make the new move
            struct tree_node *new_node;
            //new_node = add_child(node);
            new_node = create_root(new_node, node->pos);
            make_move(new_node->pos, list->move);

            print_board(new_node->pos);

            list = list->prev;

            // Recurse over alpha beta
            temp = -negamax(new_node, color, num_static,
                    num_cutoff, height - 1,
                    -hope, -achievable);

            destroy(new_node->pos);
            free(new_node);
            //destroy_node(new_node);
            //new_node = NULL;

            //printf("Returned from the recursive call\n");
            // set the new best move
            /*
                if (temp > achievable) 
                {
                    best_score = temp;
                    node->best_move = list->move;
                    printf("Best move: %s\n", node->best_move->str_rep);
                }
            */

            if (temp >= hope) 
            {
                *num_cutoff = *num_cutoff + 1;
                return temp;
            }

            // set to the max value
            if (achievable <= temp) 
            {
                node->best_move = list->move;
                printf("Best move: %s\n", node->best_move->str_rep);
                achievable = temp;
            }
        }
    }

    return achievable;
}

/*
 * This is my evaluation function. The parameters
 * to the function are the attributes of the position;
 * The guard count, the king count and the number of
 * moves available. I chose to weight the parameters
 * offering the highest weight to the number of moves
 *
 * If there are no moves available, I decided to remove
 * points from the function. It will never go below zero,
 * but this should permit it to give an extremely low
 * value for positions which have no available moves
*/
int static_evaluator(struct Position *pos, int color, int num_moves) 
{
    int evaluation = 1;

    // Calculate the value, while applying
    // weights to the parameters
    switch (color) 
    {
        case BLACK_COL:
            if (num_moves == 0) 
            {
                evaluation += 1;
                if (pos->num_black_kings > 0) 
                {
                    evaluation += pos->num_black_kings - 1;
                }
            }
            else 
            {
                evaluation += num_moves * 3;
                evaluation += pos->num_black_kings * 2;
                evaluation -= pos->num_white_kings * 2;
            }
            // Always count the guards
            evaluation += pos->num_black_guards;
            evaluation -= pos->num_white_guards;
            break;

        case WHITE_COL:
            if (num_moves == 0) 
            {
                evaluation += 1;
                if (pos->num_white_kings > 0) 
                {
                    evaluation += pos->num_white_kings - 1;
                }
            }
            else 
            {
                evaluation += num_moves * 3;
                evaluation += pos->num_white_kings * 2;
                evaluation -= pos->num_black_kings * 2;
            }
            evaluation += pos->num_white_guards;
            evaluation -= pos->num_black_guards;
            break;
    }

    return evaluation;
}
#包括“alphabeta.h”
结构树节点*创建根(结构树节点*根,结构位置*位置)
{
root=(结构树节点*)malloc(sizeof(结构树节点));
root->pos=复制(pos);
root->first\u child=NULL;
root->next_sibling=NULL;
根->最佳移动=空;
返回根;
}
结构树节点*创建节点(结构树节点*节点)
{
结构树节点*新节点=(结构树节点*)malloc(sizeof(结构树节点));
新建节点->pos=复制(节点->pos);
新建\u节点->第一个\u子节点=NULL;
新建节点->下一个兄弟节点=NULL;
新建节点->最佳移动=空;
返回新的_节点;
}
结构树节点*添加子节点(结构树节点*父节点)
{
如果(父项->第一个子项==NULL)
{
父节点->第一个子节点=创建子节点(父节点);
返回父母;
}
//循环浏览现有列表
//下一个缺口的儿童
结构树节点*ptr=NULL;
ptr=父项->第一个子项;
while(ptr->next_sibling!=NULL)
{
ptr=ptr->下一个兄弟姐妹;
}
//创建新的子项并附加到列表中
ptr->next_sibling=创建_节点(父节点);
返回ptr;
}
结构树节点*销毁树(结构树节点*根)
{
如果(根->第一个子节点!=NULL)
{
销毁树(根->第一个子树);
}
//循环浏览兄弟节点并删除
结构树\u节点*ptr=root->next\u同级;
结构树节点*ptr2=根;
while(ptr!=NULL)
{
免费(ptr2);
ptr2=ptr;
ptr=ptr->下一个兄弟姐妹;
}
返回根;
}
int negamax(结构树节点、int color、int*num\u static、,
int*num_截止、int高度、int可实现、int希望)
{
printf(“称为negamax\n”);
//首先构建移动列表
struct move_list*list=NULL;
列表=移动(颜色、节点->位置、列表);
int num_moves=_列表(列表)的大小;
int最佳分数=NEG\U INF;
如果(高度==0 | | num_移动==0)
{
*num_static=*num_static+1;
返回静态\u计算器(节点->位置、颜色、移动次数);
}
其他的
{
内部温度=0;
while(list!=NULL)
{
//采取新的行动
结构树节点*新建节点;
//新建_节点=添加_子节点(节点);
新建\u节点=创建\u根(新建\u节点,节点->位置);
移动(新建节点->pos,列表->移动);
打印板(新建节点->pos);
列表=列表->上一页;
//在alpha-beta上递归
temp=-negamax(新节点、颜色、静态数量、,
数字截止,高度-1,
-希望(可实现的);
销毁(新建节点->pos);
空闲(新的_节点);
//销毁_节点(新建_节点);
//新节点=空;
//printf(“从递归调用返回的\n”);
//设定新的最佳动作
/*
如果(温度>可实现)
{
最佳成绩=临时工;
节点->最佳移动=列表->移动;
printf(“最佳移动:%s\n”,节点->最佳移动->str\u rep);
}
*/
如果(温度>=希望)
{
*num_截止=*num_截止+1;
返回温度;
}
//设置为最大值
如果(可实现的最佳移动=列表->移动;
printf(“最佳移动:%s\n”,节点->最佳移动->str\u rep);
可实现=温度;
}
}
}
可实现的回报;
}
/*
*这是我的评估函数。参数
*与功能相关的是位置的属性;
*卫兵人数、国王人数和士兵人数
*移动可用。我选择权重参数
*为移动次数提供最高权重
*
*如果没有可用的移动,我决定删除
*函数中的点。它永远不会低于零,
*但这应该允许它给出一个极低的值
*没有可用移动的位置的值
*/
int static_计算器(结构位置*pos,int color,int num_moves)
{
综合评价=1;
//应用时计算该值
//参数的权重
开关(彩色)
{
黑色外壳颜色:
如果(num_moves==0)
{
评价+=1;
如果(位置->数量>0)
{
评估+=pos->num\u black\u kings-1;
}
}
其他的
{
评估+=移动次数*3;
评估+=pos->num\u black\u kings*2;
评估-=pos->num\u white\u kings*2;
}
//总是数一数警卫
评估+=pos->num\u黑色\u防护;
评估-=pos->num\u白色\u防护;
打破
白色外壳:
如果(num_moves==0)
{
评价+=1;
如果(位置->数值>0)
{
评估+=pos->num_white_kings-1;
}
}
其他的
{
评估+=移动次数*3;
评估+=pos->num\u white\u kings*2;
评估-=pos->num\u black\u kings*2;
}
评估+=pos->num\u白色\u卫士;