Re: [newbie] text based alignment[long]

From: Welcor (welcor@dune.net)
Date: 06/26/02


> i tried to make the score show text based alignment instead of the number,
> so i wrote this piece of code, i'm not any good at it, and got
> declaration terminated incorrectly on every if and else if..
> I have checked the archive and ftp, but i didn't find anything similar..
I'll walk you through this step by step, then.

> char align[MAX_INPUT_LENGTH];
The line above declares 'align' as an array of type 'char' of length
'MAX_INPUT_LENGTH'. What you have at this point is a reserved piece of
memory, and a name for it.

To interact with this particular piece of memory, we have some tools, the
'string' tools.

These include, but are not limited to:
strcpy, strlen, strdup, strncpy, strndup, memcpy, strcat, strcmp, strcasecmp

All of these functions are explained in detail on the GNU C library
overview pages at
  http://www.fsf.org/manual/glibc-2.0.6/html_node/libc_toc.html
under the heading 'string utilities'.

Now, let's see what you wish to do with that piece of memory:
> if (GET_ALIGNMENT(ch) >= 750 && !IS_NPC(ch))

This entire block might better be written as (this one will not work!)
if !(IS_NPC(ch)) {
  if (GET_ALIGNMENT(ch) >= 750)
    do_something(TM);
  else if (GET_ALIGNMENT(ch) <= 749)
    do_something_else(TM);
  etc. etc.
  else
    blah();
}
As you have the IS_NPC() check on all the lines, it's better, and more
readable, to embed the alignment checks in an encompassing IS_NPC() check
as above.

>         align == "Saintly";

Here's where things get sticky:
1. align, when used like this refers to the memory position at the
   beginning of the reserved memory piece above. A hex value could be
   0xde453567 (or whatever the kernel has available when the request
   is made)
2. == is the equality _check_. What you were thinking of putting here
   was the assignment operator =, but that wouldn't work here, because
3. "Saintly" is a constant. This means it occupies a piece of memory,
   which the kernel does not allow you to alter, and it might be
   unavailable just after this line.

In short, you make an equality check between a memory adress in the
functions adress space (align) and a constant in the kernels adress space.

Instead, you need to think in functions. The one you need in this case
is the strcpy() string util, as that one copies an array of characters,
be it constant or not, to a previously reserved array of memory.
This will do the trick:

strcpy(align, "Saintly");

> if (GET_ALIGNMENT(ch) <= 749 && !IS_NPC(ch))
>         align == "Beatific";
> else if (GET_ALIGNMENT(ch) <= 499 && !IS_NPC(ch))
>         align == "Good";
> else if (GET_ALIGNMENT(ch) <= 249 && !IS_NPC(ch))
>         align == "Neutral";
> else if (GET_ALIGNMENT(ch) <= -250 && !IS_NPC(ch))
>         align == "Evil";
> else if (GET_ALIGNMENT(ch) <= -500 && !IS_NPC(ch))
>         align == "Diabolic";
> else //(GET_ALIGNMENT(ch) <= -750 && !IS_NPC(ch))
>         align == "Demonic";
As you'll soon find out if you just do the changes above, you'll run into
another problem. Anyone with an alignment below 750 will get the
'Beatific' message. This is because your logic is twisted;

if (a > 5)
  // write a is over 5
else if (a <= 4)
  // write a is below 5
else
  // you never get here!

What you need is a so-called chained if sentence:

if (a > 5)
  // write a is over 5
else if (a > 4)
  // write a is equal to 5
else
  // write a is below 5


So now, after having dissected your code, I'll just show you how it can be
done:

if (!IS_NPC(ch)) {
  if (GET_ALIGNMENT(ch) >= 750)
    strcpy(align, "Saintly");
  else if (GET_ALIGNMENT(ch) >= 500)
    strcpy(align, "Beatific");
  else if (GET_ALIGNMENT(ch) >= 250)
    strcpy(align, "Good");
  else if (GET_ALIGNMENT(ch) >= -249)
    strcpy(align, "Neutral");
  else if (GET_ALIGNMENT(ch) >= -499)
    strcpy(align, "Evil");
  else if (GET_ALIGNMENT(ch) >= -749)
    strcpy(align, "Diabolic");
  else
    strcpy(align, "Demonic");
}

At this point you'll need to make the score command output this, which can
be done in two ways, depending on which version of circlemud you use;

up til bpl20:
sprintf(buf, "Alignment: %s\r\n", align);
send_to_char(buf, ch);

bpl21:
send_to_char(ch, "Alignment: %s\r\n, align);

> I know this looks amateurish.. but it's the best i can do without taking
> help from someone or something..
> please correct my errors.. :)
This REEKS of not knowing the first thing about code. Before taking on a
project as large as a mud, at least take a few of the online C tutorials.
They may vary in quality, but not spending time with this is no excuse for
making code like what you just posted, and asking 300+ people for help.

Teach yourself C in 20 days:
  http://lib.daemon.am/Books/C/fm/fm.htm
The GNU C library (2.0.6):
  http://www.fsf.org/manual/glibc-2.0.6/html_node/libc_toc.html
The Circle FAQ
  http://www.circlemud.org/cdp/faq/
The WTFAQ:
  http://www.circlemud.org/cdp/wtfaq/

I hope this all helped.

Welcor

--
   +---------------------------------------------------------------+
   | FAQ: http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html |
   | Archives: http://post.queensu.ca/listserv/wwwarch/circle.html |
   | Newbie List:  http://groups.yahoo.com/group/circle-newbies/   |
   +---------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 06/25/03 PDT