Dan Egli wrote: > void list_languages(struct char_data *ch) > { > char *tmp; > int a = 0, i; > sprintf(buf, "Languages:\r\n"); > for (i = MIN_LANGUAGES; i < MAX_SKILLS; i++) { > if (SPEAKING(ch) == i) sprintf(buf, "*%s", buf); > sprintf(buf, "%-20s %s\r\n", languages[a++], how_good...; > sprintf(tmp, "Itteration: %d, Language: %s\r\n", a+1,...; > send_to_char(tmp, ch); > } > sprintf(buf, "%s\r\n* denotes currently spoken language.\r\n", buf); > send_to_char(buf, ch); > } Let's look at what you're doing really quickly by plugging in values and simulating the loop, shall we? I call this little thing a "loop iteration graph" (I don't know if there's a real name given to it, or even if anyone else in the world bothers to do this), Let MIN_LANGUAGES = 100 and MAX_SKILLS = 106 Let SPEAKING(ch) = 100 (Common) Iteration 1: i = 100 if (100 == 100) buf = "*Languages:\r\n"; /* bug #1 */ buf = languages[0] + " " + how_good(GET_SKILL(ch, 100)); /* #2 */ a += 1; /* since we called a++ in previous sprintf(); a = 1 */ log("Iteration: " + (a+1) + ", " + language[1]); a += 1; /* since we called a++ in previous sprintf(); a = 2 */ OUTPUT: "Iteration: 2, Troll" Iteration 2: i = 101 buf = languages[2] + " " + how_good(GET_SKILL(ch, 101)); a += 1; /* a = 3 */ log(...); a += 1; /* a = 4 */ OUTPUT: "Iteration: 3, Elvish" Iteration 3: i = 102 buf = ...; a += 1; /* a = 5 */ OUTPUT: "Iteration: 6, Dragon" a += 1; /* a = 6 */ . . . (We have a significant sample size) There are a variety of bugs here. First, we're causing a bug with our attempt to discover a bug by having 'a' incremented after both sprintf() statements. My suggestion would be to move the 'a' stuff into the actual for(;;) portion, rather than have it in the block. Hence, for (a = 0, i = MIN_LANGUAGES; i < MAX_SKILL; a++, i++) { if (GET_SKILL(ch) == i) ...; sprintf(buf, "%-20s %s\r\n", languages[a], how_good...; . . . } with 'a' not being incremented within the actual loop code (i.e., no 'a++' statements). The next problem, denoted by "Bug #1" above, is that we call sprintf() with "*%s" and the argument 'buf'. Assuming that our string isn't mangled (it will almost certainly be because buf will be modified before we incorperate it into the sprintf() statement, meaning that we'll likely get "**") or we don't get a crash, we'll at best have "*Languages:" which isn't what we wanted. Rather, if (GET_SKILL(ch) == i) strcat(buf, "*"); /* add * at end of buf */ Next, denoted by "Bug #2", we overwrite the contents of buf with the new ones, rather than append them. What we want to do is, sprintf(buf+strlen(buf), ...); Which will put the new text at the end of buf. If you don't understand how this works, I suggest reading a (good) book on C, one that covers things such as pointer arithematic. Also, with our sprintf(tmp...) thing: we are crashing because tmp is a pointer to a random memory address, not an array. We want "char tmp[MAX_STRING_LENGTH];" rather than "char * tmp;". Recommendations: 1. Get a book covering pointers. There are a lot of mediocre programmers out there that don't understand pointers. Until they get a grasp of the idiosyncrasies of pointers, they'll never take that next step. 2. Desk check your code -- that is, read it once or twice before you even try to compile it. It can save you some time and maybe a few headaches. 3. If you've read over your buggy code a thousand times and things just aren't clicking together in your head, try simulating it using something like a "loop iteration graph", or splitting it up into groups to analyze certain blocks by what function they are supposed to serve. 4. If you have other coders on your MUD, try to establish a "Peer Review" method. In this, each coder would review the other's code -- reading it and writing down (or maybe even fixing) the potential problems. The only danger is if any of your coders aren't mature enough to handle constructive criticism, or give it. As a side note, I would also suggest implementing something like a "Peer Review" group with your builders, by asking them to set aside some time to go through the new areas -- perhaps as three different PC characters (since areas are typically developed for certain level/power characters make it one below the target level range, one of the average of the target level range, and one above the target level range). I realize the quantity of areas produced will go down since builders will have to set aside some time to review one another's areas, but the quality will rise and provide a more enjoyable experience for the players. Note that this isn't necessarily a "quality control" program: you should make it clear that builders aren't going to be ousted if they're not producing high quality areas/descriptions/whatever. The idea is to have each builder help one another. "No man is an island." -dak : Finally got his DVD-ROM to play DVD movies (It came with bad drivers, originally). +------------------------------------------------------------+ | Ensure that you have read the CircleMUD Mailing List FAQ: | | http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html | +------------------------------------------------------------+
This archive was generated by hypermail 2b30 : 12/15/00 PST