MudBytes
Pages: << prev 1, 2 next >>
Tables/Arrays, Need help understanding...
triskaledia
Magician






Group: Members
Posts: 62
Joined: Mar 31, 2009

Go to the bottom of the page Go to the top of the page
#1 Posted Jul 1, 2009, 6:09 pm

I typically try to stray away from tables and arrays, 1) I never got that far into my study, and 2) When i look at it I go what the fuck...
Anyway, I've decided that I need to learn how to use them properly, 1) It is how all the stats are setup to do their respective abilities, and 2) I got to start stepping outside of my coding boundaries...
So, this is the magic missile I have setup...

void spell_magic_missile( int sn, int level, CHAR_DATA *ch,void *vo,int target)
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    static const sh_int dam_each[] =  //Inside the brackets I could set a number to set a max on the following numbers allowed?
    {                                              //So 10 would make it so only 10 numbers could be included?
        0,
        25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
        30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
        35, 35, 35, 35, 35, 40, 40, 40, 40, 40,
        45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
        50, 50, 50, 50, 50, 50, 50, 50, 50, 100
    };
    int dam,i;

    level = UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
    level = UMAX(0, level);

    for(i = 1 + (ch->level / 10) ; i > 0; i--)
    {
        dam= number_range( dam_each[level], dam_each[level] * 2 ); //Is this pulling a random number from the dam_each table where the
          if ( saves_spell( level, victim,DAM_ENERGY) )                      //random number is defined "players level" to "players level * 2"
              dam /= 2;                                                                //and if I wanted to pull a number from the table = to the players level
        damage( ch, victim, dam, sn, DAM_ENERGY ,TRUE);              //I would have to go back and define numbers until I get 100 setup?
    }                                                                                    //Then I would just do dam = dam_each[level]?
  return;
}

I didn't write this, it was a snippet...

Running ROM 2.4 QuickMUD

--Silence Tyire of Reanimation
.........................
--Silence Tyire of Reanimation (Modified QuickMUD)

Justice
Sorcerer




Group: Members
Posts: 310
Joined: May 14, 2006

Go to the bottom of the page Go to the top of the page
#2 Posted Jul 1, 2009, 6:20 pm

Basically the loop initializes i to a starting point using the player's level, and then decrements it until it reaches 0.  This is the total # of hits that you will receive.

Within the loop it generates an arbitrary value using the "level" to lookup a value from the array.  It simply doubles this value to get the range of possible values.

Yes you can simply pull out a constant value from the array if you want.
.........................
In any sufficiently complex system, no one is smart enough to predict every consequence of a seemingly minor change.

quixadhal
Wizard






Group: Members
Posts: 1,256
Joined: Oct 17, 2007

Go to the bottom of the page Go to the top of the page
#3 Posted Jul 1, 2009, 6:26 pm

No, number_range() generates a random number between the lower and upper bound.  If you use the constant value from the array, you get dam_each[level]d1+0 as your damage formula, which is pretty boring.  Of course, I think the way that's done is daft too, but that's another fish.

The ways I prefer to hand things are to either code your damage function to actually take dice parameters (XdY+Z) so you can emulate the damage formulas of AD&D, which is where this stuff originated.... or work out a math function that returns an appropriate value along a slope (or curve), thus eliminating the need to worry about changing all those arrays if you decide to change how many levels your game has.
.........................
http://i302.photobucket.com/albums/nn96/quixadhal/Alelord_banner.png

triskaledia
Magician






Group: Members
Posts: 62
Joined: Mar 31, 2009

Go to the bottom of the page Go to the top of the page
#4 Posted Jul 1, 2009, 7:02 pm

For that AD&D stuff... I don't like the way the dice works... it's quite trivial to me. 1) As I never did AD&D, and 2) The number is always so off from what I'm looking for. Most of my damage values are concrete or use the number_range() to setup a number that I like.

But back to the topic at hand.  So, if I wanted to setup damage values based upon a character level, I could setup 100 numbers within that array
and set level = ch->level and it would pull the designated number from the array?

--Silence Tyire
.........................
--Silence Tyire of Reanimation (Modified QuickMUD)

Davion
Idle Hand




Group: Administrators
Posts: 1,188
Joined: May 14, 2006

Go to the bottom of the page Go to the top of the page
#5 Posted Jul 1, 2009, 7:34 pm

triskaledia said:
So, if I wanted to setup damage values based upon a character level, I could setup 100 numbers within that array
and set level = ch->level and it would pull the designated number from the array?

Yes, but make sure to set the size of the array to 101 to account for zero or use level-1
.........................
http://mudbytes.net/mudbytessignature-davion2.png

Last edited Jul 1, 2009, 7:34 pm by Davion
triskaledia
Magician






Group: Members
Posts: 62
Joined: Mar 31, 2009

Go to the bottom of the page Go to the top of the page
#6 Posted Jul 1, 2009, 8:37 pm


Davion said:
triskaledia said:
So, if I wanted to setup damage values based upon a character level, I could setup 100 numbers within that array
and set level = ch->level and it would pull the designated number from the array?

Yes, but make sure to set the size of the array to 101 to account for zero or use level-1


But would it really be necessary to account for 0 or do level -1 if you start at level 1?
.........................
--Silence Tyire of Reanimation (Modified QuickMUD)

Davion
Idle Hand




Group: Administrators
Posts: 1,188
Joined: May 14, 2006

Go to the bottom of the page Go to the top of the page
#7 Posted Jul 1, 2009, 8:41 pm

Arrays first index is 0. If you want to use the players level as an index, like say, 100. You'd have to set the array to 101 because you wont be using the 0 index. If you set the array size to 100, then you have to use level-1, because you'd be using the 0 index.
.........................
http://mudbytes.net/mudbytessignature-davion2.png

triskaledia
Magician






Group: Members
Posts: 62
Joined: Mar 31, 2009

Go to the bottom of the page Go to the top of the page
#8 Posted Jul 1, 2009, 8:43 pm

So, just like in most coding, the starting number is always 0, then increments from there.
Thanks for all the help.
--Silence Tyire
.........................
--Silence Tyire of Reanimation (Modified QuickMUD)

triskaledia
Magician






Group: Members
Posts: 62
Joined: Mar 31, 2009

Go to the bottom of the page Go to the top of the page
#9 Posted Jul 11, 2009, 10:17 pm

Alright, I believe I have tables down for numbers, but now I'm having an issue with attempting to make a table with string values.

void gem_load (CHAR_DATA * ch)
{
/***/
    stc("Gem loaded.\n\r", ch);

    OBJ_DATA *gem;
//    char buf[512];

    static const sh_int gem_num[] =
    {
        0,
        1,
    };

    static const char gem_name[] =
    {
        "amethyst" "etc etc",
    };

    static const char gem_short[] =
    {
        "small amethyst gem" "small etc etc",
    };

    static const char gem_long[] =
    {
        "A small amethyst beautifully glowing" "A small etc etc beautifully glowing",
    };

    int gnum = number_range(gem_num[0], gem_num[1]);

    gem = create_object (get_obj_index (OBJ_VNUM_RGEM), 0);
    gem->name = gem_name[gnum];
    gem->short_descr = gem_short[gnum];
    gem->description = gem_long[gnum];
    gem->timer = -1;
    gem->cost = number_range(100, 500);
    gem->weight = number_range(1,3);
    gem->level = ch->level;

    obj_to_char (gem, ch);
/***/
    return;
}

I get these warnings:
fight.c:4776: warning: assignment makes pointer from integer without a cast
fight.c:4777: warning: assignment makes pointer from integer without a cast
fight.c:4778: warning: assignment makes pointer from integer without a cast

Those warnings come from where the name/short/long are setup.
Right now, it appears to load the object to the char, because it crashes the mud on quit/reboot/copyover.
I'm assuming because the warnings are actually errors.
As always, any help is always appreciated.

--Silence Tyire
.........................
--Silence Tyire of Reanimation (Modified QuickMUD)

bbailey
Magician






Group: Members
Posts: 91
Joined: Jun 7, 2006

Go to the bottom of the page Go to the top of the page
#10 Posted Jul 12, 2009, 8:59 am


triskaledia said:
Alright, I believe I have tables down for numbers, but now I'm having an issue with attempting to make a table with string values.

    static const char gem_name[] =
    {
        "amethyst" "etc etc",
    };

    static const char gem_short[] =
    {
        "small amethyst gem" "small etc etc",
    };

    static const char gem_long[] =
    {
        "A small amethyst beautifully glowing" "A small etc etc beautifully glowing",
    };

Those warnings come from where the name/short/long are setup.
Right now, it appears to load the object to the char, because it crashes the mud on quit/reboot/copyover.
I'm assuming because the warnings are actually errors.
As always, any help is always appreciated.

--Silence Tyire


Code (text):
1
2
3
4
5
6
7
8
9
10
11
 
static const char aString[] = "This is a constant static string.";
 
static const char *arrayOfStrings[] = {
  "This is an array of constant static strings.",
  "Another string.",
  "Yet another string."
};
 
.........................
Bobby Bailey
Wynn@Tir na nOg
Chilalin/Chil/Alecksy@ElseMU*

triskaledia
Magician






Group: Members
Posts: 62
Joined: Mar 31, 2009

Go to the bottom of the page Go to the top of the page
#11 Posted Jul 12, 2009, 1:04 pm

Alright, that loads the proper gem, with all the proper values and doesn't cause a crash. Thank you.
Is there a set reason why there has to be an asterix besides the char name to make the table work properly?

I do get these warnings:
fight.c: In function âgem_loadâ:
fight.c:4776: warning: assignment discards qualifiers from pointer target type
fight.c:4777: warning: assignment discards qualifiers from pointer target type
fight.c:4778: warning: assignment discards qualifiers from pointer target type

--Silence Tyire
.........................
--Silence Tyire of Reanimation (Modified QuickMUD)

bbailey
Magician






Group: Members
Posts: 91
Joined: Jun 7, 2006

Go to the bottom of the page Go to the top of the page
#12 Posted Jul 12, 2009, 1:31 pm

triskaledia said:
Alright, that loads the proper gem, with all the proper values and doesn't cause a crash. Thank you.
Is there a set reason why there has to be an asterix besides the char name to make the table work properly?

--Silence Tyire


The asterisk denotes that it is a pointer. In C, a string is an array of characters. Strings are frequently accessed through pointers to a character which point to the memory location of a character in the array.

You may create a string by explicitly initializing an array of characters.
Code (text):
1
2
3
char myString[] = "some string";



You can also implicitly create an array of characters by initializing a pointer to a character with that string.

Code (text):
1
2
3
4
5
 
char *myString = "some string";
 


When you do this, you are still creating an array of characters, and the pointer is initialized to point to the address of the first character in the array.

Code (text):
1
2
3
4
5
6
7
8
9
 
char myString[] = "some string"; // Explicitly create an array of characters
char *stringPointer = &myString[0]; // Make stringPointer point to the first character in myString
char *stringPointerTwo = "some string";  // Implicitly create an array of characters and make stringPointerTwo point to the first character
// stringPointer and strPointerTwo now each point to a different character array
// containing "some string" and will show as equal when comparing with string functions, e.g., strcmp()
 



For your tables, you were creating an array of strings, which are themselves arrays. So you need to either do that explicitly:

Code (text):
1
2
3
4
5
6
7
8
9
 
static const char myArraryOfCharacterArrays[][] = {
   "String1",
   "String2",
   "String3'
}
 


or implicitly using character pointers:

Code (text):
1
2
3
4
5
6
7
8
9
 
static const char *myArrayOfStringPointers[] = {
   "String1",
   "String2",
   "String3"
}
 


Understanding the relationship between characters, character pointers, and character arrays is crucial to properly manipulating strings in C.
.........................
Bobby Bailey
Wynn@Tir na nOg
Chilalin/Chil/Alecksy@ElseMU*

Last edited Jul 12, 2009, 1:45 pm by bbailey
triskaledia
Magician






Group: Members
Posts: 62
Joined: Mar 31, 2009

Go to the bottom of the page Go to the top of the page
#13 Posted Jul 12, 2009, 6:05 pm

Alright, getting a little better at this whole array/table thing. I've managed to pull the following arrays out of my function gem_load in fight.c, and got them placed inside of tables.c so that I can call them from any part of the code.
    const sh_int gem_num[] =
    {
        0,  1,  2,
        3,  4,  5,
        6,  7,  8,
        9,  10,
    };

    const char *gem_name[] =
    {
        "aquamarine gem", "diamond gem", "emerald gem",
        "opal gem", "pearl gem", "ruby gem",
        "sapphire gem", "spinel gem", "topaz gem",
        "skull", "bones",
    };

    const char *gem_short[] =
    {
        "a small aquamarine", "a small diamond", "a small emerald",
        "a small opal", "a small pearl", "a small ruby",
        "a small sapphire", "a small spinel", "a small topaz",
        "a small skull", "a small set of bones",
    };

    const char *gem_long[] =
    {
        "A small aquamarine beautifully glowing", "A small diamond beautifully glowing", "A small emerald beautifully glowing",
        "A small opal beautifully glowing", "A small pearl beautifully glowing", "A small ruby beautifully glowing",
        "A small sapphire beautifully glowing", "A small spinel beautifully glowing", "A small topaz beautifully glowing",
        "A small skull glowing faintly", "A small set of bones",
    };

Now, I'm looking to remove the warnings I get when setting the gem->name, gem->short_descr, and gem->description:
  warning: assignment makes pointer from integer without a cast
I did some searching on google to see what the error meant. Only found one site that helped and it described the warning as me places a value different than what the variable calls for... I understood it to say since I'm calling  sh_int gem_num to setup all the char values of gem-> that it's calling a warning.
    int gnum = number_range(gem_num[0], gem_num[10]);
    gem->name = gem_name[gnum];
    gem->short_descr = gem_short[gnum];
    gem->description = gem_long[gnum];
That's how I have it coded... Is there anyway to remove this warning, or as the rest of my warnings that don't seem to really ruin any part of my code, am I stuck with it forever? Also, is the way I have it setup bad coding?
--Silence Tyire
.........................
--Silence Tyire of Reanimation (Modified QuickMUD)

bbailey
Magician






Group: Members
Posts: 91
Joined: Jun 7, 2006

Go to the bottom of the page Go to the top of the page
#14 Posted Jul 13, 2009, 8:37 am

triskaledia said:

Now, I'm looking to remove the warnings I get when setting the gem->name, gem->short_descr, and gem->description:
  warning: assignment makes pointer from integer without a cast
I did some searching on google to see what the error meant. Only found one site that helped and it described the warning as me places a value different than what the variable calls for... I understood it to say since I'm calling  sh_int gem_num to setup all the char values of gem-> that it's calling a warning.
    int gnum = number_range(gem_num[0], gem_num[10]);
    gem->name = gem_name[gnum];
    gem->short_descr = gem_short[gnum];
    gem->description = gem_long[gnum];
That's how I have it coded... Is there anyway to remove this warning, or as the rest of my warnings that don't seem to really ruin any part of my code, am I stuck with it forever? Also, is the way I have it setup bad coding?
--Silence Tyire


First, I'd check to make sure you're following the convention for assigning strings in your codebase. Most assign some sort of copy (using strdup, str_dup, or some other function or macro) rather than just assigning the strings directly to name/short_descr/description. E.g., most ROM derivatives would do "gem->name = str_dup(gem_name[gnum]);"

If you're still having trouble after checking on that and sorting it out, then it would be helpful to post the exact error/warning messages and the specific lines of code referenced by those messages. Typically you see that warning when trying to assign a string to a character.

Code (text):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
bobby@dev1:~$ cat test.c
int main(void) {
   char *myString = "a string";
   char myChar = '\0';
   myChar = myString;    // Can't assign a string (character array) to a character.
   return 0;
}
bobby@dev1:~$ gcc test.c
test.c: In function 'main':
test.c:4: warning: assignment makes integer from pointer without a cast
bobby@dev1:~$ 
 
.........................
Bobby Bailey
Wynn@Tir na nOg
Chilalin/Chil/Alecksy@ElseMU*

Kline
Sorcerer




Group: Members
Posts: 442
Joined: Dec 14, 2007

Go to the bottom of the page Go to the top of the page
#15 Posted Jul 13, 2009, 10:05 am

triskaledia said:

    const sh_int gem_num[] =
    {
        0,  1,  2,
        3,  4,  5,
        6,  7,  8,
        9,  10,
    };


Not related to your string issues: but why a table of sequential ints? I'm not certain I understand the use. If you're using it solely for that number_range call, you could more easily use two defines of GEM_MIN and GEM_MAX as 0 and 10 respectively.
.........................
AckFUSS -- Check it out.

Pages:<< prev 1, 2 next >>

Valid XHTML 1.1! Valid CSS!