/** * @brief Adds a new node to the move tree. * * A new node is added to the move tree. For every move in the generated move * list, a new node is added recursively. If a certain level is reached, the * recusrion is stopped. * * @param[in] color Color of move to set. * @param[in] depth Counter that shows the level in the move tree. * @param[in] alpha Alpha-Beta pruning * @param[in] beta Alpha-Beta pruning * @return Value of position */ int add_node( int color, int depth, int alpha, int beta ) { int k, l; int i, j; int valid_moves[BOARD_SIZE_MAX * BOARD_SIZE_MAX][4]; int nr_of_valid_moves; int best_value; char x[2]; char y[3]; char indent[10]; int tactic_move = 0; int qsearch = MAX_QSEARCH_DEPTH; //unsigned hash_id; int value_list[COUNT_BRAINS] = { 1, 2, 3, 4, 5, 6, 7, 8 }; best_value = ( color == BLACK ) ? INT_MIN : INT_MAX; if ( ! ( ( search_depth + MAX_QSEARCH_DEPTH ) % 2 ) ) { qsearch++; } depth++; nr_of_valid_moves = get_valid_move_list( color, valid_moves ); // PASS if no valid move is possible: if ( nr_of_valid_moves == 0 ) { make_move( color, INVALID, INVALID ); best_value = evaluate_position( value_list, false ); undo_move(); } // Count tactic moves: for ( l = 0; l < nr_of_valid_moves; l++ ) { if ( valid_moves[l][3] > 0 ) { tactic_move++; } } // Go through move list: for ( k = 0; k < nr_of_valid_moves; k++ ) { i = valid_moves[k][0]; j = valid_moves[k][1]; // Skip non-tactical moves in quiescense search: if ( depth >= search_depth && tactic_move > 0) { if ( valid_moves[k][3] == 0 ) { continue; } } // Make move: node_count++; make_move( color, i, j ); if ( depth < search_depth ) { // Start recursion: valid_moves[k][2] = add_node( color * -1, depth, alpha, beta ); } else { //insert_hash_table( hash_id, best_value ); if ( tactic_move && depth < search_depth + qsearch ) { valid_moves[k][2] = add_node( color * -1, depth, alpha, beta ); count_quiet_search++; } else { valid_moves[k][2] = evaluate_position( value_list, true ); } } if ( color == BLACK ) { // For black: remember highest value if ( valid_moves[k][2] > best_value ) { best_value = valid_moves[k][2]; if ( best_value > alpha ) { alpha = best_value; } } } else { // For white: remember lowest value if ( valid_moves[k][2] < best_value ) { best_value = valid_moves[k][2]; if ( best_value < beta ) { beta = best_value; } } } if ( do_log ) { i_to_x( i, x ); j_to_y( j, y ); indent[0] = '\0'; for ( l = 1; l <= depth; l++ ) { strcat( indent, "\t" ); } fprintf( log_file, "%s%s%s (%d) (T: %d) (%d,%d,%d,%d,%d,%d,%d,%d) (a: %d, b: %d)\n" , indent, x, y , valid_moves[k][2], valid_moves[k][3], value_list[0], value_list[1] , value_list[2], value_list[3], value_list[4], value_list[5] , value_list[6], value_list[7] , alpha, beta ); } undo_move(); if ( color == BLACK ) { if ( valid_moves[k][2] > beta ) { // Maybe only '>' is correct?! beta_break++; break; } } else { if ( valid_moves[k][2] < alpha ) { // Maybe only '<' is correct?! alpha_break++; break; } } } return best_value; }
/** * @brief Returnes list of valid moves for given color. * * This function takes a list of pseudo valid moves (as created by * get_pseudo_valid_move_list()) and drops the zero liberty moves. The * number of valid moves is returned. * * @param[in] color Color of moving side (BLACK|WHITE) * @param[out] valid_moves List of valid moves (zero liberty moves excluded) * @return Number of valid moves * @sa get_pseudo_valid_move_list() * @warning The function get_pseudo_valid_move_list() must be called * before get_valid_move_list(). */ int get_valid_move_list( int color, int valid_moves[][4] ) { int count; int i, j; int k, l; int nr_of_removed_stones; int captured_now[BOARD_SIZE_MAX * BOARD_SIZE_MAX][2]; int group_nr; int nr_of_liberties; bool is_valid; int temp_moves[BOARD_SIZE_MAX * BOARD_SIZE_MAX][4]; int value; int valid_moves_count; int atari_groups_player_before; int atari_groups_opponent_before; int atari_groups_player_after; int atari_groups_opponent_after; //int count_liberties_player_before; //int count_liberties_opponent_before; //int count_liberties_player_after; //int count_liberties_opponent_after; int value_list[COUNT_BRAINS]; //init_brains(); valid_moves_count = get_pseudo_valid_move_list( color, valid_moves ); for ( k = 0; k < BOARD_SIZE_MAX * BOARD_SIZE_MAX; k++ ) { temp_moves[k][0] = INVALID; // i coordinate temp_moves[k][1] = INVALID; // j coordinate temp_moves[k][2] = 0; // Value of move temp_moves[k][3] = 0; // Number of captured stones and atari ... } count = 0; for ( k = 0; k < valid_moves_count; k++ ) { is_valid = false; i = valid_moves[k][0]; j = valid_moves[k][1]; // Check for groups in atari before move is made: scan_board_1(); atari_groups_player_before = get_worm_count_atari(color); atari_groups_opponent_before = get_worm_count_atari( color * -1 ); //count_liberties_player_before = get_group_count_liberties(color); //count_liberties_opponent_before = get_group_count_liberties( color * -1 ); // Make move set_vertex( color, i, j ); scan_board_1(); nr_of_removed_stones = remove_stones( color * -1 ); // Check if this move is valid: if ( nr_of_removed_stones > 0 ) { is_valid = true; } else { group_nr = get_worm_nr( i, j ); nr_of_liberties = get_nr_of_liberties(group_nr); if ( nr_of_liberties > 0 ) { is_valid = true; } } atari_groups_player_after = get_worm_count_atari(color); atari_groups_opponent_after = get_worm_count_atari( color * -1 ); // Check if move gives atari: if ( atari_groups_opponent_after > atari_groups_opponent_before ) { temp_moves[k][3]++; } // Check if move avoids atari: if ( atari_groups_player_after < atari_groups_player_before ) { temp_moves[k][3]++; } //count_liberties_player_after = get_group_count_liberties(color); /* count_liberties_opponent_after = get_group_count_liberties( color * -1 ); if ( count_liberties_opponent_after < count_liberties_opponent_before) { temp_moves[k][3]++; } */ value = evaluate_position( value_list, false ); // Undo move: nr_of_removed_stones = get_captured_now(captured_now); set_vertex( EMPTY, i, j ); for ( l = 0; l < nr_of_removed_stones; l++ ) { set_vertex( color * -1, captured_now[l][0], captured_now[l][1] ); } if ( color == BLACK ) { set_black_captured( get_black_captured() - nr_of_removed_stones ); } else { set_white_captured( get_white_captured() - nr_of_removed_stones ); } // Save only valid moves in temporary list: if ( is_valid ) { temp_moves[count][0] = i; temp_moves[count][1] = j; temp_moves[count][2] = value; temp_moves[count][3] += nr_of_removed_stones; count++; } } // Copy only valid moves into valid_moves list: for ( k = 0; k < count; k++ ) { valid_moves[k][0] = temp_moves[k][0]; valid_moves[k][1] = temp_moves[k][1]; valid_moves[k][2] = temp_moves[k][2]; valid_moves[k][3] = temp_moves[k][3]; } valid_moves[count][0] = INVALID; valid_moves[count][1] = INVALID; // Sort valid moves list by value if ( color == BLACK ) { qsort( valid_moves, (size_t)count, sizeof(valid_moves[0]), compare_value_black ); } else { qsort( valid_moves, (size_t)count, sizeof(valid_moves[0]), compare_value_white ); } return count; }
int main(int argc, char *argv[]) { int ret; int choice; int i, j; float Ts=0.002; float T; float vm=0.05; //mean speed matrix xd, xd_dot, J; float q0[5], q_final[5]; float p0[3]; float p1[3]; DUNIT *unit; unsigned short motor[NUM_MOTORS]; unsigned char sensor[NUM_SENSORS]; pSM = (SM*) mbuff_alloc(NAME_OF_MEMORY, sizeof(SM)); if(pSM == NULL) { perror("mbuff_alloc failed"); return -1; } // Header = 1,; // Step = 2, motor[0] = 0; motor[1] = 0; motor[2] = 2100; motor[3] = 4200; motor[4] = -2500; motor[5] = 0; motor[6] = 18100; motor[7] = -2100; motor[8] = 1000; motor[9] = 6200; motor[10] = 0; motor[11] = 0; motor[12] = -2100; motor[13] = -4180; motor[14] = 2500; motor[15] = 0; motor[16] = -18810; motor[17] = 2000; motor[18] = -1000; motor[19] = -6200; motor[20] = 2100; motor[21] = 60; motor[22] = 60; sensor[0] = 'R'; sensor[1] = 'R'; sensor[2] = 'R'; sensor[3] = 'R'; unit = (DUNIT*)&(pSM->Data.IntDat); ret = send_commands(motor, sensor, unit); pSM->VarIF.ResRep = 0; pSM->VarIF.Mode = IDLE; pSM->VarIF.InterruptSend = TRUE; //watch return readret(unit); //desired final configuration //q_final[0]=PI*3/5; //q_final[1]=PI/3; //q_final[2]=PI/6; //q_final[3]=-PI/4; //q_final[4]=0; //evaluate_position(q_final, p1); q0[4]=0; open_hand (motor, sensor, unit); while (1) { //present position read_positions(unit, motor); robot2DH (&motor[16], q0); evaluate_position(q0, p0); printf("\nPresent position: (%f,%f,%f)\n",p0[0],p0[1],p0[2]); //select desired position choice=select_desired_position (p1); if (choice==-1) break; if (choice==1) close_hand (motor, sensor, unit); if (choice==2) open_hand (motor, sensor, unit); printf("\nDesired final position: (%f,%f,%f)\n",p1[0],p1[1],p1[2]); //execution time T=evaluate_execution_time (p0, p1, vm); //initializing matrixes initialize_matrix (&xd, T/Ts+1, 3); initialize_matrix (&xd_dot, T/Ts+1, 3); initialize_matrix (&J, 3, 5); //evaluate desired trajectory trajectory_left_arm (Ts, T, p0, p1, &xd, &xd_dot); //inverse kinematics inverse_kinematics (Ts, T, &xd, &xd_dot, unit); } //close_hand (motor, sensor, unit); free(xd.vector); free(xd_dot.vector); free(J.vector); //free memory mbuff_free(NAME_OF_MEMORY, (void*)pSM); return 0; }