Miniatures/Board Game NPC Generator - how to go about it?

This is a discussion on Miniatures/Board Game NPC Generator - how to go about it? within the C Programming forums, part of the General Programming Boards category; First off, this is my first post, hopefully I'll not sound like a complete idiot, and I hope that the ...

Miniatures/Board Game NPC Generator - how to go about it?

First off, this is my first post, hopefully I'll not sound like a complete idiot, and I hope that the questions I'm asking aren't hard/obtuse/pointless/anything but good questions - I am open to those being possibilities however.

A bit of background for the problem:

I'm writing, as a hobby, a character generator for a Pen and Paper skirmish game that has a campaign element, so things happen after each battle in terms of trading and whatnot (this is just given as a background, not really the crux of the problem).

One of the things players can do is hire in characters to fight for them: there are numerous types of character, each made up from standard statistics (represented in a "statline"), with certain numbers of "advances", which are either skills or improvements to the aforementioned statline. These advances are determined by rolling dice and comparing the result to a table. Certain results require the dice to be rolled again and compared to a further table. The only limits to what can be taken are that any skill can only be taken once, and advances can only be taken a certain number of times for each statistic. This means that if a character had 6 advances, they could end up with 6 skills, or none, or anything in between, with the remaining advances displayed in the statline.

My current imagining for the program consists of the main function "opening" the program and asking the user to choose the desired character type, with a do-while ensuring that the choice is valid before moving to a switch-case that selects the function relevant to the desired character.

The desired character function works out the values, referencing a random number generator which resides in a separate function and several switch-case statements to work through the "tables". After each iteration through the advance "table", the number of advances taken is increased by 1, with errors reducing the number by 1 so that the net effect of a "faulty" advance is 0: the entire process is contained in a do-while loop, and when the maximum number of advances are taken it finishes.

The function updates the values in the statline to reflect the advances in it, the skills are listed as strings to be referenced, and then all the relevant information is passed back to main, where it is displayed on screen to the user.

It would preferably look something like:

Code:

Character Name: [Name submitted by user]
Character Type: [Type chosen by user]
Cost: [The standard cost set in the relative function]
Rating: [The standard rating set in the relative function]
M WS BS S T W I A Ld
# # # # # # # # #
[first skill rolled, if any]
[second skill rolled, if any]
[etc.]
[weapon and equipment choices that are up to the user]
[any other relevant information, such as special rules relating to the character, whether they do anything post-game or not, etc.]

The code I have written is a poorly implemented version of the above: I haven't worked through all the advance tables in code, but the random number generator and the main function up until it goes to the external functions are kind of finished.

I took a rudimentary C module a few years ago at uni, so I know a tiny bit about C programming (strings, pointers, multidimensional arrays, random number generation, switch-case, a bit of malloc and using functions other than main(), and generally anything earlier on in any online tutorials, but not structures, unions and higher-end/lesser-known commands), and I'm currently trying to home school myself for all the bits I wasn't taught, as well as try to refresh my memory as to how certain things are supposed to work, namely pointers, arrays and malloc (and memory allocation in general).

After all that, my queries that I'd like help on are:

Can arrays store entire strings in one reference, as in advance[3]="lightning reflexes", or is it, as I seem to remember, only single characters, as in advance[1]="l", advance[2]="i", advance[3]="g" etc.? If the latter case is true, how can I make an advance be counted as a skill rather than a statline advance?

I'm hoping to make the output data not include "empty skill placeholders", but rather allocate skills to some "skill storage", to be called out when they're selected. I've thought about setting "flags" for the skills (1 for the skill is an advance, 0 for it isn't) and printing the correct ones to screen through if statements, but I'm not keen on having every skill written out for testing in if statements; it seems as though there should be an easier way to do it, but I can't see one at the moment.

Is it OK memory-usage wise to have the random number generator as a single external function being called every time, or should I somehow create an array of random numbers? If I create the array, how do I ensure that if a value occurs that doesn't make the character generator work correctly, and how do I make it find more random numbers to make the extra advance required?

Would structures (and unions?) be useful in this program? They seem to be useful for storing certain type allocations and setting initial values to be referenced throughout the program, but not much else. If they could be used to contain the advances, maybe they'd be more useful, but I don't have much experience with them.

Should I declare all of the variables in main with pointers in my other functions, since all the variables will inevitably be input to main (with the exception of the random number generator), or declare them in the other functions and have pointers in main, or should I declare all my variables as global? I've forgotten the main ramifications of global declarations beyond them hogging memory throughout the use of the program, so I'm sceptical about making them global.

Is there anything I might have to think about that I've missed, or any solution/alternative I haven't thought of? Although I have started writing code, I'd rather like to get the "proper" way I should do things before writing any more, since I started to see that I could have some problems later.

I don't know much about your game, but in most games, structures are handy to keep each player's data, all bunched together, and organized.

Like you, I'm a hobby programmer, and have never found much use for unions, in anything. RAM just isn't that critically short, and the bother of unions is at least as great as the convenience, for me.

In C all strings are simply char's, which are elevated to string status WHEN THE END OF STRING char '\0', is appended to the end. No EOS char -- no string.

Pointers are frequently used to work with strings, but 2d char arrays are used, as well:

Code:

words[3][10] = {
{ "My"}
{"Name"}
{"is"} };

Pointers are better, but may confuse you at first. If so, use the array notation, as above.

When first initialized, these will all be made into strings (the compiler will add the '\0' to the end of each row). After the initialization, however, the compiler will NOT do this for you!

Here, words[0] == "My", words[1] == "Name", etc.

But comparisons and copying on strings must use the string functions. Direct comparisons aren't possible:

if (words[0] == words[1]) /* not possible, use the string functions instead */

I'd recommend taking your game program, and carefully laying out each function it needs, then deciding on it's input needed (whether global or passed to it), and what it needs to return, if anything, to main(), or whatever function called it.

Then start with some pseudo code, and finally with filling in the pseudo code with some actual code.

Remember, you can have function stubs like this, for the time being:

Code:

int example(void) {
/* should this be a void function? Just a stub example */
return 0;
}

In general, your description is long on the game, and very short on the code part. I can't with your game really, and I can't help much with code questions because you don't have anything to concretely address.

The more specific your questions become, especially with code you've posted which tries to address the problem, the more helpful will be your answers.