【发布时间】:2020-10-21 06:35:12
【问题描述】:
我目前正在使用 MINIMAX 算法构建一个国际象棋 AI。最初没有线程很好,但它最多只有 5 层,所以为了增加深度,我使用了多线程,但它陷入了无限循环,有人可以帮忙让它工作吗?
代码:
void* best_move(void *_args){
struct forThread *args = (struct forThread *) _args;
for(int i=0; i<8; ++i){
for(int j=0; j<8; ++j){
args->res += args->state_score[i][j];
printf("%c", state[i][j]);
}
printf("\n");
}
if(args->depth == 5){
//printf("Return value in the last node = %lld\n", current_score);
pthread_exit((void*)(args->res));
}
// TURN OF THE PLAYER THAT MAXIMIZES THE SCORE :
int mid[] = {0, 7, 1, 6, 2, 5, 3, 4};
if(args->depth % 2 == 0){
//printf("Reached the maximizing player\n");
int ans = -1e8;
for(int i=0; i<8; ++i){
for(int j=0; j<8; ++j){
if(isUpper(args->state[i][mid[j]]) && args->state_score[i][mid[j]]>0){
vector<pair<int, int>> possible_moves = get_moves(i, mid[j], args->state);
if(possible_moves.size() == 0) continue;
for(auto u : possible_moves){
int x = u.first, y = u.second;
int removed_points = args->state_score[x][y];
char state_copy[8][9];
int state_score_copy[8][8];
for(int k=0; k<8; ++k){
for(int io=0; io<9; ++io){
if(io!=8) state_score_copy[k][io] = args->state_score[k][io];
state_copy[k][io] = args->state[k][io];
}
}
int new_score = args->res - args->state_score[x][y];
if(args->depth >= 3 && new_score == args->start_score) continue;
state_copy[x][y] = state_copy[i][mid[j]];
state_copy[i][mid[j]] = '_';
state_score_copy[x][y] = state_score_copy[i][mid[j]];
state_score_copy[i][mid[j]] = 0;
struct forThread *arg = (forThread*) malloc (sizeof (struct forThread));
arg->depth = args->depth + 1;
arg->depth = args->start_score;
for(int k=0; k<8; ++k){
for(int io=0; io<9; ++io){
if(io!=8) arg->state_score[k][io] = args->state_score[k][io];
arg->state[k][io] = args->state[k][io];
}
}
arg->alpha = args->alpha;
arg->beta = args->beta;
arg->res = -1;
pthread_t id;
pthread_create(&id, NULL, best_move, arg);
void *result = NULL;
//long long res = best_move(depth+1, state_copy, state_score_copy, alpha, beta);
pthread_join(id, &result);
ans = min(ans, (int)result);
args->res = ans;
//long long res = best_move(depth+1, state_copy, state_score_copy, alpha, beta);
//printf("%lld\n", res);
args->alpha = max(args->alpha, ans);
if(args->beta <= args->alpha) break;
if(args->depth == 0 && ans == args->res){
//printf("got the answer = %d\n", ans);
moveX = i;
moveY = mid[j];
toX = x;
toY = y;
}
}
}
}
}
pthread_exit((void*)(args->res));
}
else{
int ans = +1e8;
//printf("Reached the minimizing player\n");
for(int i=0; i<8; ++i){
for(int j=0; j<8; ++j){
if(isLower(args->state[i][mid[j]]) && args->state_score[i][mid[j]]<0){
vector<pair<int, int>> possible_moves = get_moves(i, mid[j], args->state);
if(possible_moves.size() == 0) continue;
for(auto u : possible_moves){
int x = u.first, y = u.second;
int removed_points = args->state_score[x][y];
char state_copy[8][9];
int state_score_copy[8][8];
for(int k=0; k<8; ++k){
for(int io=0; io<9; ++io){
if(io!=9) state_score_copy[k][io] = args->state_score[k][io];
state_copy[k][io] = args->state[k][io];
}
}
int new_score = args->res - args->state_score[x][y];
if(args->depth >= 3 && new_score == args->start_score) continue;
state_copy[x][y] = state_copy[i][mid[j]];
state_copy[i][mid[j]] = '_';
state_score_copy[x][y] = state_score_copy[i][mid[j]];
state_score_copy[i][mid[j]] = 0;
struct forThread *arg = (forThread*) malloc (sizeof (struct forThread));
arg->depth = args->depth + 1;
arg->depth = args->start_score;
for(int k=0; k<8; ++k){
for(int io=0; io<9; ++io){
if(io!=8) arg->state_score[k][io] = args->state_score[k][io];
arg->state[k][io] = args->state[k][io];
}
}
arg->alpha = args->alpha;
arg->beta = args->beta;
arg->res = -1;
pthread_t id;
pthread_create(&id, NULL, best_move, arg);
void *result = NULL;
//long long res = best_move(depth+1, state_copy, state_score_copy, alpha, beta);
pthread_join(id, &result);
ans = min(ans, (int)result);
args->res = ans;
args->beta = min(ans, args->beta);
if(args->beta <= args->alpha) break;
}
}
}
}
pthread_exit((void*)(args->res));
}
}
【问题讨论】:
-
pthread_create(&id, ...)直接后跟pthread_join(id, ...)有什么用?这与仅以非线程方式调用线程函数没有什么不同。 -
我需要在这里有点挑剔,抱歉。那是 pthreads,没有 c++ 线程。这里似乎没有一行 C++ 代码。
std::thread将是您在 C++ 中使用的东西 -
这是我第一次使用线程,我找到了很多方法,但其中很少有人告诉如何获取返回值,你能建议一些简单的方法来从函数中获取返回值吗?
-
@Reinhold 有一个向量,所以不被 C 编译器编译就足够了。我希望 C++ 不是通过先教 C 来教的。
-
@StevenAnderson 你可能想看看
std::asyncen.cppreference.com/w/cpp/thread/async 你也可能更喜欢这个:auto arg = new forThread()而不是struct forThread *arg = (forThread*) malloc (sizeof (struct forThread));
标签: c++ multithreading artificial-intelligence chess minimax