I am currently working on building a chess AI by using the MINIMAX algorithm. It was pretty good initially without the threadings but it was only going as deep as 5 ply at max, So in order to increase the depth I used multithreading but it is falling into an inifinite loop, Can someone help to make it work ?
The code :
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));
}
}