static void automap_find_cycles(loc_node *location, automap_path *curpath) { unsigned i; location->touched = TRUE; for(i = 0; i < NUM_DIRS; i++) { loc_node *thisdest = automap_edge_follow(location, i); if(thisdest && thisdest->found) { automap_path newnode; newnode.dir = i; newnode.loc = location; LEadd(curpath, newnode); if(thisdest->touched) { /* Found a cycle! */ int cyclelength = 0; automap_path *p; cycleequation *cycle = NULL; cycleequation newcycle; for(p = curpath; p; p=p->next) { int dir = p->dir; newcycle.var = &(p->loc->outgoing[dir]->guess_length); newcycle.min = &(p->loc->outgoing[dir]->min_length); newcycle.xcoefficient = dirways[dir].deltax; newcycle.ycoefficient = dirways[dir].deltay; LEadd(cycle, newcycle); cyclelength++; if(p->loc == thisdest) { /* Found the relevant endpoint */ if(cyclelength <= 2) /* Ignore two nodes going to each other */ LEdestroy(cycle); else automap_add_cycle(cycle); /* automap_add_cycle gets ownership */ break; } } if(!p) { /* The cycle had already been found */ LEdestroy(cycle); } } else { automap_find_cycles(thisdest, curpath); } LEremove(curpath); } } }
/* Returns true if all interferences have been resolved */ static BOOL automap_resolve_interference(loc_node *center, int effort) { int skip_interferences = 0; int n; while(interferences) { interlist *oldinter = interferences; interlist *i; automap_path *path; int oldcount; oldcount = 0; for(i = oldinter; i; i=i->next) oldcount++; if(skip_interferences >= oldcount) return FALSE; i = oldinter; for(n = 0; n < skip_interferences; n++) i=i->next; path = automap_find_path(i->a, i->b, FALSE); if(!path) return FALSE; interferences = NULL; if(!automap_increase_along_path(path, oldcount, center, effort)) skip_interferences++; LEdestroy(oldinter); LEdestroy(path); } return TRUE; }
/* Nitfol - z-machine interpreter using Glk for output. Copyright (C) 1999 Evin Robertson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. The author can be reached at [email protected] */ #include "nitfol.h" static int tokenise(zword dictionarytable, const char *text, int length, zword *parse_dest, int maxwords, zword sepratortable, int numseparators, BOOL write_unrecognized); static void addparsed(zword *parse_dest, int word_num, int length, int off) { if(zversion <= 4) off+=1; else off+=2; LOWORDwrite(*parse_dest, word_num); *parse_dest+=ZWORD_SIZE; LOBYTEwrite(*parse_dest, length); *parse_dest+=1; LOBYTEwrite(*parse_dest, off); *parse_dest+=1; } static int dictentry_len; static int cmpdictentry(const void *a, const void *b) { return n_memcmp(a, b, dictentry_len); } static zword find_word(zword dictionarytable, const char *word, int length) { zbyte zsciibuffer[12]; int entry_length, word_length; int num_entries; void *p; entry_length = LOBYTE(dictionarytable); dictionarytable++; num_entries = LOWORD(dictionarytable); dictionarytable+=ZWORD_SIZE; if(zversion <= 3) word_length = 4; else word_length = 6; encodezscii(zsciibuffer, word_length, word_length, word, length); dictentry_len = word_length; if(is_neg(num_entries)) { /* Unordered dictionary */ num_entries = neg(num_entries); p = n_lfind(zsciibuffer, z_memory + dictionarytable, &num_entries, entry_length, cmpdictentry); } else { /* Ordered dictionary */ p = n_bsearch(zsciibuffer, z_memory + dictionarytable, num_entries, entry_length, cmpdictentry); } if(p) return ((zbyte *) p) - z_memory; return 0; } #ifdef SMART_TOKENISER struct Typocorrection { struct Typocorrection *next; struct Typocorrection *prev; char original[13]; char changedto[13]; }; struct Typocorrection *recent_corrections; /* Inform requests two parses of each input; remember what corrections we've made so we don't print twice */ void forget_corrections(void) { LEdestroy(recent_corrections); }
static void automap_forget_interference(void) { LEdestroy(interferences); }