Author Topic: Newbie programming Q's  (Read 17850 times)

xee

  • Newcomer
  • Posts: 6
  • Karma: +0/-0
    • View Profile
Newbie programming Q's
« on: June 17, 2012, 02:23:32 PM »
Hey guys, I'm excited to have stumbled upon these forums!  I decided a couple months ago to take up a programming language (windows assembly) and to keep things interesting I started working on a rogue variant from the very beginning to help me learn.  I have a couple questions though:

How do you keep track of everything in the game, do you keep everything in seperate tables?  For instance my tables looks like this right now:

2 columns, each field DWORD in size:

Main table:
# mobs, pStruct (pointer to a table of existing structures)
X|Y, pChar (pointer to a char sheet of X,Y)
X|Y, pChar (pointer to a char sheet of X,Y)
X|Y, pChar (pointer to a char sheet of X,Y)
...
...
etc.

pStruct:
# structures, Reserved
RoomX|RoomY,RoomW|RoomH  (each are WORD size)
Wall_X|Wall_Y,pChar pointer (pointer to char sheet of wall)
Wall_X|Wall_Y,pChar pointer (pointer to char sheet of wall)
Wall_X|Wall_Y,pChar pointer (pointer to char sheet of wall)
...
etc.

pChar: 1 column, DWORD in size
pointer to name/race id
symbol
color
MobID - unique id# for this mob (word size each: # area it belongs to|# obtained from a loop counter)
STR|INT|DEX|CON  (1 byte each)
HP|CURRHP  (word size each)
status code - 0:dead, 1:normal, 2:in_combat, 3:fatality
weapon/armor/item codes
pointer to personal memory->
  DWORD == # steps to an encounter/item/etc
  DWORD == pointer to char sheet of encounter/item/etc.


(if pChar was for an item/structure instead of a mob, fields other than nameptr, symbol and color would have different meanings)

Is this a good approach to have every mob and item in the game to have their own personal record/character sheet?  Should I be concerned how much memory I'll be taking up?

Also after a lot of head banging and hair pulling I finally have my collision detection an pursuit code up and running somewhat, just wondering though are there standard algorithms for such things?

Also is there a standard database of monsters/items for roguelikes I could use as well?

Thanks for any info!

Niautanor

  • Newcomer
  • Posts: 2
  • Karma: +0/-0
    • View Profile
    • Email
Re: Newbie programming Q's
« Reply #1 on: June 18, 2012, 08:01:22 AM »
I have never seen this language before and I have the feeling, that many people here aren't familiar with it either.

May I ask, why you started with it and not something a little bit more high level like Java or C++?

Alex E

  • Rogueliker
  • ***
  • Posts: 118
  • Karma: +0/-0
    • View Profile
    • Email
Re: Newbie programming Q's
« Reply #2 on: June 18, 2012, 08:50:58 AM »
I'm not sure how exactly you're doing everything aside from what you put, but I can offer you a bit of insight based on my experiences.

You probably don't have to worry about memory when it comes to the stats of enemies. How many enemies are going to be spawned at once? If there is a maximum of 50 (which is usually plenty enough for many roguelikes), then you probably wouldn't use many variables for their stats and such. If the game is set in a multi-leveled dungeon, then you wouldn't need that many enemies, unless your roguelike is meant to have tons of them. If you want enemies to save depending on the area, then you could have the game create a text document filled with the values of that level, and just load/save it when entering/exiting areas.

I don't think that you need to worry about whatever your collision detection is or how you're doing it (unless you're looping through all of the tiles in the area or something, since you really only need to check the tile you're going to).

The amount of tiles in an area can actually slow the game down. If you want REALLY big levels, then I'd recommend saving the tiles into a text document, and loading them when you get to the specific part of the area that uses them.

Again, I really don't think that you have to worry about the amount of memory you're using up for enemy stats. For me, the actual level (assuming is large) and enemy AI is usually the memory problem :).
« Last Edit: June 18, 2012, 08:53:14 AM by Mosenzov »

guest509

  • Guest
Re: Newbie programming Q's
« Reply #3 on: June 18, 2012, 08:57:45 AM »
Ah data structures. Fun times.

Generally the map information is kept in a 2 dimensional array. Here is a discussion of it.
http://roguebasin.roguelikedevelopment.org/index.php/Data_structures_for_the_map

As far as using too much memory I don't think it will be an issue, not with a Roguelike. I could be wrong. You only really need to track instances on that level, right? Things on other levels can just be saved and reloaded if you go back to that level. Or you can just not allow revisiting levels or randomly create a level each time and get around the whole saving/persistence issue.

For a data base of items and what not you can get an old D&D manual. You can google free ones to download. If you want a classic approach you can go here, it lists all the stuff in the original Rogue.
http://userpages.monmouth.com/~colonel/rvm.html

OR you can google the Nethack and Crawl wikis and be blown away by the number of items and monsters. At some point you want to figure out if you want a game with tons and tons of stuff or a game with a few things done very very well (like in Brogue).

If you can figure out what Pender did with Brogue in regards to pursuit and AI you'd be on the right track. There are some articles here as well.

http://roguebasin.roguelikedevelopment.org/index.php/Articles

  My guess is you are looking for something more complex then the old (If target.x > monster.x then monster.x = monster.x + 1) following style. :-)

Good luck man. Never heard of Windows Assembly.

Ancient

  • Rogueliker
  • ***
  • Posts: 453
  • Karma: +0/-0
    • View Profile
Re: Newbie programming Q's
« Reply #4 on: June 18, 2012, 10:04:32 AM »
Hey guys, I'm excited to have stumbled upon these forums!  I decided a couple months ago to take up a programming language (windows assembly) and to keep things interesting I started working on a rogue variant from the very beginning to help me learn.

Greetings and welcome to the RogueTemple!

My guess is you use MASM and it is not your first programming language. You choose it because you want some challenge and a roguelike game seems like a neat thing to do in it. The newbie in thread topic indicates newbieness in writing a roguelike, not in programming. Otherwise what sense sticking to assembly would have?

Before I respond with my comments on data structures: my assembler of choice is Netwide Assembler (NASM). I view MASM as insufficient because it is limited to Microsoft. Most of my experience is with NASM. It should apply but be wary of subtle differences cropping up here and there.

How do you keep track of everything in the game, do you keep everything in seperate tables?

Yes, most of static data is kept in tables, even autogenerated stuff. Item types, monster races, spell and effect data. That kind of stuff. However at runtime monsters, item stacks and special terrain features are kept in linked lists because these are sparse on the given dungeon level. The map structure has tables that cache what monster/item stack/feature is there to speed up display.

HP|CURRHP  (word size each)

To avoid problems with checking for negative HP you can store HP and DMGTAKEN. When DMGTAKEN >= HP monster is dead.

status code - 0:dead, 1:normal, 2:in_combat, 3:fatality

First two are sufficient. At least I haven't seen a roguelike using more than those two.

Is this a good approach to have every mob and item in the game to have their own personal record/character sheet?

Probably not. PRIME has this. Every monster has its stats rolled and has skills. Most of that depth is neither used nor shown to the player so it is a potential complexity that is close to useless in the end. I would not bother with it unless you have specific plans how to take advantage of it.

Should I be concerned how much memory I'll be taking up?

Not really. PRIME generates all game levels up front (but does not populate them with monsters until player visits them) and uses less than 4 MB of memory.

Also after a lot of head banging and hair pulling I finally have my collision detection an pursuit code up and running somewhat, just wondering though are there standard algorithms for such things?

Ha, it is not going to get any easier in future. Respect for undertaking up such a difficult language to learn. Someone made a roguelike game in Prolog so maybe just maybe there will be one in assembly too thanks to you.
Michał Bieliński, reviewer for Temple of the Roguelike

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: Newbie programming Q's
« Reply #5 on: June 18, 2012, 07:19:27 PM »
I think there is a place for assembly language even today, but it's not in game programming. Higher level language is better. You need to know a lot about programming to use assembly, otherwise you'll probably just waste your time.

xee

  • Newcomer
  • Posts: 6
  • Karma: +0/-0
    • View Profile
Re: Newbie programming Q's
« Reply #6 on: June 19, 2012, 02:11:56 AM »
May I ask, why you started with it and not something a little bit more high level like Java or C++?

For some reason or another I've found C++ to have a much higher learning curve than assembly. Moving bits around registers can be tedious, but it's pretty straightforward and no-nonsense,  but OO concepts I just find difficult to grasp and it just makes my head spin.

You probably don't have to worry about memory when it comes to the stats of enemies. How many enemies are going to be spawned at once?

Right now I'm playing with the idea of have invading hordes of enemies you eventually have to deal with.  And so far I have their data structure mirror your own, they have their own stats, weapons, armor, etc.  I like to have lots of in-fighting as well with the different races, so they'll probably have their own XP and character levels as well.

Quote
I don't think that you need to worry about whatever your collision detection is or how you're doing it (unless you're looping through all of the tiles in the area or something, since you really only need to check the tile you're going to).

I didn't know about tiles until I started reading this forum, I might consider implementing that.  For now I actually have my mobs just plotted at random X,Y coords in the area and they pretty much have the freedom to walk onto any X,Y on the screen.  Mobs are often misaligned when standing next to each other and next to doorways which is more problematic.  My collision detection routine does loop through all the X,Y's in the area, and using their font width and height, tries to calculate if an X,Y is safe to venture onto. 

As far as using too much memory I don't think it will be an issue, not with a Roguelike. I could be wrong. You only really need to track instances on that level, right? Things on other levels can just be saved and reloaded if you go back to that level.

You're probably right, if anything memory leaks are probably going to be my bigger concern than running out of memory :)

Quote
OR you can google the Nethack and Crawl wikis and be blown away by the number of items and monsters. At some point you want to figure out if you want a game with tons and tons of stuff or a game with a few things done very very well (like in Brogue).

Wow, lots of good stuff on the wiki, thanks for the heads up!

Greetings and welcome to the RogueTemple!

Thanks!

Quote
My guess is you use MASM and it is not your first programming language. You choose it because you want some challenge and a roguelike game seems like a neat thing to do in it.

Yes, I've played with asm before back in the days of DOS using Borland's TASM, more so than any other language so it didn't take long to pick up from where I left off.  Coding with the windows API and with the boatload of macros available in MASM it almost feels like a high level language at this point!

Quote
Before I respond with my comments on data structures: my assembler of choice is Netwide Assembler (NASM). I view MASM as insufficient because it is limited to Microsoft. Most of my experience is with NASM. It should apply but be wary of subtle differences cropping up here and there.

I've heard NASM and FASM are good alternatives to MASM, could they all assemble from the same source code with little or no modification?

status code - 0:dead, 1:normal, 2:in_combat, 3:fatality

Quote
First two are sufficient. At least I haven't seen a roguelike using more than those two.

I have it coded this way for now, because normally my mob would just move in random directions.  But that changes if the status code is in_combat, and if the target is not in range, he will try to move in your general direction to track you down.

Is this a good approach to have every mob and item in the game to have their own personal record/character sheet?

Quote
Probably not. PRIME has this. Every monster has its stats rolled and has skills. Most of that depth is neither used nor shown to the player so it is a potential complexity that is close to useless in the end. I would not bother with it unless you have specific plans how to take advantage of it.

I was thinking it may be more realistic if monsters had some individuality to them, ie their own stats, some would be stronger/faster than others, using their own variety of armor pieces and weapons and inventory.

Also after a lot of head banging and hair pulling I finally have my collision detection an pursuit code up and running somewhat, just wondering though are there standard algorithms for such things?

Quote
Ha, it is not going to get any easier in future. Respect for undertaking up such a difficult language to learn. Someone made a roguelike game in Prolog so maybe just maybe there will be one in assembly too thanks to you.

Assembly programming really seems have fallen by the wayside but there's lots of fun stuff that can still be done with it!

I think there is a place for assembly language even today, but it's not in game programming. Higher level language is better. You need to know a lot about programming to use assembly, otherwise you'll probably just waste your time.

For large scale projects, you're probably right on the money.  But since I'm already somewhat familiar with asm, I decided to stick with that instead of trying to learn another language from scratch.  Actually programming for Windows was almost like starting all over again but the windows api really took out a lot of the grunt work to get something up and running coding in asm.

guest509

  • Guest
Re: Newbie programming Q's
« Reply #7 on: June 19, 2012, 12:30:15 PM »
  I know what you mean about OO programming. When I was doing C++ in college I could never get my brain around it. This, and a weakness in calculus, prompted a switch to an academic direction much more in synch with my aptitudes. I later found out it was because of the implementation. I was always so worried about the nuts and bolts I didn't quite understand the overarching concept. I still don't, really.

  Since I gave up on being a serious programmer and switched to Gamemaker I finally understand, a bit, about OO. Gamemaker is totally object (instance) + event based. So now I get it, but only how to USE it, not how to CREATE it.
 
  Also, Krice and Ancient are very good programmers that have managed large roguelikes (Teemu/Kaduria and Prime, respectively). I pretty much differ to them when things get technical.

Z

  • Rogueliker
  • ***
  • Posts: 905
  • Karma: +0/-0
    • View Profile
    • Z's Roguelike Stuff
Re: Newbie programming Q's
« Reply #8 on: June 19, 2012, 01:30:21 PM »
Probably you need to understand data structures first before you can learn OO.

Anyway, the more programming languages you know, the easier it is to learn new ones. Since you already know assembly, it should be straightforward to learn C.  And you get lots of useful things. And don't forget that C++ is a superset of C and even if you don't use OO, some things are much easier in C++ than in C.

Code: [Select]
weapon *weapon::reduce() {
  if(type == WT_BLADE && size > 4 && (size % 4 == 0))
    return new weapon(color, 4 * (size / 8), WT_BLADE);
  else if(type == WT_BLADE && size > 12 && (size % 3 == 0))
    return new weapon(color, size/3 - 3, WT_DIV);
  else if(type == WT_BLADE && (size % 3 == 1) && size >= 2 && color < HCOLORS)
    return new weapon(color, size/3, WT_SHLD);
  else if(type == WT_BLADE && size >= 3)
    return new weapon(color, size/3, WT_MSL);
  else if(type == WT_BLADE && size == 2)
    return new weapon(color, size/2, WT_BLADE);
  else if(type == WT_MSL && (size % 2 == 1) && size >= 3)
    return new weapon(color, size/2, WT_MSL);
  [33 cases in total]
  else return NULL;
  }

Here is an snippet from Hydra Slayer (C++). It creates the new weapon based on an old one, for example the first "if" says that if want to reforge a blade of size s which is divisible by 4 and greater than 4, then we get a blade of size 4*(s/8). How would you do that in assembly? As far as I remember, you cannot write expressions in assembly, so you would get something much less readable, and much harder to maintain. This is OO, but it helps just a bit (without OO I would have to refer to a specific weapon w: "w->type", "w->size" and "w->color" instead of "type", "size" and "color").

If your answer is indeed much complicated, then you probably should switch to C++ or maybe even something higher level.

scaught

  • Newcomer
  • Posts: 18
  • Karma: +0/-0
    • View Profile
Re: Newbie programming Q's
« Reply #9 on: June 19, 2012, 05:35:01 PM »
Code: [Select]
oh god my eyes
...and that, ladies and gentlemen, is how a C programmer codes in C++.

If you were actually writing OO code, your weapons wouldn't just be distinguished by an enum, they'd be subclasses.  If you find yourself writing massing switch statements, or massive if/else clauses, you're probably doing something 'wrong'. (semantics being what they are, you can take that to mean whatever you want)

Quote
without OO I would have to refer to a specific weapon w: "w->type", "w->size" and "w->color" instead of "type", "size" and "color"
Er, to be honest, w->type is just as OO irrelevant as internally referencing variables...w->type() (with the inference of inheritence) would be the only way to actually imply OO-ness.

Also, reduce() is acting like a factory call for some reason?  Hello over-complicated memory management -- you're just begging for memory leaks.  Why can't a weapon reduce itself?  And if you need both copies, clone() it first and then reduce one? 

Also, why does your class type look like a variable name?  And even when you have 1 line conditionals, it's still recommended to put {} around them.  And to only have one return path from a function.  And your spacing is horrible.  And your code will cause an exception if size is negative. And...and...and...

Ship games.  It's what's important.  But sometimes do it with class. :)

xee

  • Newcomer
  • Posts: 6
  • Karma: +0/-0
    • View Profile
Re: Newbie programming Q's
« Reply #10 on: June 19, 2012, 06:14:35 PM »
Er, to be honest, w->type is just as OO irrelevant as internally referencing variables...w->type() (with the inference of inheritence) would be the only way to actually imply OO-ness.

Also, reduce() is acting like a factory call for some reason?  Hello over-complicated memory management -- you're just begging for memory leaks.  Why can't a weapon reduce itself?  And if you need both copies, clone() it first and then reduce one?  

Also, why does your class type look like a variable name?  And even when you have 1 line conditionals, it's still recommended to put {} around them.  And to only have one return path from a function.

OMG I have no idea what you just wrote :)

Here's the first few lines of my code that populates the fields of your character '@':
Code: [Select]

STATS STRUCT
    raceidptr   DWORD ?    
    symb        DWORD ?
    color       DWORD ?
    attribs     DWORD ?     ;STR INT DEX CON
    weaponptr   DWORD ?
STATS ENDS  

human STATS <MOBTYPE_text1,'@',COLOR_SNOWWHITE,01100011011000110110001101100011b,dagger1>    ;6d3 all stats
goblin STATS <MOBTYPE_text2,'g',COLOR_CHARTREUSE,01000100010001000100010001000100b,barehanded1>  ;4d4 all stats

barehanded1 DWORD WEAPONTYPE_text1a,'|',COLOR_SNOWWHITE,00010011b,WEAPONTYPE_text1b    ;1d3
dagger1 DWORD WEAPONTYPE_text2a,'|',COLOR_SNOWWHITE,00010100b,WEAPONTYPE_text2b        ;1d4

MOBTYPE_text1 db "a human",0
MOBTYPE_text2 db "a goblin",0

WEAPONTYPE_text1a db "barehanded",0
WEAPONTYPE_text1b db "punch",0
WEAPONTYPE_text2a db "a dagger",0
WEAPONTYPE_text2b db "pierce",0
WEAPONTYPE_text3a db "a longsword",0
WEAPONTYPE_text3b db "slash",0
...
...
    invoke HeapAlloc,hTable,NULL,128
    mov [esi+16],eax                        ;Setup first LocalTable
    mov esi,eax

    invoke HeapAlloc,hTable,NULL,64         ;Setup Character Sheet
    mov pChar,eax
    mov [esi+12],eax
    push esi
    mov esi,[esi+12]                        ;load Char sheet
    mov eax,[human.raceidptr]
    mov [esi],eax                           ;->"human"
    mov eax,[human.symb]
    mov [esi+OFFSET_CHARSYMB],eax           ;'@'
    mov eax,[human.color]
    mov [esi+OFFSET_CHARCOLOR],eax          ;SNOW 3
    mov eax,[human.weaponptr]
    mov [esi+OFFSET_WEAPON],eax
    mov DWORD ptr [esi+OFFSET_ALLEGIANCE],1
    mov DWORD ptr [esi+OFFSET_STATUS],1
    mov eax,1
    shl eax,16
    mov ax,1
    mov [esi+OFFSET_CHARMOBID],eax          ; area 1|id# 1
    invoke HeapAlloc,hTable,HEAP_ZERO_MEMORY,96 ;create space for personal memories
    mov [esi+OFFSET_MOBMEM],eax
    lea ebx,[eax+12]
    mov [eax+OFFSET_MOBMEM_DMGMSG],ebx    
    invoke DiceRoll4,human.attribs
    mov [esi+OFFSET_CHARSTATS],eax          ;STR|INT|DEX|CON
    movzx eax,al                            ;isolate CON stat
    push ax
    shl eax,16
    pop ax                                  ;Normally HP==CON*LVL
    mov [esi+OFFSET_HPCURRHP],eax           ;HP|Current HP
    
    pop esi                                 ;->LocalTable
     
Here I'm just filling in the fields of a memory block with appropriate values of my character and it's basically the template used for all the monsters in the game. How would this look in proper C++ syntax out of curiosity?  Just wondering if it's more or less code and if it's truly more self explanatory.
« Last Edit: June 19, 2012, 06:20:31 PM by xee »

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: Newbie programming Q's
« Reply #11 on: June 19, 2012, 10:50:15 PM »
If you were actually writing OO code, your weapons wouldn't just be distinguished by an enum, they'd be subclasses.

Some people say that C++ is not a proper OO language, because you can break the rules. I always thought that a restrictive way of thinking and maybe creators of C++ also did, because they made C++ multi-paradigm.

Z

  • Rogueliker
  • ***
  • Posts: 905
  • Karma: +0/-0
    • View Profile
    • Z's Roguelike Stuff
Re: Newbie programming Q's
« Reply #12 on: June 19, 2012, 11:16:20 PM »
I never meant it to be a good example of OO. Rather an example of C++. C++ is a hybrid language. You can write in OO style, or not. Whatever is more applicable.

If you were actually writing OO code, your weapons wouldn't just be distinguished by an enum, they'd be subclasses.

I have looked at the sources of IVAN, which is done like you recommend: each monster and item is a separate class. But I did not feel convinced. I found it ugly. Class-based OO is not a good paradigm when speaking about roguelikes. Items do not follow a clear, tree-like hierarchy. You can have items or monsters which change into a different type under some circumstances (polymorph), or share the properties of several other items/monsters. You can even have properties which depend on external causes (used equipment). You can even have monsters turning into items (corpses), or items turning into monsters (sticks-to-snakes, necromancy, animated weapons).

Hydra Slayer has just once generic class, with three subclasses (hydra, item, weapon). And that's all OO it needs.

Quote
Also, reduce() is acting like a factory call for some reason?  Hello over-complicated memory management -- you're just begging for memory leaks.  Why can't a weapon reduce itself?  And if you need both copies, clone() it first and then reduce one? 
OK, so you recommend me to have a separate subclass for each weapon type. Moreover, you recommend me to clone a weapon first before reducing it (I need to create a new weapon, because reforging actually means splitting a weapon in two). Note that some rules for reforging change the type. How am I expected to do this when it is a different subclass? Create a new weapon again? And what if it turns out that the weapon cannot be reduced? *That* is begging for memory leaks.

Quote
  If you find yourself writing massing switch statements, or massive if/else clauses, you're probably doing something 'wrong'. (semantics being what they are, you can take that to mean whatever you want)
So OO recommends to have each weapon in a separate class, and have logic related to each weapon type in one place. My solution puts the whole logic related to "reduction" in one place. Both have advantages, but I find the advantages of non-class-based more important.

Quote
Er, to be honest, w->type is just as OO irrelevant as internally referencing variables...w->type() (with the inference of inheritence) would be the only way to actually imply OO-ness.
Yes, that's not very relevant. I only meant that you could not do that in C without OO.

Quote
Also, why does your class type look like a variable name?
You mean that they are both plain lowercase English words? The same convention is used in STL.

Quote
And your code will cause an exception if size is negative.
Why?

Quote
And even when you have 1 line conditionals, it's still recommended to put {} around them.  And to only have one return path from a function.  And your spacing is horrible.   And...and...and...
I have no problems understanding or maintaining this. Also, verbosity (extra {}, extra "else", a separate "reduce" function for each weapon subclass, etc) makes programming much slower.

Z

  • Rogueliker
  • ***
  • Posts: 905
  • Karma: +0/-0
    • View Profile
    • Z's Roguelike Stuff
Re: Newbie programming Q's
« Reply #13 on: June 19, 2012, 11:38:23 PM »
xee, it would look something like:

Code: [Select]

enum Stat { STR, INT, DEX, CON };

struct Race {
  string name;
  char symbol;
  int color;
  int dice[4], sides[4];
  Weapon *wpn;
  };

Weapon barehanded = {"barehanded", '|', COLOR_SNOWWHITE, 1, 3, "punch"};
Weapon dagger = {"dagger", '|', COLOR_SNOWWHITE, 1, 4, "pierce"};

Race human = {"human", '@', COLOR_SNOWWHITE, {6,6,6,6}, {3,3,3,3}, &dagger};
Race goblin = {"goblin", 'g', COLOR_CHARTREUSE, {4,4,4,4}, {4,4,4,4}, &barehanded};

struct Monster {
  Race *race;
  Weapon *weapon;
  bool allegiance, status;
  int id : 4, area : 4;
  char memory[96];
  }

int main() {
  player = new Monster;

  // actually, you would probably put the three lines below into a function
  player->race = human;
  player->weapon = human.weapon;
  for(int i=0; i<4; i++) player->stats[i] = diceroll(human.dice[i], human.sides[i]);

  player->allegiance = true;
  player->status = true;
  player->id = 1; player->area = 1;

  player->hp = player->stats[CON];
  }

Why did you pack data about initial stats in such a strange way ("01100011011000110110001101100011b")? The machine code necessary to unpack it probably takes more bytes than you save.

xee

  • Newcomer
  • Posts: 6
  • Karma: +0/-0
    • View Profile
Re: Newbie programming Q's
« Reply #14 on: June 20, 2012, 06:25:06 AM »
Why did you pack data about initial stats in such a strange way ("01100011011000110110001101100011b")? The machine code necessary to unpack it probably takes more bytes than you save.

It looked like an easy and convenient way to store dice rolls for the initial stats.  So say I have an Ogre race, with brute STR, but dumb as a rock, so-so DEX and decent HP, I'd maybe use the following dice rolls for STR INT DEX CON:

8d3 3d4 4d4 7d3

I can make each die a nibble:

1000 0011 0011 0100 0100 0100 0111 0011

which all conveniently crams into 1 register, which I can then run once through my dice roller function for each Ogre I create:

Code: [Select]
DiceRoll4 PROC USES ebx ecx edx edi Dices:DWORD
        mov ecx,32
        .REPEAT
            mov ebx,Dices           ;contains (4) individual #d# dice rolls in binary form for stats
            sub ecx,8
            shl ebx,cl
            shr ebx,20              ;bh==1st die
            shr bl,4                ;bl==2nd die
            cmp bl,0
            jz @F               
            movzx edi,bl
            mov bl,bh               ;final stat min==1st die since nrandom can generate a 0
            push ecx
            push eax
            .REPEAT
                invoke nrandom,edi
                add bl,al
                dec bh
            .UNTIL (bh==0)
            pop eax
            pop ecx
         @@:mov al,bl
            ror eax,8
        .UNTIL (ecx==0)
        ret                         ;eax==(4) completed dice rolls
DiceRoll4 ENDP       

and now have 4 randomly rolled stats in one register :)