Пример #1
0
int
init_type_table()
{
  node_t *p ;
  p = new_node(TYPE) ; p->type_type = SIMPLE  ; strcpy( p->name , "integer" )         ;
                                                strcpy( p->mapsto, "INTEGER(IntKi)")  ;
                                                add_node_to_end ( p , &Type )         ;
  p = new_node(TYPE) ; p->type_type = SIMPLE  ; strcpy( p->name , "intki" )           ;
                                                strcpy( p->mapsto, "INTEGER(IntKi)")  ;
                                                add_node_to_end ( p , &Type )         ;
  p = new_node(TYPE) ; p->type_type = SIMPLE  ; strcpy( p->name , "b4ki" )           ; // this won't necesarially work as intended!
                                                strcpy( p->mapsto, "INTEGER(IntKi)")  ;
                                                add_node_to_end ( p , &Type )         ;

  p = new_node(TYPE) ; p->type_type = SIMPLE  ; strcpy( p->name , "real" )            ;
  p = new_node(TYPE) ; p->type_type = SIMPLE  ; strcpy( p->name , "real" )            ;
                                                strcpy( p->mapsto, "REAL(ReKi)")      ;
                                                add_node_to_end ( p , &Type )         ;
  p = new_node(TYPE) ; p->type_type = SIMPLE  ; strcpy( p->name , "reki" )            ;
                                                strcpy( p->mapsto, "REAL(ReKi)")      ;
                                                add_node_to_end ( p , &Type )         ;
  p = new_node(TYPE) ; p->type_type = SIMPLE  ; strcpy( p->name , "siki" )            ;
                                                strcpy( p->mapsto, "REAL(SiKi)")      ;
                                                add_node_to_end ( p , &Type )         ;

  p = new_node(TYPE) ; p->type_type = SIMPLE  ; strcpy( p->name , "logical" )         ;
                                                strcpy( p->mapsto, "LOGICAL")         ;
                                                add_node_to_end ( p , &Type )         ;

#if 0 // bjj: would like to add this back to see if we can use this for pack/unpack
// these have to be handled individually because people can and will put lengths after them
// so can't make a generic type node here
  p = new_node(TYPE) ; p->type_type = SIMPLE  ; strcpy( p->name , "character" )       ;
                                                strcpy( p->mapsto, "CHARACTER") /**/  ;
                                                add_node_to_end ( p , &Type )         ;
#endif


  p = new_node(TYPE) ; p->type_type = SIMPLE  ; strcpy( p->name , "doubleprecision" ) ;
                                                strcpy( p->mapsto, "REAL(DbKi)")      ;
                                                add_node_to_end ( p , &Type )         ;
  p = new_node(TYPE) ; p->type_type = SIMPLE  ; strcpy( p->name , "dbki" )            ;
                                                strcpy( p->mapsto, "REAL(DbKi)")      ;
                                                add_node_to_end ( p , &Type )         ;
  p = new_node(TYPE) ; p->type_type = SIMPLE  ; strcpy( p->name , "r8ki" )            ;
                                                strcpy( p->mapsto, "REAL(R8Ki)")      ;
                                                add_node_to_end ( p , &Type )         ;
  p = new_node(TYPE) ; p->type_type = DERIVED ; strcpy( p->name , "meshtype" )        ;
                                                strcpy( p->mapsto, "MeshType")        ;
                                                add_node_to_end ( p , &Type )         ;
  p = new_node(TYPE) ; p->type_type = DERIVED ; strcpy( p->name , "dll_type" )        ;
                                                strcpy( p->mapsto, "DLL_Type")        ;
                                                add_node_to_end ( p , &Type )         ;

  return(0) ;
}
Пример #2
0
/**
 * runs minmax algorithm, extends the tree at the same time.
 * decides what is the best move to perform according to the minmax algorithm (with alphabeta pruning)
 * 
 * @param node - the current root of the minmax tree
 * @param alpha - the current maximum we got (for alphabeta pruning)
 * @param beta - the current minimum we got (for alphabeta pruning)
 * @param depth - the depth of the tree
 * @param max - do max or min?
 * @param board - the current board
 * @param best_move - pointer that will contain the best move to make, AFTER the function finishes.
 * @param is_valid_move - function that decides if a move is valid
 * @param make_move - function that makes the move on the board
 * @param get_score - the scoring function for the current game
 */
int minmax_with_extend(vertex *node, int depth, int alpha, int beta, int max,
                       Board *board, Move *best_move,
                       int (*is_valid_move)(Board *board, Move *move, int value),
                       int (*make_move)(Board* board, Move* new_move, int value), 
                       int (*get_score)(Board* board)) {
    int i;
    int unimplemented_moves_length;
    int current_score;
    Move *next_best_move;
    Board *copied_board = new_board(board->n, board->m);
    if (copied_board == NULL) {
        printf("ERROR: can't initiazlie copied board.\n");
        exit(1);
    }

    // we stop if we got to a winning move or if we reached the requested depth
    if ((depth == 0) || (node->score == EXTREME_VALUE) || (node->score == -EXTREME_VALUE)) {
        free_board(copied_board);
        return node->score;
    }
    // if we don't have a linked list, but the depth isn't 0, we'll create an empty linked list
    if (node->children == NULL) {
        if ((node->children = (linked_list*)malloc(sizeof(linked_list))) == NULL) {
            printf("ERROR: standard function malloc has failed\n");
            exit(1);
        }
        node->children->head = NULL;
        node->children->tail = NULL;
    }

    if ((next_best_move = (Move*)malloc(sizeof(Move))) == NULL) {
        printf("ERROR: malloc has failed in minmaxtree\n");
        exit(1);
    }

    element *iterator = node->children->head;
    Move *unimplemented_moves = get_unimplemented_moves(node->children, board, &unimplemented_moves_length, max,
                                                        is_valid_move);
    // we'll initialize best_move to SOME move, just in case EVERY move is a losing move.
    if (iterator != NULL) {
        best_move->i = iterator->node->current_move->i;
        best_move->j = iterator->node->current_move->j;
    } else {
        if (unimplemented_moves_length > 0) {
            best_move->i = unimplemented_moves[0].i;
            best_move->j = unimplemented_moves[0].j;
        // NO MOVES AT ALL - we don't care about the best move, just return the current score.
        } else {
            free_board(copied_board);
            free(next_best_move);
            free(unimplemented_moves);
            return node->score;
        }
    }

    // runs max
    if (max) {
        while (iterator != NULL) {
            copy_board(board, copied_board);
            make_move(copied_board, iterator->node->current_move, max ? FIRST_PL_TURN:SECOND_PL_TURN);
            current_score = minmax_with_extend(iterator->node, depth-1, alpha, beta, !max, copied_board, next_best_move,
                                               is_valid_move, make_move, get_score);
            // get the maximum of alpha and current score
            if (current_score > alpha) {
                alpha = current_score;
                // update the best move accordingly
                best_move->i = iterator->node->current_move->i;
                best_move->j = iterator->node->current_move->j;
                
                // alpha-beta pruning
                if (beta <= alpha) {
                    free_board(copied_board);
                    free(next_best_move);
                    free(unimplemented_moves);
                    return alpha;
                }
            }
            iterator = iterator->next;
        }
        for (i=0; i<unimplemented_moves_length; i++) {
            copy_board(board, copied_board);
            add_node_to_end(node->children, unimplemented_moves[i], copied_board, max ? FIRST_PL_TURN:SECOND_PL_TURN);
            // still need to update the score of the node. so we'll make the move and then update the score.
            make_move(copied_board, node->children->tail->node->current_move, node->children->tail->node->value);
            node->children->tail->node->score = get_score(copied_board);

            // now for the minmax part
            current_score = minmax_with_extend(node->children->tail->node, depth-1, alpha, beta, !max, copied_board, next_best_move,
                                               is_valid_move, make_move, get_score);
            // get the maximum of alpha and current score
            if (current_score > alpha) {
                alpha = current_score;
                // update the best move accordingly
                best_move->i = node->children->tail->node->current_move->i;
                best_move->j = node->children->tail->node->current_move->j;

                // alpha-beta pruning
                if (beta <= alpha) {
                    free_board(copied_board);
                    free(next_best_move);
                    free(unimplemented_moves);
                    return alpha;
                }
            }
        }
        free_board(copied_board);
        free(next_best_move);
        free(unimplemented_moves);
        return alpha;
    // runs min
    } else {
        while (iterator != NULL) {
            copy_board(board, copied_board);
            make_move(copied_board, iterator->node->current_move, max ? FIRST_PL_TURN:SECOND_PL_TURN);
            current_score = minmax_with_extend(iterator->node, depth-1, alpha, beta, !max, copied_board, next_best_move,
                                               is_valid_move, make_move, get_score);
            // get the minimum of beta and current score
            if (current_score < beta) {
                beta = current_score;
                // update the best move accordingly
                best_move->i = iterator->node->current_move->i;
                best_move->j = iterator->node->current_move->j;
                
                // alpha-beta pruning
                if (beta <= alpha) {
                    free_board(copied_board);
                    free(next_best_move);
                    free(unimplemented_moves);
                    return beta;
                }
            }
            iterator = iterator->next;
        }
        for (i=0; i<unimplemented_moves_length; i++) {
            copy_board(board, copied_board);
            add_node_to_end(node->children, unimplemented_moves[i], copied_board, max ? FIRST_PL_TURN:SECOND_PL_TURN);
            // still need to update the score of the node. so we'll make the move and then update the score.
            make_move(copied_board, node->children->tail->node->current_move, node->children->tail->node->value);
            node->children->tail->node->score = get_score(copied_board);

            // now for the minmax part
            current_score = minmax_with_extend(node->children->tail->node, depth-1, alpha, beta, !max, copied_board, next_best_move,
                                               is_valid_move, make_move, get_score);
            // get the minimum of beta and current score
            if (current_score < beta) {
                beta = current_score;
                // update the best move accordingly
                best_move->i = node->children->tail->node->current_move->i;
                best_move->j = node->children->tail->node->current_move->j;

                // alpha-beta pruning
                if (beta <= alpha) {
                    free_board(copied_board);
                    free(next_best_move);
                    free(unimplemented_moves);
                    return beta;
                }
            }
        }
        free_board(copied_board);
        free(next_best_move);
        free(unimplemented_moves);
        return beta;
    }
}