示例#1
0
文件: search.c 项目: cledo/HaiGo
/**
 * @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;
}
示例#2
0
文件: move.c 项目: cledo/HaiGo
/**
 * @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;
}
示例#3
0
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;
}