微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

向玩家分发任务挂起程序

如何解决向玩家分发任务挂起程序

我们给了两个结构,一个代表一个玩家,另一个代表一个任务,玩家在分配给他之后可以执行。每个玩家都有按升序排序的任务列表。最初,我们必须为Players列表实现一个带有哨兵的圆形双向链接列表,并为这些任务实现一个带有哨兵的单排序链接列表(使用Players结构的task_head和tasks_sentinel字段)。

设置好数据结构后,我们需要使用循环算法将给定的常规任务列表(由Head_GL指向)中的任务分配给玩家(不知道我的解决方案是否正确,不是)研究了该算法,这样我就可以尝试自行解决问题)。 问题是由于某种我不知道的原因,调用isTaskListempty(..)时程序似乎挂起,然后程序就这样停止了,而在cout<<"istasklist empty called";之后没有打印任何内容

关于我在做什么错的任何想法吗?

P.S。除了简单的hello world程序外,我从未在其他任何东西上使用过c ++,因此我在指针方面的经验非常有限。

结构体和一些全局变量的头文件声明:

/**
 * Structure defining a node of the players double linked list
 * tree
 */
struct Players
{
    int pid;                      /*Player's identifier*/
    int is_alien;                 /*Alien flag*/
    int evidence;                 /*Amount of evidence*/
    struct Players *prev;         /*Pointer to the prevIoUs node*/
    struct Players *next;         /*Pointer to the next node*/
    struct Tasks *tasks_head;     /*Pointer to the head of player's task list*/
    struct Tasks *tasks_sentinel; /*Pointer to the sentinel of player's task list*/
};

/**
 * Structure defining a node of the tasks sorted linked list
 */
struct Tasks
{
    int tid;                      /*Task's identifier*/
    int difficulty;               /*Task's difficulty*/
    struct Tasks *next;           /*Pointer to the next node*/  
};

struct Head_GL
{
    int tasks_count[3];           /*Count of tasks*/
    struct Tasks *head;           /*Pointer to the head of general list*/
};

/* Global variable,pointer to the head of the players list */
struct Players *players_head;

/* Global variable,pointer to the head of the tasks list */
struct Head_GL *tasks_head;

/* Global variable,pointer to the top of the completed task's stack */
struct Head_Completed_Task_Stack *tasks_stack;

/* Global variable,counter of the total num of tasks in the general tasks list */
int Total_Tasks;

Main.cpp:

/**
 * @brief Optional function to initialize data structures that 
 *        need initialization
 *
 * @return 1 on success
 *         0 on failure
 */
int initialize() {
    // players list init
    players_head = (struct Players*) malloc(sizeof(struct Players));
    players_head->evidence = -1;
    players_head->is_alien = -1;
    players_head->pid = -1;
    players_head->next = NULL;
    players_head->prev = NULL;
    players_head->tasks_head = NULL;
    players_head->tasks_sentinel = NULL;

    // General Tasks List init
    tasks_head = (struct Head_GL*) malloc(sizeof(struct Head_GL));
    tasks_head->tasks_count[0] = 0;
    tasks_head->tasks_count[1] = 0;
    tasks_head->tasks_count[2] = 0;
    tasks_head->head = NULL;

    // Completed Tasks stack init
    tasks_stack = (struct Head_Completed_Task_Stack*) malloc(sizeof(struct Head_Completed_Task_Stack));
    tasks_stack->count = 0;
    tasks_stack->head = NULL;

    Total_Tasks = 0;
    return 1;
}

/**
 * @brief distribute tasks to the players
 * @return 1 on success
 *         0 on failure
 */
int distribute_tasks() {
    if(isDLLEmpty() || isGenTaskListempty()) return 0;

    // round robin algo
    int tasksToAssign;
    struct Players* player = players_head->next; // start with the 1st player
    struct Tasks* task = tasks_head->head; // start with the 1st task

    // There's only one player and he's an impostor so exit
    if(player->is_alien == 1 && player->next == NULL) return 0;

    for(tasksToAssign = Total_Tasks; tasksToAssign > 0; tasksToAssign--) {
        if(player->is_alien == 1 || player == players_head) {
            tasksToAssign++;
            player = player->next; // go to the next player
            continue; // skip impostors
        }

        sortedInsertTaskList(&player,task->tid,task->difficulty);
        player = player->next; // go to the next player
        task = task->next; // go to the next task to assign
    }
    return 1;
}

// Beginning of General Tasks list implementation (Sorted singly linked list)

bool isGenTaskListempty() {
    return (tasks_head->head == NULL);
}

int sortedInsertGenTaskList(int tid,int difficulty) {
    // increment the list's difficulty counter
    if (difficulty == 1) tasks_head->tasks_count[0]++;
    else if (difficulty == 2) tasks_head->tasks_count[1]++;
    else tasks_head->tasks_count[2]++;

    Total_Tasks++; // increment the num of total tasks

    struct Tasks *node = (struct Tasks*) malloc(sizeof(struct Tasks)); // Could return null if not enough mem
    if(node == NULL) return 0; // not enough memory exit
    // add data to the new node
    node->tid = tid;
    node->difficulty = difficulty;
    node->next = NULL;

    if(isGenTaskListempty()) {
        tasks_head->head = node;
        return 1;
    }

    // insert the new node without breaking the sorting of the list
    Tasks *curr = tasks_head->head;

    while(curr->next != NULL && curr->next->difficulty < difficulty) {
        curr = curr->next;
    }
    node->next = curr->next;
    curr->next = node;
    return 1;
}

void printGenTasksList() {
    cout << "{" << tasks_head->tasks_count[0] << "," << tasks_head->tasks_count[1] << "," << tasks_head->tasks_count[2] << "}" << endl;
    Tasks* curr = tasks_head->head;
    do {
        cout << "Task#" << curr->tid << ":" << curr->difficulty << endl;
        curr = curr->next;
    } while (curr != NULL);
}

// End of General Tasks list implementation (Sorted singly linked list)

// Beginning of Tasks List implementation (Sorted Singly Linked List w/sentinel)

bool isTaskListempty(struct Tasks* head) {
    cout<<"istasklist empty called";
    return (head->next == NULL);
}

int sortedInsertTaskList(struct Players** player,int tid,int difficulty) {
    struct Tasks* node = (struct Tasks*) malloc(sizeof(struct Tasks)); // Could return null if not enough mem
    
    if(node == NULL) return 0;
    // add data to the new node
    node->tid = tid;
    node->difficulty = difficulty;
    node->next = NULL;

    cout << "sortedInsert before is empty";
    if (isTaskListempty((*player)->tasks_head)) { // if the list is empty,make the head and sentinel point to the new node
        cout << "list was empty";
        (*player)->tasks_head->next = node;
        (*player)->tasks_sentinel->next = node;
        return 1;
    }

    // check if the new node can be added to the end of the list
    if ((*player)->tasks_sentinel->next->difficulty <= difficulty) {
        (*player)->tasks_sentinel->next->next = node; // place new node at the end of the list
        (*player)->tasks_sentinel->next = node; // update sentinel
        return 1;
    }

    // insert the new node without breaking the sorting of the list
    struct Tasks* curr = (*player)->tasks_head->next;

    while (curr->next != NULL && curr->next->difficulty < difficulty) {
        curr = curr->next;
    }
    node->next = curr->next;
    curr->next = node;
    return 1;
}



// End of Tasks List implementation (Sorted Singly Linked List w/sentinel)

// Beginning of players list implementation (circular doubly linked list w/ Sentinel)

bool isDLLEmpty() {
    return (players_head->next == NULL);
}

int dllInsert(int pid,int isAlien) {
    // allocate memory and initialize fields
    struct Players* player = (struct Players*) malloc(sizeof(struct Players)); // Could return null if not enough mem
    if(player == NULL) return 0; // not enough memory,exit
    player->pid = pid;
    player->is_alien = isAlien;
    player->evidence = 0;
    player->prev = players_head;
    player->tasks_head = NULL;
    player->tasks_sentinel = NULL;

    // check if the list is empty
    if (isDLLEmpty()) {
        player->next = players_head;
        players_head->next = player;
        players_head->prev = player;
        return 1;
    }

    // insert the new player at the beginning of the list
    players_head->next->prev = player;
    player->next = players_head->next;
    players_head->next = player;
    return 1;
}



// End of players list implementation (circular doubly linked list w/ Sentinel)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。