randomize()

Hello all, I have little problem. To where I put randomize(){}?
If I put it after initialPlayerChar=me
I get an error The symbol “randomize” is already defined, so you cannot use it as the name of a property here.

gameMain: GameMainDef
    initialPlayerChar = me
;
 
startRoom: Room 'Start Room'
    "This is the starting room. <<me.con>> <<me.str>>"
;
  
+ me: Actor
location = startRoom
con=rand(6)
str=rand(6)
;

:blush: :blush:

You want to define a new method called randomize()? As the compiler tells you, that is an already used name. Pick another, unused name instead.

Or do you mean you want to call the randomize() function? That function initializes the random number generator with a random seed. This is something global, so there’s no reason to do that in the ‘me’ object. You can do that in the newGame() method of your GameMainDef object.

I put randomize function to newgame() which is in gamemain. The game compiles normally without errors but it doesn’t execute the randomize function, I know that because there comes same random numbers all the time. Did I do something wrong? I am little confused with these object and method things.

gameMain: GameMainDef
    initialPlayerChar = me
    newgame()
    {
        randomize();
    }
;

startRoom: Room 'Start Room'
    "This is the starting room. <<me.con>> <<me.str>>"
;

+ me: Actor 'me and myself''me'
    "kjkjkj"
location = startRoom    
con=rand(6)
str=rand(6)
;;

You can place the call to randomize in any InitObject, including an anonymous one.

// seed the RNG
InitObject
    execute()
    {
        randomize();
    }
;

I am trying to do the following thing: make random numbers to some variables and show them when players commands “examine me”. Now the game says “You look the same as usual.” I am really a newbie.

InitObject
    con=rand(6)
    str=rand(6)
    execute()
{
    randomize();
}
;

gameMain: GameMainDef
    initialPlayerChar = me
;
 
startRoom: Room 'Start Room'
    "This is the starting room. "
;

me: Actor 'me and myself' 'me'
    "kjkjkj <<con>> <<str>>"
location = startRoom    
;;

The Actor template that you are using is setting the npcDesc with your double-quoted string. For the player character you need to set the pcDesc property instead.

me: Actor 'me and myself' 'me'
    pcDesc = "kjkjkj <<con>> <<str>>"
    location = startRoom    
;

You are doing fine, BTW. I have these sorts of issues all the time. The Library Reference is invaluable in figuring out what is really going on. There’s almost always a property or method that does exactly what you want; the trick is finding it.

Oh, and you may also need to wrap your random numbers in a toString() call, to prevent a runtime error.

It’s newGame() not newgame(). TADS is case-sensitive.

To randomize a description for your player character (i.e. the “me” object) you can create a ShuffledEventList object in your “me” object, then call it in the “desc” tag via doScript() … like so:


me: Actor
    location = startRoom // or where your game starts
    vocabWords = '(tall) (thin) (average) (good) (looking) Sherlock male/man/person/guy/dude/me/myself/Holmes'
    name = 'Sherlock'
    properName = 'Sherlock'
    isProperName = true
    desc = myDescList.doScript()

    myDescList : ShuffledEventList {
         eventList = ['You look as good looking as ever. ',
                            'You are tall dark and handsome, except for that ugly scar on your cheek that you got during your stint as a knife thrower\'s assistant in the circus.',
                            new function(){  // this is just an example of using a function instead of just a single quoted string...
                                     "You look the same as you did when you woke up first thing this morning. ";
                            },
                            'You examine yourself but find nothing out of  the ordinary. '
          ]
 }
;

… unless you meant to put a permanent one time random description in there from game start, which I would do in gameMain in the showIntro method (which is where I usually set up weird variables like this at game start up) and use a temp variable that you can edit anytime.

gameMain
   playerDesc = nil
   // bunch of code goes here.... skipping to example
   showIntro(){
           gameMain.playerDesc = rand('You\'re a big ugly orc but ugliness in your case is a positive trait (whoever heard of a handsome orc?)',
                                                   'You look as daring and educated as you should be, for the world\'s greatest detective. ',
                                                   'You\'re a tall thin elf with a long crooked nose. ');
    
   }
;

me
  desc = "<<gameMain.playerDesc>> "
;

Now the game says to examine me command “kjkjkj nil nil”. I dont know to where I should put “con” and “str” variables so that them are iniatilized when the play begins and how to call them. BTW, the example which you made was interesting and i even understand it, but I need numbers as strength, stamina, health.

InitObject
    con=rand(6)
    str=rand(6)
    
    execute()
{

    randomize();
}
;

gameMain: GameMainDef
    initialPlayerChar = me
;
 
startRoom: Room 'Start Room'
    "This is the starting room. "
;

me: Actor 'me and myself''me'
pcDesc = "kjkjkj <<toString(InitObject.con)>> <<toString(str)>>"
location = startRoom    
;;

I do this a different way (see my example above of using gameMain.showIntro() to set up variables… I would set up all your random variables there which fires off one time only at game start up.

me: Actor
  stats = [20,20,20,20,20,20,5,5,5,5,5,5]
  statNames = ['str','int','dex','agi','wis','cha','nature','death','fire','cold','magic','poison']
  desc {
             "You look as good looking as ever.<.p> ";
             for(local i=0;i < me.stats.length();i++){
                        say(me.statNames[i] + ': ' + me.stats[i] + '<br>');
             }
  }
;

gameMain
  showIntro(){
          // this randomizes your player statistics from 1 to 20 at game start up
          for(local i= 0;i< me.stats.length();i++) me.stats[i] = rand(20) + 1;
  }
;

… actually the downside to putting variables in the “me” object is if you wanted to change the player character to another character later on in the game via setPlayer(newActorName). If you had them somewhere global, like in gameMain, you would not have to worry about that possibility.

I’m not sure how familiar you are with arrays. You mentioned you are new to tads, so I’m just going to explain it as if you don’t know arrays. On the above example, you refer to the variables by their position in the array. For example, strength (‘str’) is at the zero (0) position, so…

   me.stats[0] = 17;

… would set strength to 17. Str is in the 0 position of the array… ‘int’ is in the 1 position… ‘dex’ is in the 2 position… and so on. To display fire resistance (‘fire’) you could do this:

  "Your fire resistance is <<me.stats[8]>>. ";

Yes, I can use that. Thanks! If I am right, it is same what numbers are in quoted text:

Yes the arrays must match in size. So if you have an array with 10 elements, the other array must have 10 also (if you’re using them for stat names and actual stat numbers like this) but you can use whatever numbers or names you want. I just put something in there to initialize the array with some data, then randomized it from within the gameMain.showIntro method.

And really, you do not need to use arrays if you don’t want to. I’m just showing you a method I use which allows you to use a “for” loop to loop through the array faster than coding it line by line in a huge ugly string of “str = <<me.strength>
end = <<me.endurance>>
wis = <<me.wisdom>>
” etc… So the statNames array stores statistic names for looping through and displaying your statistic names and stat values in one nice and simple short block of code.

If you’re going to make weapons and armor that have statistic modifiers and also negative effects (like a curse effect cast on you by a wizard which affects your stats negatively) and also include statistic “buffs” (spells to increase your stats), your code is going to start getting rather complex.

I have programmed many languages, but not any of them well. So I know arrays, but thank you anyway.

The second code produced 2 errors. Could someonefix it? Thanks in advance.
The compiler expected a function or object definition, but found “showIntro”.
The symbol “showIntro” is already defined, so you cannot use it as the name of a function here.

I tried to put execute() to the code (first code), it solved the problems, but then came an other error:
Expected a semicolon ‘;’ but found “{”

gameMain
  showIntro(){
        execute(){
          // this randomizes your player statistics from 1 to 20 at game start up
          for(local i= 0;i< me.stats.length();i++) me.stats[i] = rand(20) + 1;
        }    }
;
me: Actor
  stats = [20,20,20,20,20,20,5,5,5,5,5,5]
  statNames = ['str','int','dex','agi','wis','cha','nature','death','fire','cold','magic','poison']
  desc {
             "You look as good looking as ever.<.p> ";
             for(local i=0;i < me.stats.length();i++){
                        say(me.statNames[i] + ': ' + me.stats[i] + '<br>');
             }
  }
;

gameMain
  showIntro(){
          // this randomizes your player statistics from 1 to 20 at game start up
          for(local i= 0;i< me.stats.length();i++) me.stats[i] = rand(20) + 1;
  }
;

I think the problem here is that you need to define the class to which gameMain belongs (since this isn’t an object defined in the library, although the library expects your game to define it). The following should work:

gameMain: GameMainDef

  initialPlayerChar = me

  showIntro(){
          // this randomizes your player statistics from 1 to 20 at game start up
          for(local i= 0;i< me.stats.length();i++) me.stats[i] = rand(20) + 1;
  }  
;

Note that you also need to define initialPlayerChar = me on the gameMain object, otherwise the game won’t know what your player character object is called (by convention TADS 3 games tend to call it ‘me’ but it can be called anything you like). Specifically the comment in misc.t states:

 *   Each game MUST define an object called 'gameMain' to define how the
 *   game starts up.  You can use GameMainDef as the base class of your
 *   'gameMain' object, in which case the only thing you're required to
 *   specify in your object is the 'initialPlayerChar' property - you can
 *   inherit everything else from the GameMainDef class if you don't
 *   require any further customizations.  
 */

Now I have done just what I needed, 6 random variables that are initialised when game begins and are showed by command “examine me”. They dont change every time when the command is executed and are easily changed later. Thanks for everybody who helped me!

startRoom: Room 'Start Room'
    "This is the starting room. "
;

me: Actor
    desc {"You look as good looking as ever.<.p> 
        Strength: <<me.Strength>><br> 
        Dexterity: <<me.Dexterity>><br>
        Constitution: <<me.Constitution>><br>
        Intelligence: <<me.Intelligence>><br>
        Wisdom: <<me.Wisdom>><br>
        Charisma: <<me.Charisma>><br>";}
    location=startRoom; 
;

gameMain: GameMainDef

  initialPlayerChar = me

    showIntro(){
        me.Strength=rand(6)+rand(6)+rand(6)+3;
        me.Dexterity=rand(6)+rand(6)+rand(6)+3;
        me.Constitution=rand(6)+rand(6)+rand(6)+3;
        me.Intelligence=rand(6)+rand(6)+rand(6)+3;
        me.Wisdom=rand(6)+rand(6)+rand(6)+3;
        me.Charisma=rand(6)+rand(6)+rand(6)+3;
    }
           
;

How can I ask from player is he

  1. Human
  2. Dwarf
  3. Elf
  4. Gnome
  5. Half elf
    6 Half orc
  6. Halfling

:blush: :blush:

I am asking lot of questions, but this is how I learn.

There might be a more elegant way but here’s one way to do it:

 local iDone = 0;
 local s0 = '';
 do{
       "<br>Please select a race for your character: 
        <br>1. Human
        <br>2. Dwarf
        <br>3. Elf
        <br>4. Gnome
        <br>5. Half elf
        <br>6. Half orc
        <b4>7. Halfling
        <br> >";
        s0 = inputManager.getInputLine(nil, nil);
        s0 = s0.toLower(); // not really needed for numbers but would be handy for standard alpha character checking
        if((s0 == '1') || 
           (s0 == '2') ||
           (s0 == '3') ||
           (s0 == '4') ||
           (s0 == '5') ||
           (s0 == '6') ||
           (s0 == '7')
        ){ 
            iDone++;
        }else{
            "Please select a number from 1 to 7<br>";
        } 
        "\n";
 }while(iDone==0);
 if(s0 == '1'){
       "You picked human. ";
       me.race = 'human';
 }else if(s0 == '2'){
       "You picked dwarf. ";
       me.race = 'dwarf';
 }else if(s0 == '3'){
       "You picked elf. ";
       me.race = 'elf';
 }else if(s0 == '4'){
       "You picked gnome. ";
       me.race = 'gnome';
 }else if(s0 == '5'){
       "You picked half-elf. ";
       me.race = 'half-elf';
 }else if(s0 == '6'){
       "You picked half-orc.";
       me.race = 'half-orc';
 }else{
       "You picked halfling. ";
       me.race = 'halfling';
 }

Thank you a lot.

s0 = inputManager.getInputLine(nil, nil);

That was what I was looking for how to do it.