Thread overview
Error Report: Internal error: ..\ztc\dt.c 104 - classgen.d
Aug 05, 2004
Walter
Aug 05, 2004
Chris Stevenson
Aug 05, 2004
J C Calvarese
August 05, 2004
I've just started playing around with D and Windows programming (with Petzold's _Programming_Windows_ 5th Ed handy) and I decided to write a D&D (3.5 ed) character generator, to help my mastery of the language.

Anyways, this code here, along with another module (diceroll.d) that compiled
successfully.

I get the error message:
Internal error: ..\ztc\dt.c 104

I'd figure this might help in figuring out the error.  Also, what part of my program is causing it, so I can figure out a workaround thus far.

Thanks,

Chris Stevenson


August 05, 2004
"Christopher Stevenson" <Christopher_member@pathlink.com> wrote in message news:cetlib$1qb7$1@digitaldaemon.com...
> I'd figure this might help in figuring out the error.  Also, what part of
my
> program is causing it, so I can figure out a workaround thus far.

Try deleting code until the minimal code is left that reproduces the error.


August 05, 2004
>
>I'd figure this might help in figuring out the error.  Also, what part of my program is causing it, so I can figure out a workaround thus far.
>
>
>begin 0644 classgen.d

aheh... oops... here:

classgen.d:
----------------------------------------------------------
import std.random;
import std.c.stdio;
import diceroll;

enum {          //PHB character classes
BARBARIAN = 1,
BARD,
CLERIC,
DRUID,
FIGHTER,
MONK,
PALADIN,
RANGER,
ROGUE,
SORCERER,
WIZARD
}
//diceRoll modes

const int NORMAL_ROLL = 3;
const int ELITE_ROLL  = 4;
const int EXCEP_ROLL  = 5;
const int TWINK_ROLL  = 6;

// Yeah, this is a little confusing below.  These integers represent the
relative
// priority of the ability scores, by class.  These are in the order of the
// AbilityScores enum type above, with a lower number indicating a greater
priority.

const int [6] [int.max] abiPriority =
[ [1, 2, 2, 3, 3, 3],    // Barbarian
[3, 2, 3, 2, 3, 1],    // Bard
[3, 3, 2, 3, 1, 2],    // Cleric
[3, 2, 2, 3, 1, 3],    // Druid,
[1, 2, 2, 3, 3, 3],    // Fighter
[2, 2, 3, 3, 1, 3],    // Monk
[2, 3, 3, 3, 2, 1],    // Paladin
[2, 1, 3, 3, 2, 3],    // Ranger
[3, 1, 3, 2, 3, 2],    // Rogue
[3, 2, 3, 2, 3, 1],    // Sorcerer
[3, 2, 2, 1, 3, 3] ];  // Wizard

class Character
{
invariant
{
//Check that the character to be generated is between level 1
//and level 20.

assert (0 < minLevel && minLevel <= maxLevel && maxLevel <= 20);

int totalLevel;
foreach(int level; classLevels)
{
assert(level > 0 && level <= 20);
totalLevel += level;
}
assert(totalLevel <= 20);
}
private:
int [int] classLevels;
int[6] abilityScores;

public:
int minLevel = 1;
int maxLevel = 1;

void pickClass( int c )
{
classLevels[c] = rand() % (maxLevel - minLevel + 1);
}

void pickClass(int[] c)
{
int i;

for (i=0; i < c.length; i++)
classLevels[c[i]] = rand() % ( (maxLevel - minLevel + 1) / c.length);
}

void generateAbilityScores(int rollMode)
{
int[6] priority;
int[6] scores;

int[] chosen = classLevels.keys;

foreach( int c; chosen)
{
for (int stupidCtr; stupidCtr < priority.length; stupidCtr++)
priority[stupidCtr] += abiPriority[c][stupidCtr];
}

Dice dice = new Dice();
dice.diceSize = 6;

switch (rollMode)
{
case NORMAL_ROLL:
dice.diceNum = 3;    // 3d6, straight up
break;

default:                  ///D compiler may not like this
case ELITE_ROLL:
dice.diceNum = 4;    // 4d6, drop lowest
dice.dropLowest = 1;
break;

case EXCEP_ROLL:         // 5d6 drop 2 lowest
dice.diceNum = 5;
dice.dropLowest = 2;
break;

case TWINK_ROLL:         // 6d6, drop 3 lowest, reroll 1s and 2s
dice.diceSize = 4;
dice.diceNum = 6;
dice.dropLowest = 3;
dice.diceMod = 6;
break;
}

dice.rollMultiple (scores[]);

scores.sort;

// This findPriority() turned out a little ugly.  Here's the idea:
// priority[] holds the relative priority of the 6 ability scores,
// with a lower number indicating a more important priority.  findPriority()
// finds the index in priority[] with the smallest number, sets the priority
// of than index to int.max (to remove in from future consideration), and
returns
// that index.  If there's a tie between two or more indicies, findPriority()
// randomly chooses between them.

int findPriority()
{
int lowest = int.max;
int []result;
int indexResult;
foreach (int abiIndex,int current; priority)
if (current <= lowest)
{
if (current < lowest)      // this will also reset result[0]
{                          // if it found a tie before
lowest = current;
result.length = 1;
result[0] = abiIndex;
}
else
{
result.length = result.length + 1;
result[result.length-1] = abiIndex;
}
}
if (result.length > 1)
indexResult = rand() % result.length;

priority[result[indexResult]] = int.max;
return result[indexResult];
}
int scoresIndex;
int i;
for (i=0; i < abilityScores.length; i++)
abilityScores[findPriority()] = scores[scoresIndex++];
return;
}
void printOutput()
{
char[][int] classString;
classString[BARBARIAN]  = "Barbarian";
classString[BARD]       = "Bard";
classString[CLERIC]     = "Cleric";
classString[DRUID]      = "Druid";
classString[FIGHTER]    = "Fighter";
classString[MONK]       = "Monk";
classString[PALADIN]    = "Paladin";
classString[RANGER]     = "Ranger";
classString[ROGUE]      = "Rogue";
classString[SORCERER]   = "Sorcerer";
classString[WIZARD]     = "Wizard";

foreach (int c, int level; classLevels)
printf("     %.*s %d\n" , classString[c] , level);

printf("STR = %d\n", abilityScores[0]);
printf("DEX = %d\n", abilityScores[1]);
printf("CON = %d\n", abilityScores[2]);
printf("INT = %d\n", abilityScores[3]);
printf("WIS = %d\n", abilityScores[4]);
printf("CHA = %d\n", abilityScores[5]);
}
}

/// FOR TESTING ONLY

int main()
{
Character me = new Character();

me.maxLevel = 5;

me.pickClass(FIGHTER);
me.generateAbilityScores(ELITE_ROLL);
me.printOutput();
return 0;
}


August 05, 2004

*sigh* I just figured out my little problem.  I changed a named enum to an unnamed one, did a text replacement for the old name to "int", and forgot to modifiy one little bit of code:

>const int [6] [int.max] abiPriority =

..oops

The D compiler should have caught that one, with the initializers for a const array not matching the array length.  Good luck on refining this new language, and geting the compiler to behave.  Now, (for D&D fans) it's on to figuring a neat way to calculate the base to hit mod and save mod, and how to prioritize skill point selection.  I think a simple switch statement will handle the former, but the latter is going to be... interesting, esp for multiclassed characters.


Sorry for the newsgroup spam...

Christopher Stevenson


August 05, 2004
Christopher Stevenson wrote:
> *sigh* I just figured out my little problem.  I changed a named enum to an
> unnamed one, did a text replacement for the old name to "int", and forgot to
> modifiy one little bit of code:
> 
> 
>>const int [6] [int.max] abiPriority =
> 
> 
> ...oops
> 
> The D compiler should have caught that one, with the initializers for a const
> array not matching the array length.  Good luck on refining this new language,

I agree. Here's a short (yet complete) example that shows how the problem manifests:

const int [6] [int.max] abiPriority =
    [ [1, 2, 2, 3, 3, 3],
      [3, 2, 2, 1, 3, 3] ];


Cryptic Error Message:
Internal error: ..\ztc\dt.c 104



I'm cross-posting this onto the bugs group to increase the likelihood that Walter fixes it:

*web interface*
http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs

*usenet interface*
news://news.digitalmars.com/digitalmars.D.bugs


> and geting the compiler to behave.  Now, (for D&D fans) it's on to figuring a
> neat way to calculate the base to hit mod and save mod, and how to prioritize
> skill point selection.  I think a simple switch statement will handle the
> former, but the latter is going to be... interesting, esp for multiclassed
> characters.
> 
> 
> Sorry for the newsgroup spam...

Submitting bug reports is helpful. (Don't be sorry. Be proud.)

I don't consider it spam unless you're trying to sell something.

> 
> Christopher Stevenson  

-- 
Justin (a/k/a jcc7)
http://jcc_7.tripod.com/d/