Classic Computer Magazine Archive ANTIC VOL. 2, NO. 6 / SEPTEMBER 1983

DRAGONSMOKE

FANTASY ROLLS

by BOB ALBRECHT and GEORGE FIREDRAKE

FANTASY ROLE PLAYING GAMES

Millions of people are playing fantasy role playing games. A role playing game is a game in which one or more players create and control characters (adventurers) who live their imaginary lives in a specially made game world. The game world is created, managed, and operated by a Game Master, also called a referee, adventure master, or dungeon master. For general information about role playing games try this excellent book:

  • Through Dungeons Deep by Robert Plamondon. From Reston Publishing Company, 11400 Sunset Hills Road, Reston, VA 22090.
Most people who play role playing games use a formal rule system. Some of the best known are listed below.

  • Dungeons & Dragons (D&D) from TSR Hobbies, P.O. Box 756, Lake Geneva, WI 53147.
  • RuneQuest (RQ) and Worlds of Wonder (WOW) from Chaosium, P.O. Box 6302, Albany, CA 94706.
  • Tunnels & Trolls (T&T) from Blade, Box 1467, Scottsdale, AZ 85252.
Beginners beware! The rule books are difficult to understand. We suggest you begin with Tunnels & Trolls or Worlds of Wonder. We will use Worlds of Wonder as the rule system in DragonSmoke. Even so, we suggest you get Tunnels & Trolls as an easy to understand introduction to games such as Dungeons & Dragons.

THE NAME MACHINE

Suppose you have just created a character to play in a fantasy role playing game. Will you name her Mary or Jane or Kate? Would you call him Bill or Joe or Tom? Probably not. Instead, you might use a name from fantasy literature or invent an unusual name.

Here is a program that invents five-letter names and prints them on the screen. Each name consists of a consonant, vowel, consonant, vowel, consonant - all picked at random. Thus, possible names include ROKAN, BARAK, NINOS, KAREN, MABEL, even CONAN.

  100 REM ** RANDOM NAMES
  110 DIM NAME$(20), C$(21), RC$(1)
  120 DIM V$(6), RV$(l)

  300 REM ** MAKE & PRINT NAMES
  310 PRINT CHR$(125);
  320 FOR K = 1 TO 80
  330   GOSUB 610
  340   PRINT NAME$,
  350 NEXT K

  500 REM ** TELL HOW TO DO AGAIN
  510 PRINT
  520 PRINT "TO DO AGAIN, PRESS SPACE"
  530 OPEN #1, 4, 0, "K:"
  540 GET #1, KEY
  550 IF KEY <> ASC(" ") THEN 540
  560 CLOSE #1
  570 GOTO 310

  600 REM ** MAKE A NAME SUBROUTINE
  610 NAME$ =""
  620 GOSUB 810
  630 GOSUB 910
  640 GOSUB 810
  650 GOSUB 910
  660 GOSUB 810
  670 RETURN

  800 REM ** ADD A CONSONANT SUBROUTINE
  810 C$ = "BCDFGHJKLMNPQRSTVWXYZ"
  820 RC = INT(21 *RND(0)) + 1
  830 RC$ = C$(RC, RC)
  840 NAME$(LEN(NAME$) + 1) = RC$
  850 RETURN

  900 REM ** ADD A VOWEL SUBROUTINE
  910 V$ = "AEIOUY"
  920 RV = INT(6*RND(0)) + 1
  930 RV$ = V$(RV, RV)
  940 NAME$(LEN(NAME$) + 1) = RV$ 
  950 RETURN
Run the program and write down any names you like. Sometimes you can change a masculine sounding name to a feminine sounding name by adding a vowel at the end. For example: ROKAN and ROKANA.

This program creates names of the form CVCVC (consonant, vowel, consonant, vowel, consonant). Modify the program to get names with a different structure.

  • CCVCV - For example: FRODO, THENA, STOKI
  • VCCVCC - For example: ELROND, ARGILF, OTTAMZ
  • and so on - pick your own structure.
Better yet, let the user decide on the structure.

  NAME STRUCTURE?  CVCVC
  FOR MORE NAMES, PRESS SPACE
  FOR NEW STRUCTURE, PRESS 'S'

GAMEMASTER'S DICE

Fantasy Dice Diagram

Here they are again, those funny dice, beloved of fantasy game people.

Last time, we challenged you to write a program to roll N dice, each with S sides. In game jargon: NDS. Here is our first program a piece at a time. We begin with blocks 100 and 300.

  100 REM ** GAMEMASTER'S DICE
  110 DIM D$(20), X$(l), S$(l)
  120 PRINT CHR$(125);

  300 REM ** ASK WHAT TO ROLL (D$)
  310 PRINT: PRINT "YOUR ROLL";
  320 INPUT D$
  330 IF LEN(D$) = 0 THEN 310
We expect someone will type something recognizable such as 3D6 or DD or P or D12. Whatever she or he enters is assigned to the string variable D$ in line 320.

Let's take care of the easy stuff - P for a percentile roll (0 to 99) and DD for a digit roll (0 to 9).

  400 REM ** PERCENTILE ROLL 
  410 IF DS <> "P" THEN 510
  420 ROLL = INT(100*RND(0))
  430 PRINT ROLL: GOTO 310

  500 REM ** DIGIT DIE ROLL
  510 IF D$ <> "DD" THEN 610
  520 ROLL = INT(10*RND(0))
  530 PRINT ROLL: GOTO 310
Well, if you don't enter 'P' or 'DD', we assume you want 3D6 or 2Dl2 or D8 or some other combination of N dice, each with S sides. Remember, 3D6 means three dice, each with six sides. D8 means one die with eight sides. lD8 also means one die with eight sides.

The letter 'D' is between the number of dice and the number of sides on each die. So, let's find the position of 'D' in the string D$. Call the position PD (Position of D).

  600 REM ** FIND 'D'in D$
  610 FOR PD = TO LEN (D$)                      Didn't find 'D'.
  620 X$ = D$(PD,PD)
  630 IF X$="D" THEN 710
  640 NEXT PD
  650 PRINT "I DON'T UNDERSTAND"
  660 GOTO 310
If D$ is 3D6, the PD is 2. Of course: D is the second character in 3D6.

3D6 Diagram

If D$ is D8, then PD is 1.

If D$ is 10D12, the PD is 3.

Having found where 'D' resides in D$, we move on. Next, we want to find N, the number of dice to "roll."

  700 REM ** NUMBER OF DICE, N
  710 IF PD = 1 THEN N = 1
  720 IF PD > 1 THEN N = VAL(D$)
Aha! If 'D' is the first character of D$, we know someone wants the computer to roll one die. If 'D' is not the first character, we assume someone has specified how many dice to roll, as in 3D6, 2D7, or lDl2.

Now we want to find the number of sides (S) for each die. This, of course, is to the right of 'D'.

  800 REM ** NUMBER OF SIDES
  810 LD = LEN(D$)
  820 S$ = D$(PD+, LD)
  830 S = VAL (S$)
Here are some examples.

D$ PD PD+1LD S$ S
3D6 2 3 3 "6" 6
2D8 2 3 3 "8" 8
D6 1 2 2 "6" 6
IOD6 3 4 4 "6" 6
D12 1 2 3 "12"12
lDl2 2 3 4 "12"12
10D123 4 5 "12"12

The time has come to roll the dice, print the result, and go back for another request, ready to roll again.

  900 REM ** ROLLS NDS DICE
  910 ROLL = 0
  920 iF N = 0 THEN 1010
  930 IF S = 0 THEN 1010
  940 FOR KK=l TO N
  950 DIE = INT(S*RND(O))+l
  960 ROLL = ROLL + DIE 
  970 NEXT KK
  1000 REM ** PRINT ROLL & GO BACK
  1010 PRINT ROLL 
  1020 GOTO 310
There is always another way. We will return to this problem and explore other ways to do it. In the meantime, your turn.

  • You can fool this program. Do it! Make a list of all the ways you fooled it, then try to make the program smarter.
  • Add block 200 to tell the user what to do.
  • In block 100, add REM statements to briefly describe the variables in the program.
  • Write a very different program to do the same thing.

A SMALL CAST OF CHARACTERS

We have just finished writing, with Greg Stafford of Chaosium, a book called Adventurer's Handbook: A Beginner's Guide to Role Playing Games. It will be published in late 1983 by Reston Publishing Company. Below are some of the characters who appear in Adventurer's Handbook.

STR CON SIZ INT POW DEX CHA
Aloysious 10 11 10 12 10 12 9
Barostan 17 17 13 8 7 15 6
Bridla 11 12 10 15 6 11 16
Dernfara 13 13 8 13 4 17 6
joleen 13 11 7 13 8 17 13
Rokana 9 9 9 17 18 9 10

Let's store this information in DATA statements, as follows.

  30000 REM ** DATA FILE
  30010 DATA ALOYSIOUS
  30011 DATA 10, 11, 10, 12, 10, 12, 9
  30020 DATA BAROSTAN
  30021 DATA 17, 17, 13, 8, 7, 15, 6
  30030 DATA BRIDLA
  30031 DATA 11, 12, 10, 15, 6, 11, 16
  30040 DATA DERNFARA
  30041 DATA 13, 13, 8, 13, 4, 17, 6
  30050 DATA JOLEEN
  30051 DATA 13, 11, 7, 13, 8, 17, 13
  30060 DATA ROKANA
  30061 DATA 9, 9, 9, 17, 18, 9, 10
  30070 DATA ENDFILE
  30071 DATA 0, 0, 0, 0, 0, 0, 0
Lines 30000 through 30071 comprise a datafile. This file consists of eight records. Each record consists of a name followed by seven numbers. For instance:

	       Name

  30010 DATA ALOYSIOUS
  30011 DATA 10, 11, 10, 12, 10, 12, 9

	   Seven numbers
The last record, which begins with ENDFILE, is not an actual character record. Instead, it simply marks the end of the file.

We challenge you to write two programs to use this data file, data base, or whatever you want to call it.

Program #1 begins at line 1000. If you type the name of a character, the computer finds the appropriate information and displays it on the screen. If you enter a name that is not in the file, the computer searches in vain and eventually finds ENDFILE. It then prints I DON'T KNOW followed by the name you entered. This also happens if you misspell a name that is in the file.

  NAME OF CHARACTER?
Enter BRIDLA and press RETURN.
  NAME OF CHARACTER?  BRIDLA

  STR 11
  CON 12
  SIZ 10
  INT 15
  POW 6
  DEX 11
  CHA 16

  TO DO AGAIN, PRESS SPACE
Program #2 scans the entire file, beginning with the first record. To get the next record, press the space bar. If the computer is already displaying the last record (ENDFILE) and your press the space bar, it begins over with the first record.

In this part of DragonSmoke we will explore the use of your friendly ATARI computer to help you store, manage, and use information. We begin with data files stored in DATA statements as part of the program. Is anyone out there interested in easy stuff for beginners about cassette files and disk files?

POSITIVE, NEGATIVE, OR ZERO

A simple program: write a program that tells whether a number is positive, negative, or zero. Last time, we showed three ways to do it, and challenged you to complete the program for METHOD #4. Here is our program.

  METHOD #4

  100 REM ** POSITIVE, NEGATIVE, OR ZERO 
  110 DIM YN$(15), NZP$(24) 
  120 YN$="YOUR NUMBER IS "
  130 NZP$ "NEGATIVEZERO    POSITIVE"

  200 REM ** TELL WHAT TO DO 
  210 PRINT CHR$(125)
  220 PRINT "ENTER A NUMBER AND I'LL TELL"
  230 PRINT "YOU WHETHER YOUR NUMBER IS"
  240 PRINT "POSITIVE, NEGATIVE, OR ZERO."

  300 REM ** ASK FOR NUMBER
  310 PRINT
  320 PRINT "YOUR NUMBER";: INPUT X

  400 REM ** TELL ABOUT NUMBER
  410 W = SGN(X) + 1
  420 PRINT YN$; NZP$(8*W+1, 8*W+8)

  500 REM ** GO FOR ANOTHER NUMBER 
  510 GOTO 310
Line 130 contains the words NEGATIVE, ZERO, and POSITIVE. We added four spaces to the right of ZERO so each substring has exactly eight characters.

  "NEGATIVEZERO    POSITIVE"

	8 characters
  • NEGATIVE is in character positions 1 to 8.
  • ZERO and four space occupies positions 9 to 16.
  • POSITIVE resides in positions 17 to 24.
Here is a handy table to help you understand lines 410 and 420.

X W 8*W+1 8*W+8 NZP$(8*W+1, 8*W+8)
< 00 1 8 NEGATIVE
= 0 1 9 16 ZERO and 4 spaces
> 02 17 24 POSITIVE

We also asked you to do METHOD #5, with block 100 changed as follows.

  100 REM ** POSITIVE, NEGATIVE, OR ZERO
  110 DIM YN$(lS), NZP$(8)
  120 YN$ = "YOUR NUMBER IS "
  130 DATA NEGATIVE
  140 DATA ZERO
  150 DATA POSITIVE
Here are two ways. We call 'em METHODS 5 and 6.

  METHOD #5

  400 REM ** TELL ABOUT NUMBER
  410 W=SGN(X)+2:REM W is 1, 2 or 3
  420 RESTORE
  430 FOR K=1 TO W
  440 READ NZP$
  450 NEXT K
  460 PRINT YN$; NZP$

  METHOD #6

  400 REM ** TELL ABOUT NUMBER
  410 W = SGN(X) + 1
  420 RESTORE 130 + 10*W
  430 READ NZP$
  440 PRINT YN$; NZP$
Both methods depend on the SGN function, a curious sort of beast. It behaves like this.

  • If X is negative, sign(X) is -1.
  • If X is zero, SGN(X) is 0.
  • If X is positive, SGN(X) is 1.
  • SGN is always -1, 0, or 1.
Here is another handy table to help you understand lines 410, 420, and 430 in METHOD #6.

X W RESTORE 130+10*WNZP$(8*W+1, 8*W+8)
< 00 RESTORE 130 NEGATIVE
= 0 1 RESTORE 140 ZERO
> 02 RESTORE 150 POSITIVE


Copyright © 1983 by DragonQuest, P.O. Box 310, Menlo Park, CA 94025.