#include "com_move.h" #include "room.h" #include "move.h" #include "random_functs.h" #include "stringops.h" typedef struct link_valid_list_elt { link *l; struct link_valid_list_elt *next; } link_valid_list_elt; typedef struct link_valid_list { link_valid_list_elt *head; int size; } link_valid_list; static char word[128]; static link *command_move_random (globals *g) { room_queue_elt *room_visited; link *scan; #ifdef FUNCTIONS puts ("<command_move_random>"); #endif for (room_visited = g->rooms_visited->head; room_visited != NULL; room_visited = room_visited->next) { for (scan = g->room_current->links->head; scan != NULL; scan = scan->next) { if ((scan->dest == room_visited->room) && (random_int () % 2 == 0)) return scan; } } if (g->room_current->links->head != NULL) { return (link_find_num (g->room_current->links, random_int () % g->room_current->links->size + 1)); } else { if (random_int () % g->moveodds == 0) { socket_write (g->socket, g->home_str); room_queue_add (g->rooms_visited, g->room_current, g->movequeuesize); g->room_current = g->room_home; } } return NULL; } static link_valid_list *command_move_valid_list (room_queue *rq, room *r) { link *lscan; room_queue_elt *rscan; link_valid_list *lvl = NULL; link_valid_list_elt *lvle; int flag; #ifdef FUNCTIONS puts ("<command_move_valid_list>"); #endif lvl = allocate (link_valid_list); lvl->head = NULL; lvl->size = 0; for (lscan = r->links->head; lscan != NULL; lscan = lscan->next) { flag = 0; for (rscan = rq->head; rscan != NULL; rscan = rscan->next) { if (lscan->dest == rscan->room) flag = 1; } if (flag == 0) { lvle = allocate (link_valid_list_elt); lvle->l = lscan; lvle->next = lvl->head; lvl->head = lvle; (lvl->size)++; } } return lvl; } static void command_move_valid_list_elements_burn (link_valid_list_elt *lvle) { #ifdef FUNCTIONS puts ("<command_move_valid_list_elements_burn>"); #endif if (lvle != NULL) { command_move_valid_list_elements_burn (lvle->next); free (lvle); } } static void command_move_valid_list_burn (link_valid_list *lvl) { #ifdef FUNCTIONS puts ("<command_move_valid_list_burn>"); #endif command_move_valid_list_elements_burn (lvl->head); free (lvl); } static link *command_move_valid_list_num (link_valid_list *lvl, int n) { link_valid_list_elt *scan; #ifdef FUNCTIONS puts ("<command_move_valid_list_num>"); #endif for (scan = lvl->head; (scan != NULL) && (n > 1); scan = scan->next, n--); return scan->l; } void command_move (globals *g, char *l) { link *link = NULL; link_valid_list *lvl; #ifdef FUNCTIONS puts ("**command_move"); #endif if (g->room_current == NULL) return; if (g->room_current->links->head == NULL) return; l = tokenize (word, l); if (strlen (word) > 0) link = link_find (g->room_current->links, word); if (link == NULL) { if (g->rooms_visited->size > 0) { lvl = command_move_valid_list (g->rooms_visited, g->room_current); if (lvl->size > 0) { link = command_move_valid_list_num (lvl, random_int () % lvl->size + 1); command_move_valid_list_burn (lvl); } else { link = link_find_num (g->room_current->links, random_int () % g->room_current->links->size + 1); } } else link = command_move_random (g); } if (g->movequeuesize > 0) room_queue_add (g->rooms_visited, g->room_current, g->movequeuesize); if (link != NULL) { g->room_current = link->dest; socket_write (g->socket, link->name); } }