void test(void) { GAME game; MOVE moves[MAX_MOVES]; int vector[MAX_PLAYERS]; int num_moves; int i; MOVE chosen_move; clock_t start_time, end_time; int centiseconds, rate; printf("Rankoids AI test\n"); clear_transposition_table(); init_stack(&game_stack, 100*sizeof(GAME)); initialise_game(&game); game.num_players = 3; game.players[0].hand[0] = 1; game.players[0].hand[1] = 3; game.players[0].hand[3] = 2; game.players[1].hand[4] = 1; game.players[0].hand[6] = 4; game.players[0].hand[7] = 3; game.players[0].hand[10] = 2; game.players[0].hand[JOKER_VALUE] = 1; game.players[1].hand[1] = 1; game.players[1].hand[2] = 3; game.players[1].hand[3] = 1; game.players[1].hand[4] = 1; game.players[1].hand[5] = 1; game.players[1].hand[9] = 3; game.players[1].hand[12] = 1; game.players[1].hand[5] = 2; game.players[2].hand[0] = 3; game.players[2].hand[2] = 1; game.players[2].hand[3] = 1; game.players[1].hand[4] = 2; game.players[2].hand[5] = 2; game.players[2].hand[9] = 1; game.players[2].hand[11] = 4; game.current_player = 0; game.pile_owner = 0; printf("Current game:\n"); print_game(&game); printf("All moves for player 1:\n"); num_moves = generate_all_moves(game.players[0].hand, moves); for (i = 0; i < num_moves; i++) print_move(moves[i]); printf("\n"); evaluate_game_immediate(&game, vector); printf("Game vector is: [%d,%d,%d]\n", vector[0], vector[1], vector[2]); printf("All valid moves for player 1:\n"); num_moves = generate_valid_moves(&game, moves); for (i = 0; i < num_moves; i++) print_move(moves[i]); printf("\n"); chosen_move = MAKE_MOVE(3, 2); printf("Apply move "); print_move(chosen_move); printf(", game is:\n"); apply_move(&game, chosen_move); print_game(&game); evaluate_game_immediate(&game, vector); printf("Game vector is: [%d,%d,%d]\n", vector[0], vector[1], vector[2]); printf("All valid moves for player 2:\n"); num_moves = generate_valid_moves(&game, moves); for (i = 0; i < num_moves; i++) { print_move(moves[i]); clear_transposition_table(); evaluate_move(&game, moves[i], vector, parameters.depth); printf(", with vector [%d,%d,%d]\n", vector[0], vector[1], vector[2]); } node_count = 0; clear_transposition_table(); start_time = clock(); chosen_move = choose_move(&game, vector, parameters.depth+5); end_time = clock(); centiseconds = (end_time - start_time)*100 / CLOCKS_PER_SEC; if (centiseconds != 0) { rate = (int) (100.0*node_count/centiseconds); } else { rate = 0; } printf("%d nodes examined (%d hits), time was: %0.2f seconds, rate is: %d nodes/sec\n", node_count, hit_count, centiseconds/100.0, rate); printf("Chosen move was:"); print_move(chosen_move); printf(", with vector [%d,%d,%d]\n", vector[0], vector[1], vector[2]); free_stack(&game_stack); }
/* Search thread main function */ void *search_loop(void *arg) { uint8_t ply; move_t mv, mv_tmp; SET_BLANK_MOVE(mv); SET_BLANK_MOVE(mv_tmp); pthread_mutex_lock(&mutex); /* Initializations */ precompute_moves(); precompute_distances(); init_zobrist_keys(); init_history(); init_transposition_table(); config_alarm(config->max_seconds); max_depth = config->max_depth; /* Setup board */ board = set_board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); if(board == NULL) quit("Error: Could not setup new board!\n"); /* ECO = encyclopedia of chess openings */ if(atoi(config->name) >= 50) if(!load_eco(board)) quit("Error: Could not load Encyclopedia of Chess Openings!\n"); pthread_mutex_unlock(&mutex); /* Keep alive until the status changes to QUIT */ while(status != QUIT) { switch(status) { case NOP: /* NOP: just wait for a change in status */ pthread_mutex_lock(&mutex); while(status == NOP) pthread_cond_wait(&cond, &mutex); pthread_mutex_unlock(&mutex); break; case FORCE: /* FORCE: wait for a change in status but don't start searches */ pthread_mutex_lock(&mutex); while(status == FORCE) pthread_cond_wait(&cond, &mutex); pthread_mutex_unlock(&mutex); break; case SEARCH: /* Iterative Deepening Search */ /* Save the on-move color */ onmove = board->onmove; /* Sets as blank the move to be played*/ SET_BLANK_MOVE(mv); /* Starts counting the time */ start_alarm(); /* For each depth, search with alpha-beta minimax */ for(ply = 2; ply <= max_depth; ply += 2) { mv_tmp = alpha_beta(board, -MAX_HEU, MAX_HEU, ply); /* Did we run out of time? If so, stops deepening iterations */ if(get_timeout()) break; mv = mv_tmp; } /* Stops counting the time, if it hasn't already reached limit */ stop_alarm(); /* If the move is still blank, use the partial move found */ if(IS_BLANK_MOVE(mv)) mv = mv_tmp; /* Perform the move found in the search */ move(board, mv); /* Returns to the NOP status */ set_status(NOP); break; case PONDER: /* Reserved for future use */ set_status(NOP); break; default: quit("Error: Invalid search status!\n"); } } /* Clean up memory */ clear_eco(); clear_transposition_table(); clear_history(); clear_board(board); /* Exit Search Thread */ return NULL; }