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