HODBProVol1 PDF
HODBProVol1 PDF
Volume 1
A Self-Study Guide to Games Programming
Alistair Stewart
Digital Skills
Milton
Barr
Girvan
Ayrshire
KA26 9TY
www.digital-skills.co.uk
Copyright © Alistair Stewart 2005
All brand names and product names are trademarks of their respective
companies and have been capitalised throughout the text.
ISBN : 1-874107-08-4
ISBN-13 978-1-874107-08-8
Chapter 3 Data
Program Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Integer Variables . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Real Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
String Variables . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Using Meaningful Names . . . . . . . . . . . . . . . . . . . . . 77
Naming Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
Allocating Values to Variables . . . . . . . . . . . . . . . . . . . . . . . 79
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
The Assignment Statement . . . . . . . . . . . . . . . . . . . . . . 79
Assigning a Constant . . . . . . . . . . . . . . . . . . . . . . . 79
Copying a Variables Value . . . . . . . . . . . . . . . . . . . . 80
Copying the Result of an Arithmetic Expression . . . . . . . . . . 80
Operator Precedence . . . . . . . . . . . . . . . . . . . . . . . . . 83
Using Parentheses . . . . . . . . . . . . . . . . . . . . . . . . . 84
Variable Range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
String Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
The PRINT Statement Again . . . . . . . . . . . . . . . . . . . . . . 85
Other Ways to Store a Value in a Variable . . . . . . . . . . . . . . . 87
The INPUT Statement . . . . . . . . . . . . . . . . . . . . . . .87
The READ and DATA Statements . . . . . . . . . . . . . . . . .88
The RESTORE Statement . . . . . . . . . . . . . . . . . . . . .91
The Time and Date . . . . . . . . . . . . . . . . . . . . . . . . . . .91
The TIMER Statement . . . . . . . . . . . . . . . . . . . . . . .91
The GET TIME$ Statement . . . . . . . . . . . . . . . . . . . .92
The GET DATE$ Statement . . . . . . . . . . . . . . . . . . . .93
Generating Random Numbers . . . . . . . . . . . . . . . . . . . . .93
The RND Statement . . . . . . . . . . . . . . . . . . . . . . . .93
The RANDOMIZE Statement . . . . . . . . . . . . . . . . . . .94
Structured English and Programs . . . . . . . . . . . . . . . . . . .95
Using Variables to Store Colour Values . . . . . . . . . . . . . . . .96
Named Constants . . . . . . . . . . . . . . . . . . . . . . . . . . .96
Testing Sequential Code . . . . . . . . . . . . . . . . . . . . . . . .97
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .98
Determining Current Settings . . . . . . . . . . . . . . . . . . . . . . . 100
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Screen Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
The SCREEN HEIGHT Statement . . . . . . . . . . . . . . . . 100
The SCREEN WIDTH Statement . . . . . . . . . . . . . . . . 100
The SCREEN DEPTH Statement . . . . . . . . . . . . . . . . 101
Colour Components . . . . . . . . . . . . . . . . . . . . . . . . . 101
The RGBR Statement . . . . . . . . . . . . . . . . . . . . . . 101
The RGBG Statement . . . . . . . . . . . . . . . . . . . . . . 102
The RGBB Statement . . . . . . . . . . . . . . . . . . . . . . 102
Text Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
The TEXT BACKGROUND TYPE Statement . . . . . . . . . . 103
The TEXT STYLE Statement . . . . . . . . . . . . . . . . . . 103
The TEXT SIZE Statement . . . . . . . . . . . . . . . . . . . 104
The TEXT FONT$ Statement . . . . . . . . . . . . . . . . . . 104
The TEXT WIDTH Statement . . . . . . . . . . . . . . . . . . 104
The TEXT HEIGHT Statement . . . . . . . . . . . . . . . . . . 105
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
Solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Chapter 4 Selection
Binary Selection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
The IF Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Condition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Compound Conditions - the AND and OR Operators . . . . . . 116
The NOT Operator . . . . . . . . . . . . . . . . . . . . . . . . 118
ELSE - Creating Two Alternative Actions . . . . . . . . . . . . 119
The Other IF Statement . . . . . . . . . . . . . . . . . . . . . . . 120
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
Multi-Way Selection . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
Nested IF Statements . . . . . . . . . . . . . . . . . . . . . . . . 122
The SELECT Statement . . . . . . . . . . . . . . . . . . . . . . . 124
Testing Selective Code . . . . . . . . . . . . . . . . . . . . . . . . 127
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
Chapter 5 Iteration
Iteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
The WHILE .. ENDWHILE Construct . . . . . . . . . . . . . . . . . 134
The REPEAT .. UNTIL Construct . . . . . . . . . . . . . . . . . . 136
The FOR.. NEXT Construct . . . . . . . . . . . . . . . . . . . . . 138
Finding the Smallest Value in a List of Values . . . . . . . . . . 142
Using FOR with READ and DATA . . . . . . . . . . . . . . . . 144
The EXIT Statement . . . . . . . . . . . . . . . . . . . . . . . 145
The DO .. LOOP Construct . . . . . . . . . . . . . . . . . . . . . . 146
The WAIT milliseconds Statement . . . . . . . . . . . . . . . . 147
The SLEEP Statement . . . . . . . . . . . . . . . . . . . . . . 147
Nested Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
Nested FOR Loops . . . . . . . . . . . . . . . . . . . . . . . 149
Testing Iterative Code . . . . . . . . . . . . . . . . . . . . . . . . 150
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
Solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
Chapter 9 Hangman
Creating a First Game . . . . . . . . . . . . . . . . . . . . . . . . . . 230
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
The Rules of the Game . . . . . . . . . . . . . . . . . . . . . . . . 230
What Part the Computer Plays in the Game . . . . . . . . . . . . . 230
Designing the Screen Layout . . . . . . . . . . . . . . . . . . . . . 231
Game Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
Game Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
Game Documentation . . . . . . . . . . . . . . . . . . . . . . . . 233
Implementing the Design . . . . . . . . . . . . . . . . . . . . . . . 237
Adding InitialiseGame() . . . . . . . . . . . . . . . . . . . . . 238
Adding ThinkOfWord() . . . . . . . . . . . . . . . . . . . . . . 239
Adding DrawInitialScreen() . . . . . . . . . . . . . . . . . . . . 241
Adding GetGuess() . . . . . . . . . . . . . . . . . . . . . . . 243
Adding CheckForLetter() . . . . . . . . . . . . . . . . . . . . . 247
Adding DrawLetter() . . . . . . . . . . . . . . . . . . . . . . . 248
Adding AddToHangedMan() . . . . . . . . . . . . . . . . . . . 249
Adding WordGuessed() . . . . . . . . . . . . . . . . . . . . . 249
Adding HangedManComplete() . . . . . . . . . . . . . . . . . 249
Adding GameOver() . . . . . . . . . . . . . . . . . . . . . . . 249
Keeping a Test Log . . . . . . . . . . . . . . . . . . . . . . . . . . 250
Flaws in the Game . . . . . . . . . . . . . . . . . . . . . . . . . . 250
Omissions from the Code . . . . . . . . . . . . . . . . . . . . 250
Deviating from the Original Specifications . . . . . . . . . . . . 251
Final Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
Solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
Chapter 10 Arrays
Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
Creating Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
The DIM Statement . . . . . . . . . . . . . . . . . . . . . . . 259
Accessing Array Elements . . . . . . . . . . . . . . . . . . . . . . 260
Variable Subscripts . . . . . . . . . . . . . . . . . . . . . . . 261
Basic Algorithms that Use Arrays . . . . . . . . . . . . . . . . . . 264
Calculating the Sum of the Values in an Array . . . . . . . . . . 264
Finding the Smallest Value in an Array . . . . . . . . . . . . . 265
Searching For a Value in an Array . . . . . . . . . . . . . . . . 266
Keeping an Arrays Values in Order . . . . . . . . . . . . . . . 267
Using an Array for Counting . . . . . . . . . . . . . . . . . . . 269
Associating Numbers with Strings . . . . . . . . . . . . . . . . 270
Card Shuffling . . . . . . . . . . . . . . . . . . . . . . . . . . 271
Choosing a Set of Unique Values . . . . . . . . . . . . . . . . 273
Dynamic Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
The UNDIM Statement . . . . . . . . . . . . . . . . . . . . . . 275
Using Arrays in a Game . . . . . . . . . . . . . . . . . . . . . . . 276
Multi-Dimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . 276
Two Dimensional Arrays . . . . . . . . . . . . . . . . . . . . . 276
Inputting Values to a 2D Array . . . . . . . . . . . . . . . . . . 277
Even More Dimensions . . . . . . . . . . . . . . . . . . . . . 277
Arrays and Functions . . . . . . . . . . . . . . . . . . . . . . . . . 278
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
Solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
Chapter 13 Bitmaps
Bitmaps Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
Colour Palette . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
File Size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
File Formats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
Bitmaps in DarkBASIC Pro . . . . . . . . . . . . . . . . . . . . . . . . 342
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
The LOAD BITMAP Statement . . . . . . . . . . . . . . . . . 342
The BITMAP WIDTH Statement . . . . . . . . . . . . . . . . . 344
The BITMAP HEIGHT Statement . . . . . . . . . . . . . . . . 344
The BITMAP DEPTH Statement . . . . . . . . . . . . . . . . . 345
The SET CURRENT BITMAP Statement . . . . . . . . . . . . 345
The CREATE BITMAP Statement . . . . . . . . . . . . . . . . 346
The COPY BITMAP Statement . . . . . . . . . . . . . . . . . 347
The FLIP BITMAP Statement . . . . . . . . . . . . . . . . . . 348
The MIRROR BITMAP Statement . . . . . . . . . . . . . . . . 349
The BLUR BITMAP Statement . . . . . . . . . . . . . . . . . . 350
The FADE BITMAP Statement . . . . . . . . . . . . . . . . . . 351
Copying Only Part of a Bitmap . . . . . . . . . . . . . . . . . . . . 352
The COPY BITMAP Statement - Version 2 . . . . . . . . . . . 352
Zooming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
Bitmap Status . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
The BITMAP EXIST Statement . . . . . . . . . . . . . . . . . 356
The BITMAP MIRRORED Statement . . . . . . . . . . . . . . 356
The BITMAP FLIPPED Statement . . . . . . . . . . . . . . . . 357
The CURRENT BITMAP Statement . . . . . . . . . . . . . . . 357
The DELETE BITMAP Statement . . . . . . . . . . . . . . . . 357
Placing More than One Image in the Same Area . . . . . . . . . . 358
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
Solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
Chapter 20 Images
Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488
Image Handling Statements . . . . . . . . . . . . . . . . . . . . . 488
The LOAD IMAGE Statement . . . . . . . . . . . . . . . . . . 488
The PASTE IMAGE Statement . . . . . . . . . . . . . . . . . 489
The SET IMAGE COLORKEY Statement . . . . . . . . . . . . 490
The SAVE IMAGE Statement . . . . . . . . . . . . . . . . . . 490
The DELETE IMAGE Statement . . . . . . . . . . . . . . . . . 491
The GET IMAGE Statement . . . . . . . . . . . . . . . . . . . 492
The IMAGE EXIST Statement . . . . . . . . . . . . . . . . . . 493
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493
Solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494
Chapter 21 Sprites1
Creating and Moving Sprites . . . . . . . . . . . . . . . . . . . . . . . 496
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
Loading a Sprite Image . . . . . . . . . . . . . . . . . . . . . . . . 496
The SPRITE Statement . . . . . . . . . . . . . . . . . . . . . 496
Translating a Sprite . . . . . . . . . . . . . . . . . . . . . . . . . . 498
The PASTE SPRITE Statement . . . . . . . . . . . . . . . . . 498
The MOVE SPRITE Statement . . . . . . . . . . . . . . . . . 499
The ROTATE SPRITE Statement . . . . . . . . . . . . . . . . 500
How MOVE SPRITE Operates . . . . . . . . . . . . . . . . . . . . 502
Moving a Sprites Origin . . . . . . . . . . . . . . . . . . . . . . . 503
The OFFSET SPRITE Statement . . . . . . . . . . . . . . . . 503
Sprite Reflection . . . . . . . . . . . . . . . . . . . . . . . . . . . 505
The MIRROR SPRITE Statement . . . . . . . . . . . . . . . . 505
The FLIP SPRITE Statement . . . . . . . . . . . . . . . . . . 506
Reflecting a Tilted Sprite . . . . . . . . . . . . . . . . . . . . . 507
Sprite Background Transparency . . . . . . . . . . . . . . . . . . 507
Giving the User Control of a Sprite . . . . . . . . . . . . . . . . . . 508
Vertical Movement . . . . . . . . . . . . . . . . . . . . . . . . 508
Horizontal Movement . . . . . . . . . . . . . . . . . . . . . . 508
Rotational Movement . . . . . . . . . . . . . . . . . . . . . . 509
Free Movement . . . . . . . . . . . . . . . . . . . . . . . . . 510
Restricting Sprite Movement . . . . . . . . . . . . . . . . . . . 511
Storing the Position of the Sprite in a Record . . . . . . . . . . 512
Velocity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512
Sprites and the PRINT Statement . . . . . . . . . . . . . . . . . . 521
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522
Solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523
Chapter 22 Sprites 2
Changing a Sprites Appearance . . . . . . . . . . . . . . . . . . . . . 528
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 528
Resizing Sprites . . . . . . . . . . . . . . . . . . . . . . . . . . . 528
The SCALE SPRITE Statement . . . . . . . . . . . . . . . . . 528
The STRETCH SPRITE Statement . . . . . . . . . . . . . . . 529
The SIZE SPRITE Statement . . . . . . . . . . . . . . . . . . 530
Changing Transparency and Colour Brightness . . . . . . . . . . . 530
The SET SPRITE ALPHA Statement . . . . . . . . . . . . . . 530
The SET SPRITE DIFFUSE Statement . . . . . . . . . . . . . 531
Showing and Hiding Sprites . . . . . . . . . . . . . . . . . . . . . 532
The HIDE SPRITE Statement . . . . . . . . . . . . . . . . . . 532
The SHOW SPRITE Statement . . . . . . . . . . . . . . . . . 533
The HIDE ALL SPRITES Statement . . . . . . . . . . . . . . . 533
The SHOW ALL SPRITES Statement . . . . . . . . . . . . . . 533
Duplicating a Sprite . . . . . . . . . . . . . . . . . . . . . . . . . . 533
The CLONE SPRITE Statement . . . . . . . . . . . . . . . . . 533
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534
Adding a Background . . . . . . . . . . . . . . . . . . . . . . . . . . . 536
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536
Ways to Change the Background . . . . . . . . . . . . . . . . . . 536
The COLOR BACKDROP Statement . . . . . . . . . . . . . . 536
The BACKDROP ON Statement . . . . . . . . . . . . . . . . . 536
The BACKDROP OFF Statement . . . . . . . . . . . . . . . . 537
Using a Sprite as a BackGround . . . . . . . . . . . . . . . . . 537
Sprite Order . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
The SET SPRITE PRIORITY Statement . . . . . . . . . . . . . 538
The SET SPRITE TEXTURE COORD Statement . . . . . . . . 539
The SET SPRITE Statement . . . . . . . . . . . . . . . . . . . 542
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 543
Retrieving Data About Sprites . . . . . . . . . . . . . . . . . . . . . . 544
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544
Sprite Data Retrieval Statements . . . . . . . . . . . . . . . . . . 544
The SPRITE EXIST Statement . . . . . . . . . . . . . . . . . 544
The SPRITE X Statement . . . . . . . . . . . . . . . . . . . . 544
The SPRITE Y Statement . . . . . . . . . . . . . . . . . . . . 544
The SPRITE ANGLE Statement . . . . . . . . . . . . . . . . . 545
The SPRITE OFFSET X Statement . . . . . . . . . . . . . . . 545
The SPRITE OFFSET Y Statement . . . . . . . . . . . . . . . 546
The SPRITE SCALE X Statement . . . . . . . . . . . . . . . . 546
The SPRITE SCALE Y Statement . . . . . . . . . . . . . . . . 546
The SPRITE WIDTH Statement . . . . . . . . . . . . . . . . . 547
The SPRITE HEIGHT Statement . . . . . . . . . . . . . . . . 547
The SPRITE MIRRORED Statement . . . . . . . . . . . . . . 547
The SPRITE FLIPPED Statement . . . . . . . . . . . . . . . . 548
The SPRITE VISIBLE Statement . . . . . . . . . . . . . . . . 548
The SPRITE ALPHA Statement . . . . . . . . . . . . . . . . . 548
The SPRITE RED Statement . . . . . . . . . . . . . . . . . . 549
The SPRITE GREEN Statement . . . . . . . . . . . . . . . . . 549
The SPRITE BLUE Statement . . . . . . . . . . . . . . . . . . 549
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550
Sprite Collision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551
Dealing With Sprite Collisions . . . . . . . . . . . . . . . . . . . . 551
The SPRITE HIT Statement . . . . . . . . . . . . . . . . . . . 551
The SPRITE COLLISION Statement . . . . . . . . . . . . . . 553
A Basic Bat and Ball Game . . . . . . . . . . . . . . . . . . . . . 553
Firing Projectiles . . . . . . . . . . . . . . . . . . . . . . . . . . . 555
The DELETE SPRITE Statement . . . . . . . . . . . . . . . . 555
The Missile Game . . . . . . . . . . . . . . . . . . . . . . . . 556
Extending the Game . . . . . . . . . . . . . . . . . . . . . . . 558
The SET SPRITE IMAGE Statement . . . . . . . . . . . . . . 559
The SPRITE IMAGE Statement . . . . . . . . . . . . . . . . . 560
Updating the Screen . . . . . . . . . . . . . . . . . . . . . . . . . 562
The SYNC ON Statement . . . . . . . . . . . . . . . . . . . . 562
The SYNC Statement . . . . . . . . . . . . . . . . . . . . . . 562
The SYNC OFF Statement . . . . . . . . . . . . . . . . . . . 563
The SYNC RATE Statement . . . . . . . . . . . . . . . . . . . 563
The FASTSYNC Statement . . . . . . . . . . . . . . . . . . . 564
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 564
Solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 565
Chapter 24 Sound
Mono and Stereo Sound . . . . . . . . . . . . . . . . . . . . . . . . . 604
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 604
The Basics of Loading and Playing Sounds . . . . . . . . . . . . . 604
The LOAD SOUND Statement . . . . . . . . . . . . . . . . . . 604
The PLAY SOUND Statement . . . . . . . . . . . . . . . . . . 604
The LOOP SOUND Statement . . . . . . . . . . . . . . . . . . 606
The PAUSE SOUND Statement . . . . . . . . . . . . . . . . . 607
The RESUME SOUND Statement . . . . . . . . . . . . . . . . 607
The STOP SOUND Statement . . . . . . . . . . . . . . . . . . 608
The SET SOUND SPEED Statement . . . . . . . . . . . . . . 608
The SET SOUND VOLUME Statement . . . . . . . . . . . . . 609
The CLONE SOUND Statement . . . . . . . . . . . . . . . . . 609
The DELETE SOUND Statement . . . . . . . . . . . . . . . . 610
Recording Sound . . . . . . . . . . . . . . . . . . . . . . . . . . . 611
The RECORD SOUND Statement . . . . . . . . . . . . . . . . 611
The STOP RECORDING SOUND Statement . . . . . . . . . . 611
The SAVE SOUND Statement . . . . . . . . . . . . . . . . . . 612
Retrieving Sound File Data . . . . . . . . . . . . . . . . . . . . . . 613
The SOUND EXIST Statement . . . . . . . . . . . . . . . . . 613
The SOUND PLAYING Statement . . . . . . . . . . . . . . . . 613
The SOUND LOOPING Statement . . . . . . . . . . . . . . . 614
The SOUND PAUSED Statement . . . . . . . . . . . . . . . . 614
The SOUND VOLUME Statement . . . . . . . . . . . . . . . . 616
The SOUND SPEED Statement . . . . . . . . . . . . . . . . . 616
Moving a Sound . . . . . . . . . . . . . . . . . . . . . . . . . . . 617
The SET SOUND PAN Statement . . . . . . . . . . . . . . . . 617
The SOUND PAN Statement . . . . . . . . . . . . . . . . . . 617
Playing Multiple Sound Files . . . . . . . . . . . . . . . . . . . . . 618
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 618
3D Sound Effects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 620
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 620
Loading and Playing 3D Sounds . . . . . . . . . . . . . . . . . . . 621
The LOAD 3DSOUND Statement . . . . . . . . . . . . . . . . 621
The POSITION SOUND Statement . . . . . . . . . . . . . . . 621
Controlling the Listener . . . . . . . . . . . . . . . . . . . . . . . . 622
The POSITION LISTENER Statement . . . . . . . . . . . . . . 622
The ROTATE LISTENER Statement . . . . . . . . . . . . . . 623
The SCALE LISTENER Statement . . . . . . . . . . . . . . . 623
Retrieving Data on 3D Sounds and the Listener . . . . . . . . . . . 624
The SOUND POSITION X Statement . . . . . . . . . . . . . . 624
The SOUND POSITION Y Statement . . . . . . . . . . . . . . 624
The SOUND POSITION Z Statement . . . . . . . . . . . . . . 624
The LISTENER POSITION X Statement . . . . . . . . . . . . 625
The LISTENER POSITION Y Statement . . . . . . . . . . . . 625
The LISTENER POSITION Z Statement . . . . . . . . . . . . . 625
The LISTENER ANGLE X Statement . . . . . . . . . . . . . . 625
The LISTENER ANGLE Y Statement . . . . . . . . . . . . . . 625
The LISTENER ANGLE Z Statement . . . . . . . . . . . . . . 626
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 626
Solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 628
Chapter 25 2D Vectors
2D Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 632
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 632
A Mathematical Description of Vectors . . . . . . . . . . . . . 632
Vectors in DarkBASIC Pro . . . . . . . . . . . . . . . . . . . . 633
Creating a 2D Vector . . . . . . . . . . . . . . . . . . . . . . . . . 633
The MAKE VECTOR2 Statement . . . . . . . . . . . . . . . . 633
The SET VECTOR2 Statement . . . . . . . . . . . . . . . . . 634
The X VECTOR2 Statement . . . . . . . . . . . . . . . . . . . 635
The Y VECTOR2 Statement . . . . . . . . . . . . . . . . . . . 635
The DELETE VECTOR2 Statement . . . . . . . . . . . . . . . 636
The COPY VECTOR2 Statement . . . . . . . . . . . . . . . . 637
The MULTIPLY VECTOR2 Statement . . . . . . . . . . . . . . 638
The SCALE VECTOR2 Statement . . . . . . . . . . . . . . . . 638
The DIVIDE VECTOR2 Statement . . . . . . . . . . . . . . . . 639
The LENGTH VECTOR2 Statement . . . . . . . . . . . . . . . 639
The SQUARED LENGTH VECTOR2 Statement . . . . . . . . 640
The ADD VECTOR2 Statement . . . . . . . . . . . . . . . . . 640
The SUBTRACT VECTOR2 Statement . . . . . . . . . . . . . 643
The DOT PRODUCT VECTOR2 Statement . . . . . . . . . . . 644
The IS EQUAL VECTOR2 Statement . . . . . . . . . . . . . . 645
The MAXIMIZE VECTOR2 Statement . . . . . . . . . . . . . . 646
The MINIMIZE VECTOR2 Statement . . . . . . . . . . . . . . 647
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 648
In Mathematics . . . . . . . . . . . . . . . . . . . . . . . . . . 648
In Geometry . . . . . . . . . . . . . . . . . . . . . . . . . . . 648
In DarkBASIC Pro . . . . . . . . . . . . . . . . . . . . . . . . 648
Solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 650
Chapter 28 Pelmanism
The Game of Pelmanism . . . . . . . . . . . . . . . . . . . . . . . . . 698
Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 698
The Screen Layout . . . . . . . . . . . . . . . . . . . . . . . . . . 698
Game Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 699
Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . 699
Structures Defined . . . . . . . . . . . . . . . . . . . . . . . . 699
Global Variables . . . . . . . . . . . . . . . . . . . . . . . . . 699
Game Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 700
The Program Code . . . . . . . . . . . . . . . . . . . . . . . . . . 700
Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . 700
Adding InitialiseGame() . . . . . . . . . . . . . . . . . . . . . 701
Adding HandleMouse() . . . . . . . . . . . . . . . . . . . . . . 703
Adding GameOver() . . . . . . . . . . . . . . . . . . . . . . . 706
Pelmanism - Program Listing . . . . . . . . . . . . . . . . . . . . . . . 707
Solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713
I would like to thank all those who helped me prepare the final draft of this book.
In particular, Virginia Marshall who proof-read the original script and Michael Kerr
who did an excellent job of checking the technical contents.
Any errors that remain are probably due to the extra few paragraphs I added after
all the proof-reading was complete!
Thanks also to The Game Creators Ltd for producing an excellent piece of software
- DarkBASIC Professional - known as DarkBASIC Pro to its friends.
Finally, thank you to every one of you who has bought this book. Any constructive
comments would be most welcome.
Email me at [email protected].
Introduction
Welcome to a book that I hope is a little different from any other you've come across.
Instead of just telling you about software design and programming, it makes you
get involved. There's plenty of work for you to do since the book is full of exercises
- most of them programming exercises - but you also get a full set of solutions, just
in case you get stuck!
Learn by Doing
The only way to become a programming expert is to practice. No one ever learned
any skill by just reading about it! Hence, this is not a text book where you can just
sit back in a passive way and read from cover to cover whilst sitting in your favourite
chair. Rather it is designed as a teaching package in which you will do most of the
work.
The tasks embedded in the text are included to test your understanding of what has
gone before and as a method of helping you retain the knowledge you have gained.
It is therefore important that you tackle each task as you come to it. Also, many of
the programming exercises are referred to, or expanded, in later pages so it is
important that you are familar with the code concerned.
You don't need any experience of programming, but knowing your bits from your
bytes and understanding binary and hexadecimal number systems would be useful.
2. Re-read the chapter. This time take things slowly; make notes and
summaries of the material you are reading (even if you understand the
material, making notes helps to retain the facts in your long-term
memory); re-read any parts you are unclear about.
IF condition THEN
statement
ELSE
statement
Each tile in the diagram holds a token of the statement. Raised tiles represent fixed
terms in the statement, which must be entered exactly as shown. Sunken tiles
represent tokens whose exact value is decided by you, the programmer, but again
these values must conform to some stated rule.
ELSE
Items enclosed in brackets may be omitted if not required. In this
example we can see that ELSE and all the terms that follow may be
statement omitted.
Occasionally, a single line of code will have to be printed over two or more lines
Ä
because of paper width restrictions; these lines are signified by a symbol. Enter
these lines without a break when testing any of the programs in which they are used.
For example, the code
Boolean expressions
Data Variables
Designing Algorithms
Desk Checking
IF Control Structure
FOR Control Structure
REPEAT Control Structure
Stepwise Refinement
Testing
WHILE Control Structure
Think of a mammal that starts with the second letter of the countrys name
Congratulations! You’ve just become a human computer. You were given a set of
instructions which you have carried out (by the way, did you think of the colour
grey?).
That’s exactly what a computer does. You give it a set of instructions,the machine
carries out those instructions, and that is ALL a computer does. If some computers
seem to be able to do amazing things, that is only because someone has written an
amazingly clever set of instructions. A set of instructions designed to perform some
specific task is known as an algorithm.
There are a few points to note from the algorithm given above:
This time let’s see if you can devise your own algorithm.
The task you need to solve is to measure out exactly 4 litres of water. You
have two containers. Container A, if filled, will hold exactly 5 litres of water,
while container B will hold 3 litres of water. You have an unlimited supply of
water and a drain to get rid of any water you no longer need. It is not possible
to know how much water is in a container if you only partly fill it from the
A B supply.
If you managed to come up with a solution, see if you can find a second way
of measuring out the 4 litres.
As you can see, there are at least two ways to solve the problem given in Activity
1.2. Is one better than the other? Well, if we start by filling container A, the solution
needs less instructions, so that might be a good guideline at this point when choosing
which algorithm is best.
Computer programs are normally copied (or loaded) from a magnetic disk into the
computer’s memory and then executed (or run). Execution of a program involves
the computer performing each instruction in the program one after the other. This
it does at impressively high rates, possibly exceeding 2,000 million (or 2 billion)
instructions per second (2,000 mips).
Depending on the program being run, the computer may act as a word processor, a
database, a spreadsheet, a game, a musical instrument or one of many other
possibilities. Of course, as a programmer, you are required to design and write
computer programs rather than use them. And, more specifically, our programs in
this text will be mainly games-related; an area of programming for which
DarkBASIC Pro has been specifically designed.
Activity 1.3
Control Structures
Although writing algorithms and programming computers are certainly
complicated tasks, there are only a few basic concepts and statements which you
need to master before you are ready to start producing software. Luckily, the
concepts are already familiar to you in everyday situations. If you examine any
algorithm, no matter how complex, you will find it consists of three basic structures:
These are explained in detail over the next few pages. All that is needed is to
formalise the use of these structures within an algorithm. This formalisation better
matches the structure of a computer program.
Sequence
A set of instructions designed to be carried out one after another, beginning at the
first and continuing, without omitting any, until the final instruction is completed,
The set of instructions given earlier in Activity 1.1 is also an example of a sequence.
Activity 1.4
Selection
Binary Selection
Often a group of instructions in an algorithm should only be carried out when certain
circumstances arise. For example, if we were playing a simple game with a young
child in which we hide a sweet in one hand and allow the child to have the sweet
if she can guess which hand the sweet is in, then we might explain the core idea
with an instruction such as
Give the sweet to the child if the child guesses which hand the sweet is in
Notice that when we write a sentence containing the word IF, it consists of two main
components:
Notice that the layout of this instruction makes use of three terms that are always
included. These are the words IF, which marks the beginning of the instruction;
THEN, which separates the condition from the command; and finally, ENDIF which
marks the end of the instruction.
Sometimes, there will be several commands to be carried out when the condition
specified is met. For example, in the game of Scrabble we might describe a turn as:
This longer sequence of instructions highlights the usefulness of the term ENDIF
in separating the conditional command, Give the sweet to the child, from subsequent
unconditional instructions, in this case, Ask the child if they would like to play again.
Activity 1.5
The IF structure is also used in an extended form to offer a choice between two
alternative actions. This expanded form of the IF statement includes another formal
term, ELSE, and a second command. If the condition specified in the IF statement
is true, then the command following the term THEN is executed, otherwise that
following ELSE is carried out.
For instance, in our earlier example of playing a guessing game with a child, nothing
happened if the child guessed wrongly. If the person holding the sweet were to eat
it when the child’s guess was incorrect, we could describe this setup with the
following statement:
Activity 1.6
When we have several independent selections to make, then we may use several IF
statements. For example, when playing Monopoly, we may buy any unpurchased
property we land on. In addition, we get another turn if we throw a double. This
part of the game might be described using the following statements:
Although a single IF statement can be used to select one of two alternative actions,
sometimes we need to choose between more than two alternatives (known as
multi-way selection). For example, imagine that the rules of the simple guessing
game mentioned in Activity 1.5 are changed so that there are three possible
responses to Player 2’s guess; these being:
Ø Correct
Ø Too low
Ø Too high
One way to create an algorithm that describes this situation is just to employ three
separate IF statements:
This will work, but would not be considered a good design for an algorithm since,
when the first IF statement is true, we still go on and check if the conditions in the
second and third IF statements are true. After all, only one of the three conditions
can be true at any one time.
Where only one of the conditions being considered can be true at a given moment
in time, these conditions are known as mutually exclusive conditions.
The most effective way to deal with mutually exclusive conditions is to check for
one condition, and only if this is not true, are the other conditions tested. So, for
example, in our algorithm for guessing the number, we might begin by writing:
We already know how to handle a situation where there are only two alternatives:
use an IF statement. So we can chose between Too low and Too high with the
statement
Now, by replacing the phrase ***Check the other conditions*** in our original
algorithm with our new IF statement we get:
Notice that the second IF statement is now totally contained within the ELSE section
of the first IF statement. This situation is known as nested IF statements. Where
there are even more mutually exclusive alternatives, several IF statements may be
nested in this way. However, in most cases, we’re not likely to need more than two
nested IF statements.
As you can see from the solution to Activity 1.7, although nested IF statements get
the job done, the general structure can be rather difficult to follow. A better method
would be to change the format of the IF statement so that several, mutually
exclusive, conditions can be declared in a single IF statement along with the action
required for each of these conditions. This would allow us to rewrite the solution
to Activity 1.7 as:
IF
crossbow is too high:
Say Down a bit
crossbow is too low:
Say Up a bit
crossbow is too far right:
Say Left a bit
crossbow is too far left:
Say Right a bit
crossbow is on target:
Say Fire
ENDIF
Each option is explicitly named (ending with a colon) and only the one which is
true will be carried out, the others will be ignored.
Of course, we are not limited to merely five options; there can be as many as the
situation requires.
When producing a program for a computer, all possibilities have to be taken into
account. Early adventure games, which were text based, allowed the player to type
a command such as Go East, Go West, Go North, Go South and this moved the
player’s character to new positions in the imaginary world of the computer program.
If the player typed in an unrecognised command such as Go North-East or Move
faster, then the game would issue an error message. This setup can be described by
adding an ELSE section to the structure as shown below:
IF
command is Go East:
Move players character eastward
command is Go West:
Move players character westward
command is Go North:
Move players character northward
command is Go South:
Move players character southward
ELSE
Display an error message
ENDIF
This gives us the final form of this style of the IF statement as shown in FIG-1.3:
Activity 1.8
If you know the phrase, you should make a guess at what it is; if there are
still many unseen letters, you should guess a consonant; as a last resort you
can buy a vowel.
Write an IF statement in the style given above describing how to choose from
the three options.
Complex Conditions
Often the condition given in an IF statement may be a complex one. For example,
in the TV game Family Fortunes, you only win the star prize if you get 200 points
and guess the most popular answers to a series of questions. This can be described
in our more formal style as:
IF at least 200 points gained AND all most popular answers have been guessed THEN
winning team get the star prize
ENDIF
Note the use of the word AND in the above example. AND (called a Boolean
operator) is one of the terms used to link simple conditions in order to produce a
more complex one (known as a complex condition). The conditions on either side
of the AND are called the operands. Both operands must be true for the overall result
to be true. We can generalise this to describe the AND operator as being used in the
form:
For example, if we assume the group reaching the final of the game show Family
Fortunes has amassed 230 points but have not guessed all of the most popular
answers, then a computer would determine the overall result of the IF statement
given earlier as shown in FIG-1.4.
This condition is true This condition is false
FIG-1.4
Calculating the Result IF at least 200 points gained AND all most popular answers have been guessed THEN
of an AND Operation
giving
reduces to
IF false THEN
With two conditions there are four possible combinations. The first possibility is
that both conditions are false; another possibility is that condition 1 is false but
condition 2 is true.
Activity 1.9
What are the other two possible combinations of true and false?
Activity 1.10
In the card game Snap, you win the cards on the table if you are first to place
your hand over those cards, and the last two cards laid down are of the same
value.
The OR Operator
Simple conditions may also be linked by the Boolean OR operator. Using OR, only
one of the conditions needs to be true in order to carry out the action that follows.
For example, in the game of Monopoly you go to jail if you land on the GoTo Jail
condition 1 OR condition 2
When OR is used, only one of the conditions involved needs to be true for the overall
result to be true. Hence the results are determined by the following rules:
For example, if a player in the game of Monopoly has not landed on the Go To Jail
square, but has thrown three consecutive pairs, then the result of the IF statement
given above would be determined as shown in FIG-1.5.
Calculating the Result of IF player lands on Go To Jail OR player has thrown 3 pairs in a row THEN
an OR Operation
giving
reduces to
IF true THEN
Activity 1.11
In Monopoly, a player can get out of jail if he throws a double or pays a £50
fine.
The final Boolean operator which can be used as part of a condition is NOT. This
operator is used to reverse the meaning of a condition. Hence, if property mortgaged
is true, then NOT property mortgaged is false.
In Monopoly a player can charge rent on a property as long as that property is not
mortgaged. This situation can be described with the statement:
NOT condition
When NOT is used, the result given by the original condition is reversed. Hence the
results are determined by the following rules:
For example, if a player lands on a property that is not mortgaged, then the result
of the IF statement given above would be determined as shown in FIG-1.6.
This condition is false
FIG-1.6
Calculating the Result of IF NOT property mortgaged THEN
a NOT Operation
giving
Although us humans might be able to work all of this out in our heads without even
a conscious thought, computers deal with such complex conditions in a slow, but
methodical way.
To calculate the final result of the condition given above, the computer requires
several operations to be performed. These are performed in two stages:
IF player lands on Go To Jail OR player throws 3 pairs in a row OR player lifts a Go To Jail card THEN
giving
reduces to
IF false OR true THEN
reduces to
IF true THEN
That might seem a rather complicated way of achieving what was probably an
obvious result, but when the conditions become even more complex, this methodical
approach is necessary.
Notice that when a complex condition contains only a single Boolean operator type
(OR in the example above), that the expression is worked out from left to right.
However, should the condition contain a mixture of OR, AND and NOT operators,
NOT operations are performed first, ANDs second, and ORs last.
and a player has magic armour and has drunk the invisibility potion, then to
determine if the player can kill the dragon, the process shown in FIG-1.8 is followed.
FIG-1.8 This condition is false This condition is true
AND Operators have IF player has a magic sword AND player has magic armour
Priority
OR player has taken invisibility potion AND player possesses sleep spell THEN
giving
reduces to
IF false OR true AND false THEN
reduces to
reduces to
IF false THEN
The final result shows that the player cannot kill the dragon.
IF a player has an Ace AND player has King OR player has two Knaves THEN
Using a similar approach to that shown in FIG-1.8 above, show the steps
involved in deciding if the player should take an extra card assuming the
player already has an Ace and one Knave.
Sometimes the priority of operators works against what we are trying to express.
For example, if a player receives a bonus if he lands on a red, green or blue square
after throwing 7 on a pair of dice, then we might be tempted to write:
We would not expect a player landing on a red square after throwing 9 to receive
the bonus. But, if we look at the calculation for such a situation, we get the result
shown in FIG-1.9 which means that the bonus is incorrectly added to the player’s
score.
FIG-1.9 This condition is true This condition is false This condition is false This condition is false
How the Final Result is IF landed on red OR landed on green OR landed on blue AND thrown 7 THEN
Calculated
giving
reduces to
IF true OR false OR false THEN
reduces to
reduces to
IF true THEN
To achieve the correct results, we need the OR operations to be performed first and
this can be done by giving the OR operators a higher priority than the AND.
Luckily, operator priority can be modified by using parentheses. Operations in
parentheses are always performed first. So, by rewriting our instruction as
giving
reduces to
reduces to
IF false THEN
Activity 1.13
The rules for winning a card game are that your hand of 5 cards must add up
to exactly 43 (faces =10, Ace = 11) or you must have four cards of the same
value. In addition, a player cannot win unless he has a Queen in his hand.
Activity 1.14
Throw dice
Add dice value to total
are carried out three times, once for each turn taken by the player. Not only does it
seem rather time-consuming to have to write the same pair of instructions three
times, but it would be even worse if the player had to throw the dice 10 times!
Activity 1.15
What statements make up the loop body in our dice problem given above?
FOR..ENDFOR
There are two parts to this statement. The first of these is placed just before the loop
body and in it we state how often we want the statements in the loop body to be
carried out. For the dice problem our statement would be:
FOR 3 times DO
Next come the statements that make up the loop body. These are indented:
FOR 3 times DO
Throw dice
Add dice value to total
Finally, to mark the fact that we have reached the end of the loop body statements
we add the word ENDFOR:
The instructions between the terms FOR and ENDFOR are now carried out three
times.
Activity 1.16
You can find the average If the player was required to throw the dice 10 times rather than 3, what
of the 10 numbers by changes would we need to make to the algorithm?
dividing the final total by
10. If the player was required to call out the average of these 10 numbers, rather
than the total, show what other changes are required to the set of instructions.
We are free to place any statements we wish within the loop body. For example,
the last version of our number guessing game produced the following algorithm
player 2 would have more chance of winning if he were allowed several chances at
guessing player 1’s number. To allow several attempts at guessing the number, some
of the statements given above would have to be repeated.
Activity 1.17
Activity 1.19
During a lottery draw, two actions are performed exactly 6 times. These are:
Add a FOR loop to the above statements to create an algorithm for the lottery
draw process.
Occasionally, we may have to use a slightly different version of the FOR loop.
Imagine we are trying to write an algorithm explaining how to decide who goes first
in a game. In this game every player throws a dice and the player who throws the
highest value goes first. To describe this activity we know that each player does the
following task:
But since we can’t know in advance how many players there will be, we write the
algorithm using the statement
If we had to save the details of a game of chess with the intention of going back to
the game later, we might write:
Activity 1.20
A game uses cards with images of warriors. At one point in the game the
player has to remove from his hand every card with an image of a knight. To
do this the player must look through every card and, if it is a knight, remove
the card.
Write down a set of instructions which performs the task described above.
Although the FOR loop allows us to perform a set of statements a specific number
of times, this statement is not always suitable for the problem we are trying to solve.
For example, in the guessing game we stated that the loop body was to be performed
7 times, but what if player 2 guesses the number after only three attempts? If we
were to follow the algorithm exactly (as a computer would), then we must make
four more guesses at the number even after we know the correct answer!
To solve this problem, we need another way of expressing looping which does not
commit us to a specific number of iterations.
REPEAT.. UNTIL
The REPEAT .. UNTIL statement allows us to specify that a set of statements should
be repeated until some condition becomes true, at which point iteration should
cease. The word REPEAT is placed at the start of the loop body and, at its end, we
add the UNTIL statement. The UNTIL statement also contains a condition, which,
when true, causes iteration to stop. This is known as the terminating (or exit)
condition. For example, we could use the REPEAT.. UNTIL structure rather than
the FOR loop in our guessing game algorithm. The new version would then be:
We could also use the REPEAT..UNTIL loop to describe how a slot machine
(one-armed bandit) is played:
REPEAT
Put coin in machine
Pull handle
IF you win THEN
Collect winnings
ENDIF
UNTIL you want to stop
FIG-1.12 REPEAT
Activity 1.21
A one-armed bandit costs 50p per play. A player has several 50p pieces and is
determined to play until his coins are gone or until he wins at least £10.00.
Write an algorithm describing the steps in this game. The algorithm should
make use of the following statements:
Collect winnings
Place coin in machine
Pull arm
WHILE.. ENDWHILE
A final method of iteration, differing only subtly from the REPEAT.. UNTIL loop,
is the WHILE .. ENDWHILE structure which has an entry condition at the start
of the loop.
The aim of the card game of Pontoon is to attempt to make the value of your cards
add up to 21 without going over that value. Each player is dealt two cards initially
but can repeatedly ask for more cards by saying “twist”. One player is designated
the dealer. The dealer must twist while his cards have a total value of less than 16.
So we might write the rules for the dealer as:
But this solution implies that the dealer must take at least one card before deciding
to stop. Using the WHILE..ENDWHILE structure we could describe the logic as
Now determining if the sum is less than 16 is performed before Take another card
instruction. If the dealer’s two cards already add up to 16 or more, then the Take
another card instruction will be ignored.
Activity 1.22
A game involves throwing two dice. If the two values thrown are not the
same, then the dice showing the lower value must be rolled again. This
process is continued until both dice show the same value.
and
Choose dice with lower value
Activity 1.23
3. What type of loop structure should be used when looping needs to occur an
exact number of times?
4. What type of loop structure can bypass its loop body without ever executing
it?
Data
Almost every game requires the players to remember or record some facts and
figures. In our number guessing game described earlier, the players needed to
remember the original number and the guesses made; in Hangman the word being
guessed and the letters guessed so far must be remembered.
These examples introduce the need to process facts and figures (known as data).
Every computer game has to process data. This data may be the name of a character,
the speed of a missile, the strength of a blow, or some other factor.
a name
and a value
In programming, a data item is often referred to as a variable. This term arises from
the fact that, although the name assigned to a data item cannot change, its value may
vary. For example, the value assigned to a variable called lives remaining, will be
reduced if the player’s character is killed.
Activity 1.24
List the names of four data items that might be held about a player in a game
of Monopoly.
Operations on Data
There are four basic operations that a computer can do with data. These are:
Input
This involves being given a value for a data item. For example, in our
number-guessing game, the player who has thought of the original number is given
the value of the guess from the second player. When playing Noughts and Crosses
adding an X (or O) changes the set up on the board. When using a computer, any
value entered at the keyboard, or any movement or action dictated by a mouse or
joystick would be considered as data entry. This type of action is known as an input
operation.
Calculation
Most games involve some basic arithmetic. In Monopoly, the banker has to work
out how much change to give a player buying a property. If a character in an
adventure game is hit, points must be deducted from his strength value. This type
of instruction is referred to as a calculation operation.
Comparison
Often values have to be compared. For example, we need to compare the two
numbers in our guessing game to find out if they are the same. This is known as a
comparison operation.
Output
The final requirement is to communicate with others to give the result of some
calculation or comparison. For example, in the guessing game player 1
communicates with player 2 by saying either that the guess is Correct, Too high or
Too low.
Similarly, when we need to compare values, rather than use terms such as is less
than, we use the less than symbol (<). A summary of these relational operators is
given in TABLE-1.6.
TABLE-1.6 English Symbol
Relational Operators is less than <
is less than or equal to <=
is greater than >
is greater than or equal to >=
is equal to =
is not equal to <>
As well as replacing the words used for arithmetic calculations and comparisons
with symbols, the term calculate or set is often replaced by the shorter but more
cryptic symbol := between the variable being assigned a value and the value itself.
Using this abbreviated form, the instruction:
becomes
Although the long-winded English form is more readable, this more cryptic style is
briefer and is much closer to the code used when programming a computer.
Below we compare the two methods of describing our guessing game; first in
English:
Activity 1.26
Levels of Detail
When we start to write an algorithm in English, one of the things we need to consider
is exactly how much detail should be included. For example, we might describe
how to record a programme on a video recorder as:
However, this lacks enough detail for anyone unfamiliar with the operation of the
machine. We could replace the first statement with:
This approach of starting with a less detailed sequence of instructions and then,
where necessary, replacing each of these with more detailed instructions can be used
to good effect when tackling long and complex problems.
Problem:
Describe how to make a cup of tea.
1. Fill kettle
2. Boil water
3. Put tea bag in teapot
4. Add boiling water to teapot
5. Wait 1 minute
6. Pour tea into cup
7. Add milk and sugar to taste
Before going any further, we must assure ourselves that this is a correct and full
(though not detailed) description of all the steps required to tackle the original
problem. If we are not happy with the solution, then changes must be made before
going any further.
1. Fill kettle
1.1 Remove kettle lid
1.2 Put kettle under tap
1.3 Turn on tap
1.4 When kettle is full, turn off tap
1.5 Place lid back on kettle
The numbering of the new statement reflects that they are the detailed instructions
pertaining to statement 1. Also note that the number system is not a decimal fraction
so if there were to be many more statements they would be numbered 1.6, 1.7, 1.8,
1.9, 1.10, 1.11, etc.
It is important that these sets of more detailed instructions describe how to perform
only the original task being examined - they must achieve no more and no less.
Sometimes the detailed instructions will contain control structures such as IFs,
WHILEs or FORs. Where this is the case, the whole structure must be included in
the detailed instructions for that task.
Having satisfied ourselves that the breakdown is correct, we proceed to the next
statement from the original solution.
2. Boil water
2.1 Plug in kettle
2.2 Switch on power at socket
2.3 Switch on power at kettle
2.4 When water boils switch off kettle
5. Wait 1 minute
Notice that this last expansion (step 7) has introduced IF statements. Control
structures (i.e. IF, WHILE, FOR, etc.) can be introduced at any point in an
algorithm.
Finally, we can describe the solution to the original problem in more detail by
substituting the statements in our LEVEL 1 solution by their more detailed
equivalent:
This is a LEVEL 2 solution. Note that a level 2 solution includes any LEVEL 1
statements which were not given more detail (in this case, the statement Wait 1
minute).
For some more complex problems it may be necessary to repeat this process to more
levels before sufficient detail is achieved. That is, statements in LEVEL 2 may need
to be given more detail in a LEVEL 3 breakdown.
The game of battleships involves two players. Each player draws two 10 by 10
grids. Each of these have columns lettered A to J and rows numbered 1 to 10.
In the first grid each player marks squares in the first grid to mark the
position of warships. Ships are added as follows
1 aircraft carrier 4 squares
2 destroyers 3 squares each
3 cruisers 2 squares each
4 submarines 1 square each
The squares of each ship must be adjacent and must be vertical or horizontal.
The first player now calls out a grid reference. The second player responds to
the call by saying HIT or MISS. HIT is called if the grid reference corresponds
to a position of a ship. The first player then marks this result on his second
grid using an o to signify a miss and x for a hit (see diagram below).
A B C D E F G H I J A B C D E F G H I J
1 1 O
2 2
3 A A A A 3 O
4 S 4
5 C C D 5
6 S D 6 X X X
7 D D D D 7 O
8 C S 8
9 S C 9
10 C C 10
If the first player achieves a HIT then he continues to call grid references until
MISS is called. In response to a HIT or MISS call the first player marks the
second grid at the reference called: 0 for a MISS, X for a HIT.
When the second player responds with MISS the first player’s turn is over,
and the second player has his turn.
The first player to eliminate all segments of the opponent’s ships is the
winner. However, each player must have an equal number of turns, and if both
sets of ships are eliminated in the same round the game is a draw.
The algorithm describing the task of one player is given in the instructions
below. Create a LEVEL 1 algorithm by assembling the lines in the correct
order, adding line numbers to the finished description.
REPEAT
Draw grids
Get reply
ENDIF
Call HIT
Call MISS
ENDWHILE
REPEAT
ELSE
We do this by going back to the original description of the task our algorithm is
attempting to solve. For example, let’s assume we want to check our number
guessing game algorithm. In the last version of the game we allowed the second
player to make as many guesses as required until he came up with the correct answer.
The first player responded to each guess by saying either “too low”, “too high” or
“correct”.
To check our algorithm for errors we must come up with typical values that might
be used when carrying out the set of instructions and those values should be chosen
so that each possible result is achieved at least once.
So, as well as making up values, we need to predict what response our algorithm
should give to each value used. Hence, if the first player thinks of the value 42 and
the second player guesses 75, then the first player will respond to the guess by saying
“Too high”.
Our set of test values must evoke each of the possible results from our algorithm.
One possible set of values and the responses are shown in TABLE-1.7.
TABLE-1.7
Test Data Expected Results
Test Data for the Number
number = 42
Guessing Game Algorithm
guess = 75 Says “Too high”
guess = 15 Says “Too low”
guess = 42 Says “Correct”
Next we create a new table (called a trace table) with the headings as shown in
FIG-1.14.
FIG-1.14
Any condition contained in
The Components of a the statement is written here The value currently
The result of the stored in each variable
Trace Table condition is written is given here
Contains the number here as T or F
of the instruction which Any value displayed
has been executed (or spoken) is shown here
Now we work our way through the statements in the algorithm filling in a line of
the trace table for each instruction.
Instruction 1 is for player 1 to think of a number. Using our test data, that number
will be 42, so our trace table starts with the line shown in FIG-1.15.
FIG-1.15 Instruction Condition T/F Variables Output
number guess
Tracing the First
Statement 1 42
The REPEAT word comes next. Although this does not cause any changes,
nevertheless a 2 should be entered in the next line of our trace table. Instruction 3
involves player 2 making a guess at the number (this guess will be 75 according to
our test data). After 3 instructions our trace table is as shown in FIG-1.16.
Because the condition is false, we now jump to instruction 6 (the ELSE line) and
on to 7. This is another IF statement and our table now becomes that shown in
FIG-1.18.
FIG-1.18
Instruction Condition T/F Variables Output
Tracing a Second number guess
Condition
1 42
2
3 75
4 guess = number F
6
7 guess < number F
Since this second IF statement is also false, we move on to statements 9 and 10.
Instruction 10 causes output (speech) and hence we enter this in the final column
as shown in FIG-1.19.
FIG-1.19
Instruction Condition T/F Variables Output
Recording Output number guess
1 42
2
3 75
4 guess = number F
6
7 guess < number F
9
10 Too high
FIG-1.20
Instruction Condition T/F Variables Output
Reaching the end of the number guess
REPEAT .. UNTIL
Structure 1 42
2
3 75
4 guess = number F
6
7 guess < number F
9
10 Too high
11
12
13 guess = number F
Activity 1.28
Create your own trace table for the number-guessing game and, using the
same test data as given in TABLE-1.7 complete the testing of the algorithm.
Summary
l Computers can perform many tasks by executing different programs.
Ø Sequence
Ø Selection
Ø Iteration
l A sequence is a list of instructions which are performed one after the other.
IF condition THEN
instructions
ELSE
instructions
ENDIF
REPEAT
instructions
UNTIL condition
WHILE condition DO
instructions
ENDWHILE
l Data items (or variables) hold the information used by the algorithm.
Input
Calculated
Compared
or Output
Multiplication * Addition +
Division / Subtraction -
l The symbol := is used to assign a value to a data item. Read this symbol as is
l LEVEL 2 gives a more detailed solution by taking each sub-task from LEVEL
1 and, where necessary, giving a more detailed list of instructions required to
perform that sub-task.
l Further levels of detail may be necessary when using stepwise refinement for
complex problems.
IF letter appears in word THEN The AND operation is then performed giving:
Add letter at appropriate position(s)
ELSE IF false OR false THEN
Add part to hanged man
ENDIF
Next, the OR operation is completed giving a final
value of
Activity 1.7
IF false THEN
IF the crossbow is on target THEN
Say “Fire” and, therefore the player does not pick up an extra card.
ELSE
IF the crossbow is pointing too high THEN
Say “Down a bit”
ELSE
Activity 1.13
IF the crossbow is pointing too low THEN IF (total of cards held is 43 OR hand has
Say “Up a bit” 4 cards of the same value ) AND hand
ELSE contains a Queen THEN
IF crossbow is too far left THEN
Say “Right a bit”
ELSE Activity 1.14
Say “Left a bit"
ENDIF 1. Sequence
ENDIF
Selection
ENDIF
ENDIF
Iteration
Throw dice
Add dice value to total Activity 1.22
Roll both dice
Activity 1.16 WHILE both dice do not match in value DO
Choose dice with lower value
Only one line, the FOR statement, would need to be Roll the chosen dice
changed, the new version being: ENDWHILE
FOR 10 times DO
Activity 1.23
To call out the average, the algorithm would change to 1. Iteration means executing a set of instructions over and
over again.
Set the total to zero
FOR 10 times DO 2. The three looping structures are:
Throw dice
Add dice value to total FOR .. ENDFOR
ENDFOR REPEAT .. UNTIL
Calculate average as total divided by 10 WHILE .. ENDWHILE
Call out the value of average
3. The FOR .. ENDFOR structure.
4. The WHILE .. ENDWHILE structure.
Activity 1.17 5. The REPEAT .. UNTIL structure.
In fact, only the first line of our algorithm is not repeated,
so the lines that need to be repeated are: Activity 1.24
Player 2 makes an attempt at guessing the Number of properties held
number Amount of money held
IF guess matches number THEN The playing token being used
Player 1 says “Correct “
The position on the board
ELSE
IF guess is less than number THEN
Player 1 says “Too low”
ELSE
Activity 1.25
Player 1 says “Too high”
ENDIF
Input:
ENDIF Letter guessed
Word guessed
Calculations:
Activity 1.18 Where to place a correctly guessed letter
The number of wrong guesses made
The FOR loop forces the loop body to be executed Comparisons:
exactly 7 times. If the player guesses the number in The letter guessed with the letters in the word
less attempts, the algorithm will nevertheless The word guessed with the word to be guessed
continue to ask for the remainder of the 7 guesses. The number of wrong guesses with the value 6
(6 wrong guesses completes the drawing of the
Later, we’ll see how to solve this problem. hanged man)
Output:
Hyphens indicating each letter in the word
Activity 1.19 Gallows
FOR 6 times DO Body parts of the hanged man
Pick out ball Correctly guessed letters
Call out number on the ball
ENDFOR
Activity 1.27
The LEVEL 1 is coded as:
1. Draw grids
2. Add ships to left grid
3. REPEAT
4. Call grid position(s)
5. Respond to other player’s call(s)
6. UNTIL there is a winner
5.1.REPEAT
5.2 Get other player’s call
5.3 IF other player’s call matches position of ship THEN
5.4 Call HIT
5.5 ELSE
5.6 Call MISS
5.7 ENDIF
5.8 UNTIL other player misses
Activity 1.28
Instruction Condition T/F Variables Output
number guess
1 42
2
3 75
4 guess = number F
6
7 guess < number F
9
10 Too high
11
12
13 guess = number F
2
3 15
4 guess = number F
6
7 guess < number T
8 Too low
11
12
13 guess = number F
2
3 42
4 guess = number T
5 Correct
11
12
13 guess = number T
Correcting Errors
Executing a Program
Screen Output
There are many programming languages; C++, Java, C#, and Visual Basic being
amongst the most widely used. So how do we choose which programming language
to use? Probably the most important consideration is the area of programming that
is best suited to a given language. For example, Java is designed to create programs
that can be executed on a variety of different computers, while C++ was designed
for fast execution times.
This is exactly the approach the computer uses. We begin the process of creating a
new piece of software by mentally converting our structured English into
DarkBASIC Pro commands. These commands are entered using a text editor which
is nothing more than a simple word-processor-like program allowing such basic
operations as inserting and deleting text. Once the complete program has been
entered, we get the machine itself to translate those instructions into machine code.
The original code is known as the source code; the machine code equivalent is
known as the object code.
The compiler is a very exacting task master. The structure, or syntax, of every
statement must be exactly right. If you make the slightest mistake, even something
as simple as missing out a comma or misspelling a word, the translation process
will fail. When this happens in DarkBASIC Pro the incorrect command is
highlighted in red.
But a second file, known as the project file is also produced. This second file is
created automatically by DarkBASIC Pro and contains details of any images,
sounds or other resources that might be used by your program.
When we compile our program (translating it from source code to object code), yet
another file is produced. This third file, the executable file, contains the object code
and is, again, created automatically.
To run our program, the source code in the executable file is loaded into the
computer’s memory (RAM) and the instructions it contains are carried out.
FIG-2.1 Design
algorithm
Creating Software
Convert
to program code
Save source code
and project details
to disk
Compile
program
Save object code
to disk
If we want to make changes to the program, we load the source code into the editor,
make the necessary changes, then save and recompile our program, thereby
replacing the old version of all three files.
Activity 2.1
The language was invented by Lee Bamber who formed a company to sell
DarkBASIC Pro. Over the last few years the company has grown in size and
expanded to sell other DarkBASIC related products, such as DarkMatter, which
contains many 3D objects that can be used in DarkBASIC programs.
In fact, there are two versions of the language: DarkBASIC and DarkBASIC
Professional. It’s this second, enhanced version of the language we will be using
here.
To do this DarkBASIC Pro creates two files every time you produce a new program
(see FIG-2.2).
The first of these files, known as the project file, contains details of the images and
sounds used by your program, as well as other information such as the screen
resolution and number of colours used. This file has a .dbpro extension.
The second file, known as the source file, contains only the program’s code written
in the DarkBASIC Pro language. This file has a .dba extension.
Every DarkBASIC Pro program creates two files
FIG-2.2
DarkBASIC Pro Start-Up Screen (First Start-Up Only) DarkBASIC Pro Start-Up Screen (Subsequent Start-Ups)
First Start-Up
If this is the first time DarkBASIC Pro has been run on your machine, as well as
the main window, the Assistant Window also shows on the right-hand side.
If you close down the Assistant Window the display changes to match that shown
in FIG-2.4, showing the Project Dialog box.
FIG-2.4
The Project Dialog Box
Subsequent Start-Ups
Click on this icon
to show the New Project
When DarkBASIC Pro is started up for the second (or subsequent) time, use the
dialog FILE | NEW PROJECT option from the main menu, or click on the New Project icon
near the top left corner, to display the Project Dialog box.
Specifying a Project
The next stage is to create a project file by filling in the details required by the
Project Dialog box.
First the name to be given to the project is entered. This should be something
meaningful like Hangman or SpaceMonsters.
Once the OK button in the Project Dialog box is clicked, the dialog box disappears
and you are left with the main edit area where the program code is entered. Line
numbers appear to the left of this area.
A First Program
Before we begin looking in detail at the commands available in DarkBASIC Pro,
we’ll have a quick look at a simple program and show you how to type it in, run it
and save the code.
The program in LISTING-2.1 gets you to enter your name at the keyboard and then
displays a greeting on the screen.
When you type in a INPUT This is a keyword in DarkBASIC Pro. Keywords are words
program, you’ll see that
recognised by the programming language as having a
the instructions are
colour-coded with specific meaning.
keywords appearing in
blue. All keywords are shown throughout this text in uppercase,
but lowercase characters are also acceptable.
WAIT KEY This command contains two key words which tell the
computer to wait for a key to be pressed before continuing
to the next instruction.
Activity 2.2
In this Activity you are going to type in and run the program given in
LISTING-2.1.
The first three lines of the program will appear automatically (only the date
and time will differ from that in LISTING-2.1).
Click on this icon
to execute your
program Type in the remainder of the program as shown in LISTING-2.1.
Execute the program by pressing the F5 key or clicking on the Run icon.
When requested, type in your name. You should then see a message including
your name displayed on the screen.
Finally, press any key to finish the program and return to the editor.
FIG-2.6
Files Created by
DarkBASIC Pro
If you ever want to give away your completed programs to other people, you only
need to give them a copy of the .exe file. This contains everything they need to run
your program without allowing them to see your original DarkBASIC Pro code.
Activity 2.4
When opening the file
in Notepad, change the
File of Type entry to All Without closing down DarkBASIC Pro, load up Notepad (it’s in Accessories)
Files. and open up the file first.dba.
Notice that the file only contains the three REM statements which were
generated automatically when you opened your new project. None of the
lines you typed in are present.
Activity 2.5
Ending a Program
The END Statement
The first statement we examine is the one that should come at the end of any program
you write. It consists of the single keyword END and, as you might have guessed,
marks the end of your program.
Some of the statements available in DarkBASIC Pro have quite a complex syntax
so, to help show exactly what options are available when using a statement, we’ll
use informal syntax diagrams. FIG-2.7 shows a syntax diagram for the END
statement.
FIG-2.7
The END Statement END
These diagrams contain one or more tiles. A raised tile (like the one above) signifies
a DarkBASIC Pro keyword. The order of the tiles signifies the order in which the
keywords must be placed when using this statement in your program.
So the diagram above tells us that the END statement contains only the single word
END.
For example, in the program given in LISTING-2.1, the computer will pause after
the PRINT statement is executed.
For most simple programs, you need to include a WAIT KEY statement
immediately before the END statement, otherwise your program will finish and
close down before you get a chance to view what is being displayed on the screen.
Comments are totally ignored by the translation process as it turns DarkBASIC Pro
statements into machine code. The purpose of comments is to make a program more
readable to other people who may have to modify a program after you’ve moved
on to other things.
Ø Add the keyword REM. The remainder of the line becomes a comment
(see FIG-2.9).
FIG-2.9
The REM Comment REM comment
Notice that this syntax diagram introduces the sunken tile. Sunken tiles
signify details that are determined by the programmer. Hence, the
programmer gets to choose exactly what comment should be added after the
keyword REM. For example:
Adding asterisks to a
comment helps it to stand out. REM *** Program to display numbers ***
Ø Add an opening quote character (you’ll find this on the top left key, just
next to the 1). Again the remainder of the line is treated as a comment
(see FIG-2.10).
FIG-2.10
The ‘ Comment ` comment
For example:
FIG-2.11
REMSTART
The REMSTART ..
REMEND Comment
comment line
REMEND
For example, we can use this statement to create the following comment
which contains three comment lines:
REMSTART
This program is designed to play the game of
battleships. Two peer-to-peer computers are
required.
REMEND
Activity 2.6
In DarkBASIC Pro the simplest way to display information on the screen is to use
the PRINT statement. Other statements exist which allow changes to the colour,
font and style of displayed characters to be specified.
A description of most of these statements are given over the next few pages
To use it, we start with the keyword PRINT, followed by whatever information we
want to display. For example, the statement
PRINT “Hello”
displays the word Hello on the screen. The quotes themselves are not displayed.
Absolutely any set of characters can appear between the quotes, including spaces.
Unfortunately, all the values in this statement will be displayed without any spaces
between them giving the impression of one large number (1271.2) rather than three
separate values.
To solve this problem we need to display some spaces between the numbers:
To turn this into a complete program we just need to add the WAIT KEY and END
statements as shown in LISTING-2.2.
Activity 2.7
In the Project dialog box that appears, call the project printing.dbpro; select
Specify a Folder; browse to your DarkBASICProjects folder and click OK.
Remember to save the Source and Project files when you have finished.
The PRINT statement can even be used without any data values being given, as in
the line
PRINT
This has the effect of creating a blank line on the screen. Hence, the lines
PRINT 1
PRINT
PRINT 2
would display the values 1 and 2 with a blank line between them.
Activity 2.8
Modify your last program so that a blank line appears between each number
displayed.
If you end a PRINT statement with a string and a semicolon, the output produced
by the next PRINT statement will be displayed on the same line. For example, the
lines:
PRINT 12,"";
PRINT 7
PRINT 1.2
127
1.2
As you will see later, this apparently useless option can be used to great effect.
Write a program which displays the numbers 1, 2 and 3 on the same line.
There should be a small gap between each number.
Change your program so that the numbers 1, 2 and 3 are displayed on separate
lines.
Modify the code again so that the program pauses before each number is
shown. (HINT: You’ll need to add a WAIT KEY statement after each PRINT
statement.)
Activity 2.10
Write a program (call the project Shapes) to display the following three
shapes (pause the program between each):
a) **********
**********
**********
b) *
**
***
****
*****
c) *
**
***
****
*****
[ data item
,
[ ;
This diagram introduces two new concepts. Items within the brackets are optional
and may be omitted. Any number of data items can be displayed, but each must be
separated from the next by a comma.
Activity 2.11
Using the information given in the PRINT statement’s syntax diagram, which
of the following PRINT statements are invalid?
a) PRINT
b) PRINT “Start game”
c) PRINT 7;
d) PRINT "";
e) PRINT 6,5,4;
A pixel’s position is given by the column number (also known as the position on
the x-axis) followed by the row number (the position on the y-axis) separated by a
comma.
The top left pixel is at position (0,0). This point is known as the origin.
FIG-2.13
The origin
The Screen is Made Up of (0,0)
0 1 2 3 4 5 6
The x-axis (columns)
Pixels 0
1
2
3
4
5
6
Position
(6,2)
The y-axis (rows)
The Screen
Exactly how many pixels are on the screen depends on the screen resolution (which
we will examine later) but there will be at least 640 columns by 480 rows.
displays the word HELLO, with the top-left comer of the H starting at position
(350,100) (i.e. at column 350, row 100) as shown in FIG-2.14.
FIG-2.14 The
0
0 1 2 x-axis
3 4 5 6 (columns)
1
2
3
4
The top-left corner of
Positioning Text Using the
5
6 the text starts at position
(350,100)
SET CURSOR Statement
The y-axis (rows)
The Screen
Activity 2.12
(You’ll have to use trial and error to find the correct positions)
Activity 2.13
Since we can output at any position on the screen, this allows us to display
different values at the same position on the screen.
has the same effect as the SET CURSOR example given earlier, although you may
find that the program uses a different screen resolution when the output is displayed.
Your screen will almost
certainly use a different
resolution when using the Activity 2.14
TEXT statement than it
did in previous programs. Change your corners.dbpro project so that it uses the TEXT command to
This means that in this
Activity you’ll have to
position the letters in the corners of the screen.
change the coordinates
from those used in the
There are a few differences between the PRINT and TEXT commands.
previous example.
Activity 2.15
Change your overwrite.dbpro project replacing the SET CURSOR and PRINT
commands with equivalent TEXT statements.
The second difference is that the TEXT command will only display strings, so a
line such as
TEXT 100, 100, 12
where the statement attempts to display the value 12 is not acceptable and will cause
an error message to appear when you attempt to run the program. Of course, by
enclosing the 12 in quotes you turn it from a number into a string and this would
be accepted:
A final difference is that the TEXT command can only be used to display a single
value at a time. Hence, a statement such as
would fail since there are two strings in the command. Again, this could be
corrected, this time by joining the two strings:
Activity 2.16
We can change the font style and size used when outputting text by using the SET
TEXT FONT and SET TEXT SIZE commands. Once a new font and size has been
set, any subsequent output statements will be done in this style.
will result in the Courier New font being used by any subsequent output.
will result in subsequent output using characters that are 20/72 of an inch tall.
The following program (LISTING-2.3) outputs the word HELLO in large, bold,
Courier New font:
LISTING-2.3 REM *** Use Courier New size 20 bold ***
SET TEXT FONT “Courier New”
Setting Text Size, Font SET TEXT SIZE 20
and Style SET TEXT TO BOLD
PRINT “HELLO”
WAIT KEY
Type in and test the program given in LISTING-2.3. Name the project
fonts.dbpro.
Change the code so that all of the text is displayed in Times New Roman.
{ }
BOLD
The SET TEXT TO
Statement
BOLDITALIC
SET TEXT TO
ITALIC
NORMAL
This diagram introduces another new feature. The braces are used to enclose items
which are mutually exclusive alternatives. In other words, the statement is
completed by choosing one of the options given in the braces.
Changing Colours
So far we’ve had white text on a black background, but you’re free to choose any
colours you want for both the text and the background. Before we see how to do
that in DarkBASIC Pro, let’s start with some basic facts about colour.
Every other colour that you see on the screen is made up from those three colours.
For example, to show the colour yellow, the screen combines the colours red and
green; red, green and blue together produce white; when all three basic colours are
switched off, we have black.
This is known as the additive colour process and the colours red, green and blue
are known as the primary colours. The basic colours that can be constructed from
these three primary colours are shown in FIG-2.22.
FIG-2.22
Green
The Additive Colour
Process
Yellow Cyan
White
As you can see from the figure above, green and blue combine to give a colour
To create other colours and shades we need only to vary the brightness of the
primary colours. Hence, to create orange we use an intense red, a less intense green,
and no blue.
In computer systems the colour of any spot on the screen is recorded as a series of
three numbers. These numbers represent the intensities of the red, green and blue
(RGB) components (in that order) that make up the colour of the spot. Each number
can range between 0 and 255; 0 means that the colour is not used, while 255 means
that the colour is at full brightness. Hence, a bright yellow spot on the screen will
be recorded as 255, 255, 0, meaning that the red and green are at full intensity, and
the blue is switched off.
PRINT RGB(255,255,0)
Activity 2.18
integer
In the diagram:
How do you find out the red, green and blue values of some particularly nice shade
of orange? Luckily, the DarkBASIC Pro editor can help. If you are busy typing in
a program and suddenly need to supply the three values required by an RGB
statement, you can simply right-click in the edit window. The resulting pop-up menu
(see FIG-2.24) has an RGB Color Picker option which, when selected, displays a
colour palette (see FIG-2.25).
FIG-2.24
The DarkBASIC Pro
Editor’s Pop-Up Menu
Colour values
can be selected
with the help of the
RGB Color Picker option
FIG-2.25
The Colour Palette Box
Selecting a colour from this palette and clicking OK automatically produces an RGB
statement in your program code with the appropriate values to match the colour
selected. We’ll use this in the next Activity.
In the diagram:
The colour values themselves are created using the RGB command. So to have our
text output in yellow on a red background we would use the command:
Where you want to use black, rather than use RGB (0, 0, 0) you may simply enter
the value zero. For example, to change the foreground to blue and the background
to black, we would use the statement
INK RGB(0,0,255) ,0
Once you have set the ink colour, any output you do to the screen will be in that
colour. For example, we would expect the program in LISTING-2.4 to display the
word HELLO in yellow on a red background.
LISTING-2.4 REM *** Set yellow foreground and red background ***
INK RGB(255,255,0) , RGB(255,0,0)
Setting Foreground and PRINT “HELLO”
Background Colours
REM *** End program ***
WAIT KEY
END
Activity 2.19
Delete the first RGB command within the INK statement and use the RGB
Color Picker option to replace it with a colour of your choice.
Notice that the background colour in the INK command was set to red and yet the
colour behind the letters is still black. If you want to know why, read on!
There are two main areas to any text that appears on the computer screen: the text
and the text background (see FIG-2.27).
FIG-2.27
Text
Text background
Text Areas
Hello Screen
background
Screen
The foreground colour setting determines the colour of the text itself while the
background colour sets the colour used in the text background. However, normally
the text background is transparent so setting the background colour appears to have
no effect. Usually, a transparent background will be exactly what we want, since it
allows us to do things such as place text on top of an image, and have the image
still show through the text (see FIG-2.28) but, as we’ll see in a moment, we can
change this transparent background setting.
Activity 2.20
the word Hello should appear in blue with a yellow background around the text.
Activity 2.21
Add the line SET TEXT OPAQUE to start of your previous program.
Change the program so that the word GOODBYE shows in cyan with a
magenta background.
CLS
This gives a empty black screen. However, if you don’t want the screen to be black,
you can clear the screen to another colour by specifying a colour setting in
conjunction with the CLS statement. For example, to create a green screen, use the
line:
CLS RGB(0,255,0)
In the diagram:
The program in LISTING-2.5 displays the word HELLO several times using both
opaque and transparent modes. The screen colour is set to red.
REM *** Output the word HELLO twice with opaque background ***
SET TEXT OPAQUE
PRINT “HELLO”
PRINT “HELLO”
Activity 2.23
*************
* BOX *
*************
Use Courier New, size 20, bold for the text.
The asterisks should be yellow and the word BOX in blue with a black
background.
Summary
l The CLS statement clears the screen using a given colour.
l The PRINT statement moves the cursor to a new line unless it finishes with a
semicolon.
l The SET CURSOR statement moves the cursor to any position on the screen.
l The TEXT statement will output a single string at any position on the screen.
l The CENTER TEXT statement will output a string centred round a specified
position.
l The INK statement sets the foreground and background colours used.
l The SET TEXT FONT statement sets the font to be used when displaying
information.
l The SET TEXT SIZE statement sets the size to be used in text output.
l The SET TEXT BOLD statement sets the text style to be used for output to bold.
l The SET TEXT BOLDITALIC statement sets the text style to be used for output
to bold italics.
l The SET TEXT ITALIC statement sets the style to be used for output to italics.
l The SET TEXT NORMAL statement sets the style to be used for output to
normal.
l The WAIT KEY statement causes the program to halt until any key is pressed.
Luckily, we can choose which resolution we want the program’s output to use by
clicking on the brown Settings button at the bottom right of screen. In the resulting
Configure EXE Settings window we can choose the resolution we want to use (see
FIG-2.33).
FIG-2.33
Setting the Screen 1
Resolution Select the type
of display required
Here it is
Fullscreen Exclusive Mode
2
Click on the
Pick button
3
From the Dimensions
combobox, choose the
resolution required
To set the screen to a resolution of 1280 by 1024 using 32 bit pixels we would use
the line
It is only valid to chose a resolution which can be achieved by your video card and
screen. Attempt to set an invalid resolution will produce an error message.
Most fonts are proportional fonts. That is, the horizontal width of a character
depends on what that character is. Hence, w’s take up more width than i’s. You can
see this in the two lines below:
wwwwww
iiiiii
But some fonts are mono-spaced. In this style every character takes up the same
width, as you can see below:
wwwwww
iiiiii
When you’re working in the DarkBASIC Pro editor entering the lines of your
program, the text is displayed in a mono-spaced font, but the default font used by
your program when outputting to the screen is a proportional font.
Erasing Text
Back in Activity 2.15, we saw that when the TEXT command is used to output more
than one item to the same area of the screen it created an unreadable blob. We need
some way of getting rid of the old text before outputting new text at the same
position.
Activity 2.24
There should be 5 spaces between the quotes in the second TEXT statement.
A second method of erasing text is to overwrite with exactly the same text, but this
time in the background colour. The logic of our strategy is:
Run the program and check that the text (Hello) is correctly erased.
Modify the TEXT statements in the program so that word Goodbye is erased
from position 100,80.
Shadow Text
We can create shadowed text by writing the same text in different colours at slightly
R
offset positions. This needs the following logic:
Activity 2.26
Embossed Text
By creating two versions of a text, we achieved shadowed text; by creating three
copies, we can produce an embossed effect.
CLS RGB(126,126,126)
REM *** Embossed Text ***
INK RGB(0,0,0),0
TEXT 201,201,"Goodbye"
INK RGB(255,255,255),0
TEXT 199,199,"Goodbye"
INK RGB(126,126,126),0
TEXT 200,200,"Goodbye"
Try modifying the font, size and colours used as well as the offset values to
create the best effect.
Summary
l The screen resolution used by your program can be set manually using the
Settings button.
l The screen resolution can be set from within your program using the SET
DISPLAY MODE statement.
l Text can be erased from the screen by overwriting it with opaque spaces.
l Text can be removed from the screen by overwriting it with the same text in the
background colour.
l Shadow text can be created by outputting a darker version of the text and then
overwriting it with the same text slightly offset from the original and in a different
colour.
1. Machine code (or object code) instructions REM *** Display numbers on the separate
2. Compiler lines
3. A syntax error PRINT 1
PRINT 2
PRINT 3
REM *** End program ***
Activity 2.2 WAIT KEY
END
No solution required.
Version 3:
Activity 2.3
REM *** Display numbers on the separate
1. A keyword lines ***
2. Strings PRINT 1
3. Causes the program to pause until a key is pressed. WAIT KEY
PRINT 2
WAIT KEY
PRINT 3
Activity 2.4 REM *** End program ***
WAIT KEY
No solution required.
END
The second string writes on top of the first without REM *** Clear screen to red ***
removing it. We'll see a cure for this later in the chapter. CLS RGB(255,0,0)
REM *** Set text characteristics ***
SET TEXT FONT “Courier New”
SET TEXT TO BOLD
Activity 2.16 SET TEXT SIZE 20
REM *** Set colours (yellow and red) ***
For 1248 by 1024, the program code is:
INK RGB(255,255,0),RGB(255,0,0)
REM *** Output box ***
CENTER TEXT 623,500, “MIDDLE” TEXT 0, 0, “**********”
REM *** End program *** TEXT 0,20, “* *”
WAIT KEY TEXT 0,40, “**********”
END REM *** Set opaque text ***
SET TEXT OPAQUE
REM *** Set colours (blue and black) ***
Activity 2.17 INK RGB(0,0,255),RGB(0,0,0)
REM *** Output text ***
The second line of the LISTING-2.3 should be changed TEXT 34,18,"BOX"
to REM *** End program
WAIT KEY
SET TEXT FONT “Times New Roman” END
Activity 2.18
PRINT RGB(255,255,0)
Activity 2.24
Activity 2.26
Existing code is in grey:
Activity 2.27
Existing code is in grey:
Arithmetic Operators
Assignment Statement
Constants
Input Statement
String Operations
Variables
Variable Names
For example, if player Daniel McLaren had 3 lives and 10.6 minutes to complete a
game, then:
Activity 3.1
a) -9 f) 0
b) abc g) -3.0
c) 18 h) Mary had a little lamb
d) 12.8 i) 4 minutes
e) ? j) 0.023
Constants
When a specific value appears in a computer program’s code it is usually referred
to as a constant. Hence, in the statement
PRINT 7
the value 7 is a constant. More specifically, we may refer to constant’s type. In the
line
Charlotte is a string constant, 15, an integer constant, and 42.7, a real constant.
Note that in DarkBASIC Pro, string constants always appear within double quotes.
Activity 3.2
Integer Variables
In DarkBASIC Pro variables are created automatically as soon as we mention them
in our code. For example, let’s assume we want to store the number of lives allocated
to a game player in a variable called lives. To do this in DarkBASIC Pro we simply
write the line:
lives = 3
This sets up a variable called lives and stores the value 3 in that variable (see
FIG-3.1)
FIG-3.1
lives Value stored
Storing Data in a in the variable
Variable name 3
Variable
You are free to change the contents of a variable at any time by just assigning it a
different value. For example, we can change the contents of lives with a line such
as:
lives = 2
When we do this any previous value will be removed and the new value stored in
its place (see FIG-3.2).
FIG-3.2 The contents of
lives lives are changed
Changing the Value in a
Variable 2
The variable lives is designed to store an integer value. In the lines below, a, b, c,
d, and e are also integer variables. So the following assignments are correct
a = 200
b = 0
c = -8
since they attempt to store real constants in variables designed to hold an integers.
DarkBASIC Pro won’t actually report an error if you try out these last two examples,
it simply ignores the fractional part of the numbers and ends up storing 3 in d and
1 in e (see FIG-3.3).
Real Variables
If you want to create a variable capable of storing a real number, then we must end
the variable name with the hash (#) symbol. For example, if we write
d# = 3.14
e# = -1.9
we have created variables named d# and e#, both capable of storing real values(see
FIG-3.4).
FIG-3.4 d# e#
d# = 3.14 3.14 e# = -1.9 -1.9
Creating Real Variables
The complete
number is stored
Any number can be stored in a real variable, so we could also write a statement such
as:
d# = 12
If any value can be stored in a real variable, why bother with integer variables?
Actually, you should always use integer values wherever possible because the
computer is much faster at handling integer values than reals which require much
more processing whenever you want to do any calculations. Also, real numbers can
be slightly inaccurate because of rounding errors within the machine. For example,
the value 2.3 might be stored as 2.2999987.
String Variables
Finally, if you want to store a string value, you need to use a string variable. String
variable names must end with a dollar ($) sign. The value to be stored must be
enclosed in double quotes. We could create a string variable named player$ and
store the name Liz Heron in it using the statement:
player$ = “Liz Heron”
The double quotes are not stored in the variable (see FIG-3.5).
FIG-3.5 player$
Absolutely any value can be stored in a string variable as long as that value is
enclosed in double quotes. Below are a few examples:
Activity 3.3
Which of the following are valid DarkBASIC Pro statements that will store
the specified value in the named variable?
a) a = 6 d) d# = 5
b) b = 12.89 e) e$ = ‘Goodbye’
c) c$ = Hello f) f# = -12.5
a = 3
b = 120
c = 2000
lives = 3
points = 120
timeremaining = 2000
which give a much clearer indication of what the variables are being used for.
Naming Rules
DarkBASIC Pro, like all other programming languages, demands that you follow
a few rules when you make up a variable name. These rules are:
a
bc
de_2
fgh$
iJKlmnp#
are invalid.
The most common mistake people make is to have a space in their variable names
(e.g. fuel level). This is not allowed. As a valid alternative, you can replace the space
with an underscore (fuel_level) or join the words together (fuellevel). Using capital
letters for the joined words is also popular (FuelLevel).
Note that the names no, no# and no$ represent three different variables; one
designed to hold an integer value (no), one a real value (no#) and the last a string
(no$).
Activity 3.4
a) x e) total score
b) 5 f) ts#o
c) “total” g) end
d) al2$ h) G2_F3
Summary
l Fixed values are known as constants.
l A variable is a space within the computer’s memory where a value can be stored.
l Variables that end with the # symbol can hold real values.
l Variables that end with the $ symbol can hold string values.
l The name given to a variable should reflect the value held in that variable.
In its simplest form the assignment statement has the form shown in FIG-3.6.
FIG-3.6
The Assignment variable = value
Statement
The value copied into the variable may be one of the following types:
Ø a constant
Ø another variable
Ø an arithmetic expression
Examples of each are shown below.
Assigning a Constant
This is the type of assignment we’ve seen earlier, with examples such as
where a fixed value (a constant) is copied into the variable. Make sure that the
constant is the same type as the variable. For instance, the statement
desc = “tall”
is invalid since it attempts to copy a string constant (“tall”) into an integer variable
(desc). Not every mistake will be signalled by the compiler. For example, if we try
to assign a real constant to an integer variable as in the statement
result = 12.79
the integer variable result stores only the integral part of the constant (i.e. 12), the
fractional part being lost.
However, an integer value may be copied into a real variable, as in the line:
result# = 33
The program deals with this by storing the value assigned to result# as 33.0.
What are the minimum changes required to make the following statements
correct?
1. desc = “tall”
2. result = 12.34
no1 = 12
we can copy the contents of that variable into another variable with a command
such as:
no2 = no1
As before, you must make sure the two variables are of the same type, although the
contents of an integer variable may be copied to a real variable as in the lines:
ans# = no1
Although not invalid, trying this the other way round (real copied to integer) as in
ans# = 12.94
no1 = ans#
will cause no1 to store only the integral part of ans# contents (i.e. 12).
Activity 3.6
no1 = 23
weight# = 125.8
description$ = “sword”
no1 = 7 + 3
The example shows the use of the addition operator, but there are 5 possible
operators that may be used when performing a calculation. These are shown in
TABLE-3.1.
TABLE-3.1 Operator Function Example
The result of most statements should be obvious. For example, if a program begins
with the statements
no1 = 12
no2 = 3
then the variable total will contain the value 9, while the line
The remainder operator (mod) is used to find the integer remainder after dividing
one integer into another. For example,
ans = 9 mod 5
assigns the value 4 to the variable ans since 5 divides into 9 once with a remainder
of 4. Other examples are given below:
6 mod 3 gives 0
7 mod 9 gives 7
123 mod 10 gives 3
Activity 3.7
a) 12 mod 5 c) 5 mod 11
b) -7 mod 2 d) -12 mod -8
The power operator ( ^ ) allows us to perform a calculation of the form xy. For
example, a 24-bit address bus on the microprocessor of your computer allows 224
addresses = 2^24
However, the results of some statements are not quite so obvious. The line
ans# = 19/4
will result in the value 4.0 being stored in ans# since the division operator always
returns an integer result if the two values involved are both integer. On the other
hand, if we write
ans# = 19/4.0
and thereby use a real value, then the result stored in ans# will be 4.75.
When a real value is copied into an integer variable, the fractional part of the value
being copied is lost. For example, the variable result would contain the value 4 after
executing the line
result = 19/4.0
When using the division operator, a second situation that you must guard against is
division by zero. In mathematics, dividing any number by zero gives an undefined
result, so computers get quite upset if you try to get them to perform such a
calculation. Hence, the line
ans = 10/0
would cause a program to crash when it attempted to perform that line in the
program. You might be tempted to think that you would never write such a
statement, but a more likely scenario is that your program contains a line such as
and if no2 contains the value zero attempting to execute the line will still cause the
program to terminate.
Some statements may not appear to make sense if you are used to traditional algebra.
For example, what is the meaning of a line such as:
no1 = no1 + 3
FIG-3.8
no1
Adding to a Variable’s 20
no1 is assigned
Contents an initial value
no1 = 20
no1 = no1 + 3
3 is added to ...
no1
... the current value of no1 ...
23
... and the result stored in no1
no1 = -no1
The effect of this statement is to change the sign of the value held in no1. For
example, if no1 contained the value 12, the above statement would change that value
to -12. Alternatively, if no1 started off containing the value -12, the above statement
would change no1‘s contents to 12.
Activity 3.8
no1 = 2
v# = 41.09
answer = no1 - 3 / v# * 2
and, how the final result of such lines is calculated is determined by operator
precedence.
Operator Precedence
If we have a complex arithmetic expression such as
answer# = 12 + 18 / 3^2 - 6
then there’s a potential problem about what should be done first. Will we start by
adding 12 and 18 or subtracting 6 from 2, raising 3 to the power 2, or even dividing
18 by 3. In fact, calculations are done in a very specific order according to a fixed
set of rules. The rules are that the power operation (^ ) is always done first. After
that comes multiplication and division with addition and subtraction done last. The
power operator ( ^ ) is said to have a higher priority than multiplication and division;
they in turn having a higher priority than addition and subtraction.
So, to calculate the result of the statement above the computer begins by performing
the calculation 3^2 which leaves us with:
answer = 12 + 18 / 9 - 6
answer = 12 + 2 - 6
The remaining operators, + and -, have the same priority, so the operations are
performed on a left-to-right basis meaning that we next calculate 12+2 giving
answer = 14 - 6
answer = 8
Activity 3.9
Using Parentheses
If we need to change the order in which calculations within an expression are
performed, we can use parentheses. Expressions in parentheses are always done
first. Therefore, if we write
answer = 30 / 9 - 6
answer = 3.3333 - 6
answer = -2.6667
Activity 3.10
If sets of parentheses are placed inside one another (this is known as nested
parentheses) , then the contents of the inner-most set is calculated first. Hence, in
the expression
12 / (3 * (10 - 6) + 4)
Activity 3.11
They are often disappointed when the program crashes at this point.
There is a limit to the value that can be stored in a variable. That limit is determined
by how much memory is allocated to a variable, and that differs from language to
language. The range of values that can be stored in DarkBASIC Pro variables is
shown in TABLE-3.2.
TABLE-3.2 Variable Type Range of Values
Variable Range
integer -2,147,483,648 to + 2,147,483,647
real ±3.4 E ± 38
String Operations
The + operator can also be used on string values to join them together. For example,
if we write
a$ = “to” + “get”
then the value toget is stored in variable a$. If we then continue with the line
b$ = a$ + “her”
b$ will contain the value together, a result obtained by joining the contents of a$ to
the string constant “her”.
Activity 3.12
PRINT 12
PRINT “Hello”
We can also get the PRINT statement to display the answer to a calculation. Hence,
PRINT 7+3
number = 23
by the line
PRINT number
our program will display the value 23 on the screen, this being the value held in
number. Real and string variables can be displayed in the same way. Hence the lines
name$ = “Charlotte”
weight# = 95.3
PRINT name$
PRINT weight#
Charlotte
95.3
Activity 3.13
Activity 3.14
Type in and test the following program (don’t bother to save the program):
number = 23
PRINT number
WAIT KEY
END
Change the program by removing the first two lines and replacing this with
two statements which will assign the value Jessica McLaren to a variable
called name$ and then display the contents of name$ on the screen.
The PRINT statement can display more than one value at a time. For example, we
can get it to display the number 12 and the word Hello at the same time by writing
PRINT 12,"Hello"
Each value we want displayed must be separated from the next by a comma. We
can use this to display a message alongside the contents of a variable. For example,
the lines
capital$ = “Washington”
PRINT “The capital of the USA is ”, capital$
Write a program (name.dbpro) that sets the contents of the variable name$ to
Jessica MacLaren and then uses a PRINT statement that displays the contents
of name$ in such a way that the final message on the screen becomes:
INPUT name$
expecting the person at the keyboard to type in their name and then storing what
they type in the variable name$. Of course, the player has to be told what sort of
information they are expected to enter, so we could precede the INPUT statement
with a message telling them what to type in :
DarkBASIC Pro makes things simpler than this by allowing us to include the
message we want displayed as part of the INPUT statement. Hence, we can achieve
the same effect as the two statements above using the line:
This gives us the final format for the INPUT statement as shown in FIG-3.9.
FIG-3.9
The INPUT Statement INPUT [ message , variable
In the diagram:
a) INPUT age
b) INPUT “Enter your height ”, height#
c) INPUT “Enter your salary ” salary
Activity 3.17
We can use the INPUT statement anywhere in our program and as often as
necessary.
Activity 3.18
Modify your last program so that it also reads in the age of the player and
displays a message of the form:
Hello, {name goes here}, I see you are {age goes here} years old.
daysinmonth = 31
PRINT daysinmonth
daysinmonth = 28
PRINT daysinmonth
daysinmonth = 31
PRINT daysinmonth
DATA 31,28,31,30,31,30,31,31,30,31,30,31
and then use a READ statement every time we want to assign a value to
daysinmonth.
READ daysinmonth
DATA 31,28,31,30,31,30,31,31,30,31,30,31
READ daysinmonth
PRINT daysinmonth
READ daysinmonth
PRINT daysinmonth
READ daysinmonth
PRINT daysinmonth
31
READ daysinmonth
Each READ statement causes
another value to be taken from
the DATA statement READ daysinmonth
daysinmonth
28
Is this second approach any better than the first? You should have noticed that by
using the DATA/READ approach we repeat exactly the same statements over and
over again. In a later chapter we will see that this code can be shortened by using a
loop statement which would not be possible with the first approach.
The computer simply groups the values given in the DATA statements into a single
list, so the two DATA statements above have exactly the same effect as:
DATA 31,28,31,30
The DATA statement can contain values of any type. The next example stores the
names of the first three days of the week:
Of course, when you read from this DATA statement, the variable being assigned
the value must be a string:
READ day$
The type of values in a DATA statement can even be mixed, containing integer,
real or string constants in any order. It is only important that READ statements use
the type of variable appropriate to the next value coming from the DATA statement.
We might write
DATA 12, 2.7, “Hello”
READ no1
READ x#
READ word$
and this would be acceptable because variables and values being read are of
matching types. That is, the first READ statement would assign the integer value
12 to the integer variable no1; the second READ would assign the real value 2.7 to
the real variable x# and the third READ would assign the string “Hello” to the string
variable word$. It’s also possible to read the value of more than one variable in a
single READ statement. Hence, we could reduce the three statements above to the
single line:
The format for the DATA statement is shown in FIG-3.11 and the format of the
READ statement is shown in FIG-3.12.
FIG-3.11
The DATA Statement DATA constant
,
In the diagram:
,
In the diagram:
An error will be reported if your program contains a READ statement but no DATA
statement. An error will also occur if a READ statement is executed after all the
values in the DATA statement have been used.
Activity 3.19
Write a short program (days01.dbpro) which displays the names of the days of
the week. Start with Sunday.
The names should be set up in a DATA statement, then accessed using a series
of READ statements.
Initially this marker points to the first value in the first DATA statement. After each
READ the marker moves on one position. However, it is possible to return the
marker to the start of the DATA list by executing the RESTORE statement.
DATA 3,6,9,12
READ no1
READ no2
RESTORE
READ no3
the variable no3 will be assigned the value 3 because the RESTORE statement will
have moved the DATA marker back to the first value in the list.
Activity 3.20
Modify your last program so that after all the days of the week have been
displayed the word Sunday is displayed for a second time.
You can achieve this result by adding a RESTORE statement, another READ
statement and a PRINT statement to your program.
FIG-3.14
TIMER ( )
The TIMER Statement
integer
So the TIMER statement could be used to display how long your machine has been
on with the single line
PRINT TIMER ()
but this would be in milliseconds. Perhaps a better option would be to save the value
returned by TIMER and convert that value to seconds, as in the lines:
millisecondsPassed = TIMER()
seconds = millisecondsPassed / 1000
PRINT “Your computer has been on for ”, seconds, “ seconds”
Activity 3.21
By using TIMER before and after some event we can measure how long that event
lasts. For example, we could create a simple reaction time game by seeing how
quickly the user can press a key after being told to do so. Such a program requires
the following logic:
Activity 3.22
FIG-3.15
The GET TIME$
GET TIME$ ( )
Statement
string
For example, we could display the current time using the line:
string
The string returned is in the American form MM/DD/YY. For example, when run
at the time of writing, the statement
PRINT RND(10)
RND has to be supplied with a value enclosed in parentheses. This value lets the
command know what range of possible values may be generated. Notice that the
lowest value that can be generated is always zero, while the largest value is equal
to the number given in the brackets.
Activity 3.23
integer
The value given within the parentheses can also be a variable or arithmetic
expression, as in the lines:
num = 25
PRINT RND (num) ‘0 to 25
PRINT RND (num*2-3) ‘0 to 47
The value returned by RND could be stored in a variable using a statement such as:
number = RND(10)
If RND(5) generates a number between 0 and 5, how are we going to emulate a dice
throw which gives values 1 to 6? Often people suggest writing RND(6), but this
gives values in the range 0 to 6, not 1 to 6.
Instead we have to generate a value between 0 and 5 and then add 1 to that number.
diceThrow = RND(5)+1
and follow this with a PRINT statement displaying the contents of diceThrow:
But to get the mathematics started correctly, we need to supply it with a start up
value or seed value. Effectively this seed value determines what numbers the
computer is going to generate when RND is used.
The seed value is set up using the RANDOMIZE statement which has the format
shown in FIG-3.18.
FIG-3.18
The RANDOMIZE
Statement RANDOMIZE seed
In the diagram:
Exactly what seed value you use doesn’t really matter, but if you start with the same
seed value every time, you’ll always get the same set of values from RND. For
example, if a program contained the lines
every time that program is executed, the same numbers would be displayed.
To stop this happening we need to make sure that the seed value is different every
time we run a program. We can achieve this using the TIMER statement. So if we
write
number = TIMER()
RANDOMIZE number
then, since TIMER will return a different value every time it’s carried out
(remember the time in your computer is being updated 1000 times per second), the
seed value for RANDOMIZE will always be different. Actually, we can combine
the two statements above into one:
RANDOMIZE TIMER()
Now we are ready to write a program using random numbers. The program in
LISTING-3.1 simulates a dice throw and displays the number generated.
Activity 3.24
Activity 3.25
The computer displays both the guess and the original number
Since the RGB statement also returns a value, we can use that same approach there.
So rather than write
INK RGB(255,0,0),RGB(0,255,0)
we could write
colour1 = RGB(255,0,0)
colour2 = RGB(0,255,0)
INK colour1, colour2
Activity 3.26
Named Constants
When a program uses a fixed value which has an important role (for example,
perhaps the value 1000 is the score a player must achieve to win a game), then we
have the option of assigning a name to that value using the #CONSTANT statement.
In the diagram:
For example, we can name the value 1000 WinningScore using the line:
Real and string constants can also be named, but the names assigned must NOT end
with # or $ symbols. Therefore the following lines are valid
it is not valid to try to assign a new value with a line such as:
WinningScore = 1900
The two main reasons for using named constants in a program are:
than
to
Every program we write needs to be tested. For a simple sequential program that
involves input, the minimum testing involves thinking of a value to be entered,
predicting what result this value should produce, and then running the program to
check that we do indeed obtain the expected result.
The program below (see LISTING-3.2) reads in a value from the keyboard and
displays the square root of that number.
To test this program we might decide to enter the value 16 with the expectation of
the result being 4.
Activity 3.27
Type in the program given above (root.dbpro) and test it by inputting the
value 16.
Perhaps that would seem sufficient to say that the program is functioning correctly.
However, a more cautious person might try a few more values just to make sure.
But what values should be chosen? Should we try 25 or 9, 3 or 7?
As a general rule it is best to think carefully about what values you choose as test
data. A few carefully chosen values may show up problems when many more
randomly chosen values show nothing.
When the test data is numeric, the most obvious choices are to use a typical value
(in the case of the above program, 16 falls into this category), a very large value, a
negative value and zero. But in each case it is important that you work out the
expected result before entering your test data into the program - otherwise you have
no way of knowing if the results you are seeing on the screen are correct.
Activity 3.28
What results would you expect from root.dbpro if your test data was
401286
0
-9
Run the program with these test values and check that the expected results are
produced.
When entering string test values, an empty string (just press Enter when asked to
enter the data), a single character string, and a multicharacter string should do.
These suggestions for creating test data may need to be modified depending on the
nature of the program you are testing.
Summary
l The assignment statement takes the form
variable = value
l The value assigned should be of the same type as the receiving variable.
l Calculations are performed on the basis of highest priority operator first and a
left-to-right basis.
l The power operator has the highest priority; multiplication and division and the
mod operator the next highest, followed by addition and subtraction.
l The INPUT statement reads a value from the keyboard and places that value in
a named variable.
l The INPUT statement can display a message designed to inform the user what
has to be entered.
l The DATA and READ statements can be used to assign a listed value to a
variable.
l The RESTORE statement forces a return to the start of the first DATA statement.
l The TIMER statement returns the time in milliseconds from switch on.
l The RANDOMIZE statement ensures that the numbers created by the RND are
truly random.
l The value returned by statements such as RND and RGB can be assigned to a
variable.
Screen Settings
The SCREEN HEIGHT Statement
The SCREEN HEIGHT statement returns the height of the output screen in pixels
and has the format shown in FIG-3.20.
FIG-3.20
The SCREEN HEIGHT SCREEN HEIGHT ( )
Statement
integer
For example, the statement
would display the value 600, assuming the screen resolution was set to 800 by 600.
integer
For example, the statement
would assign the value 800 to the variable screenwidth, assuming the screen
resolution was set to 800 by 600.
The program in LISTING-3.3 displays the word WELCOME at the centre of the
screen.
Activity 3.29
The SCREEN DEPTH statement returns the number of bits used per pixel and has
the format shown in FIG-3.22.
FIG-3.22
The SCREEN DEPTH SCREEN DEPTH ( )
Statement
integer
If a call to this statement returns the value 16, then the number of colours that can
be shown is calculated as 216. The code required to perform this calculation is:
Colour Components
If we were to generate a random colour with the lines
RANDOMIZE TIMER()
colour = RGB(RND(255),RND(255),RND(255))
we could find out the settings of the red, green and blue components of that colour
using the following statements.
integer
In the diagram:
Hence, assuming the variable colour had been set using the line given earlier, we
could extract the red component of that colour with the line
redvalue = RGBR(colour)
integer
In the diagram:
integer
In the diagram:
Activity 3.30
Text Settings
Details of the text font, size and style currently being used by a program can be
retrieved using the following statements.
FIG-3.26
TEXT BACKGROUND TYPE ( )
The TEXT
BACKGROUND
Statement
integer
The statement returns the value zero if a transparent background is being used; 1 is
returned when the background setting is opaque.
The integer value returned lies between 0 and 3 (0 - normal; 1 - italic; 2 - bold; 3 -
bold italic).
integer
integer
string
integer
In the diagram:
integer
In the diagram:
The program in LISTING-3.5 demonstrates the use of the statements in this section.
LISTING 3.5 REM *** Set text characteristics ***
SET TEXT FONT "Arial"
Display Text
SET TEXT TO BOLD
Characteristics
SET TEXT SIZE 20
SET TEXT OPAQUE
Activity 3.31
Summary
l Use SCREEN WIDTH to find the current screen width setting.
l Use SCREEN DEPTH to find how many bits are used to represent one screen
pixel.
l Use RGBR to find the value of the red component in a specified colour.
l Use RGBB to find the value of the blue component in a specified colour.
Activity 3.3
Activity 3.10
a) Valid
b) Invalid. Integer variable will store 12 Steps
c) Invalid. Hello should be enclosed in double
quotes(“Hello”) 8*(6-2)/(3-1)
d) Valid 8*4/(3-1)
e) Invalid. Must be double quotes, not single quotes 8*4/2
f) Valid 32/2
16
Activity 3.4
Activity 3.11
a) Valid
b) Invalid. Must start with a letter answer = no1 / (4 + no2 - 1) * 5 - no3 ^ 2
answer = 12 / (4 + 3 - 1) * 5 - 5 ^ 2
c) Invalid. Names cannot be within quotes.
answer = 12 / (7 - 1) * 5 - 5 ^ 2
d) Valid answer = 12 / 6 * 5 - 5 ^ 2
e) Invalid. Spaces are not allowed in a name answer = 12 / 6 * 5 - 25
f) Valid answer = 2 * 5 - 25
g) Invalid, end is a DarkBASIC Pro keyword answer = 10 - 25
h) Valid answer = -15
Activity 3.13
Activity 3.6
Output:
a) Valid
b) Invalid. Fraction part lost number
c) Invalid. A string cannot be copied to an integer 23
variable
d) Valid
e) Invalid. A real cannot be copied to a string variable Activity 3.14
f) Invalid. A string cannot be copied to a real variable
The final version of the program should read:
Activity 3.24
Activity 3.20
The RND line needs to be changed to read:
Existing lines are in grey.
RND(48) + 1
REM *** Set up names of days of the week ***
DATA
“Sunday”,“Monday”,“Tuesday”,“Wednesday”, Activity 3.25
“Thursday”,“Friday”,“Saturday”
REM *** Generate random value ***
REM *** Read and display each day ***
RANDOMIZE TIMER()
READ day$
number = RND(99)+1
PRINT day$
REM *** Guess the number ***
READ day$
INPUT “Enter your guess (1 to 100) : ”
PRINT day$
,guess
READ day$
REM *** Display both values
PRINT day$
PRINT “Number was ”, number," Guess was “
READ day$
,guess
Activity 3.26
REM *** Assign colours ***
scarlet = RGB(255,0,0)
sky = RGB(0,0,255)
CLS scarlet
INK sky, scarlet
PRINT “Ocean”
REM *** End program ***
WAIT KEY
END
Activity 3.27
No solution required.
Activity 3.28
Test Value Expected Result
401286 633.471
0 0
-9 Undefined
Activity 3.29
The text is not centred vertically since the CENTER TEXT
statement positions the top of the text at the y-ordinate
specified. To be correctly centred, the middle of the text
would have to positioned at this y-ordinate.
Activity 3.30
No solution required
Activity 3.31
No solution required.
Boolean Conditions
IF..ENDIF Statement
IF..THEN Statement
Nested IF Statements
Relational Operators
SELECT Statement
IF condition THEN
action
ENDIF
Hence, in our guessing game we described the response to a correct guess as:
Say Correct
ENDIF
As we’ll see, DarkBASIC Pro also makes use of an IF statement to handle such
situations.
The IF Statement
In its simplest form the IF statement in DarkBASIC Pro takes the format shown in
FIG-4.1.
FIG-4.1
IF condition
The Simple IF Statement
statement
Notice that DarkBASIC
Pro’s IF statement does
ENDIF
not contain the word
THEN
In the diagram:
If condition evaluates to true, then the set of statements between the IF and ENDIF
terms are executed; if condition evaluates to false, then the set of statements are
ignored and execution moves on to the statements following the ENDIF term.
An unlimited number of statements may be placed between the IF and ENDIF terms.
Condition
Generally, the condition will be an expression in which the relationship between
two quantities is compared. For example, the condition
no < 0
will be true if the content of the variable no is less than zero (i.e. negative).
In the diagram:
TABLE-4.1
English Symbol
Relational Operators
is less than <
is less than or equal to <=
is greater than >
is greater than or equal to >=
is equal to =
is not equal to <>
The values being compared should be of the same type, but it is acceptable to mix
integer and real numeric values as in the conditions:
v > x#
t# < 12
name$ = 34
no1 <> “16"
are invalid.
Activity 4.1
IF name$ = “Fred”
the condition will only be considered true if the match is an exact one (see FIG-4.3),
even the slightest difference between the two strings will return a false result.
FIG-4.3
“fred” ”Fred” “broadsword” “broad sword”
Comparing Strings
IF name$ = “Fred”
IF village$ <> “Turok”
it is also valid to test if one string value is greater or less than another. For example,
it is true that
Such a condition is considered true not because B comes after A in the alphabet,
but because the coding used within the computer to store a “B” has a greater numeric
value than the code used to store “A”.
The method of coding characters is known as ASCII (American Standard Code for
Information Interchange). This coding system is given in Appendix A at the back
of the book.
If you are comparing strings which only contain letters, then one string is less than
another if that first string would appear first in an alphabetically ordered list. Hence,
But watch out for upper and lower case letters. All upper case letters are less than
all lower case letters. Hence, the condition
is true.
If two strings differ in length, with the shorter matching the first part of the longer
as
then the shorter string is considered to be less than the longer string. Also, because
the computer compares strings using their internal codes, it can make sense of a
condition such as
which is also considered true since the $ sign has a smaller value than the ? character
in the ASCII coding system.
Activity 4.2
Determine the result of each of the following conditions (true or false). You
may have to examine the ASCII coding at the end of the book for part f).
TABLE-4.2 shows some Structured English IF statements and the DarkBASIC Pro
equivalents.
The program in LISTING-4.1 reads in two numbers and displays a message if the
numbers are equal. The program employs the following logic:
ENDIF
Notice the use of indentation in the program listings. DarkBASIC Pro does not
demand that this be done, but indentation makes a program easier to read - this is
particularly true when more complex programs are written.
Activity 4.3
Type in and test the program in LISTING-4.1 (Call the project same.dbpro)
Modify the program you created for project guess.dbpro, so that, after the
player has typed in his guess, the program displays the word Correct if the
guess and number are equal.
In the next program (see LISTING-4.2) a real value representing the radius of a
circle is read from the keyboard. As long as a valid value has been entered (i.e. a
value greater than zero) then the area of the circle is calculated and displayed.
Notice that this time we have more than one statement within the IF structure.
Write separate DarkBASIC Pro programs for each of the following tasks:
(Name the projects act4_5_1.dbpro, act4_5_2.dbpro, etc.)
1. Read in an integer number (no1) and display the message “Negative value”
if the number is less than zero.
2. Read in a real number representing the width and height of a square. If the
number is greater than zero, calculate and display the area of the square.
3. Read in a word. If the word is “yes”, display the message “Access granted".
The term AND should be used when we need two conditions to be true before an
action should be carried out. For example, if a game requires you to throw two sixes
to win, this could be written as:
RANDOMIZE TIMER ()
dice1 = RND(5) + 1
dice2 = RND(5) + 1
IF dice1 = 6 AND dice2 = 6
PRINT “You win!”
ENDIF
The statement PRINT “You win!” will only be executed if both conditions, dice1=
6 and dice2 = 6, are true.
Activity 4.6
Using the code given above, if dice1 = 6 and dice2 = 5, will the statement
PRINT “You win!” be carried out?
You may recall from Chapter 1 that there are four possible combinations for an IF
statement containing two simple expressions. Because these two conditions are
linked by the AND operator, the overall result will only be true when both conditions
are true. These combinations are shown in TABLE-4.3.
TABLE-4.3
condition 1 condition 2 condition 1 AND condition 2
The AND Operator
false false false
false true false
true false false
true true true
RANDOMIZE TIMER ()
dice1 = RND(5) + 1
dice2 = RND(5) + 1
total = dice1 + dice2
IF total = 7 OR total = 11
PRINT “You win!”
ENDIF
Again, the computer reduces the individual Boolean expressions to either true or
false. If at least one of the individual conditions is true, then the overall result is also
true. This time the four possible combinations give the results shown in TABLE-4.4
TABLE-4.4
condition 1 condition 2 condition 1 OR condition 2
The OR Operator
false false false
false true true
true false true
true true true
Activity 4.7
If no1 =10 and no2 = 7, which of the following IF statements will evaluate to
true?
There is no limit to the number of conditions that can be linked using AND and OR.
For example, a statement of the form
IF condition1 AND condition2 AND condition3
means that all three conditions must be true, while the statement
Activity 4.8
A game requires 3 dice to be thrown. If at least two dice show the same value,
the player has won.
ENDIF
Modify your previous project Act4_5_3 so that the message “Access granted"
is displayed if the word input is either “yes” or “YES”.
Once we start to create conditions containing both AND and OR operators, we must
remember that the AND operator takes precedence over the OR operator. Therefore,
the statement
IF dice = 5 OR dice = 2 AND card$ = “Ace”
means that throwing a dice value of 5 is sufficient to give us an overall result of true
and it does not matter what value card$ is. However, it we don’t throw a 5, then we
must throw a 2 and card$ must be equal to “Ace” to achieve an overall true result.
The normal rule of performing the AND operation before OR can be modified by
the use of parentheses. Expressions within parentheses are always evaluated first.
Hence, if we write
IF (dice = 5 OR dice = 2) AND card$ = “Ace”
= false
Activity 4.10
(score > 20 OR lives > 2) AND (weaponpower < 1 OR ammunition >= 200)
will evaluate as
= NOT false
= true
Activity 4.11
When money =100 and cards =21, what is the result of the condition:
IF guess = number
PRINT “Correct”
ENDIF
One way to do this is to follow the first IF statement with another testing the opposite
condition:
IF guess = number
PRINT “Correct”
ENDIF
IF NOT guess = number
PRINT “Wrong”
ENDIF
Although this will work, it’s not very efficient since we always have to test both
conditions - and the second condition can’t be true if the first one is!
As an alternative, we can add the word ELSE to our IF statement and follow this
by the action we wish to have carried out when the stated condition is false:
IF guess = number
PRINT “Correct”
ELSE
PRINT “Wrong”
ENDIF
Activity 4.12
This gives us the longer version of the IF statement format as shown in FIG-4.4.
FIG-4.4
The IF..ELSE Statement IF condition
statement
ELSE
statement
ENDIF
Modify your guess.dbpro project so that the message “Wrong” appears if the
player guesses the wrong number.
Activity 4.14
Activity 4.15
Modify project act4_5_4.dbpro so that the program displays the word “Odd”
if an odd value is entered.
FIG-4.5
The Alternative IF IF condition THEN
Statement
statement
statement
As you can see from the diagram, this version uses the word THEN but omits the
ENDIF term. You can have as many statements as you need in each section (after
THEN and ELSE) but these must be separated by colons.
A major restriction when using this version of the IF statement is that the keyword
ELSE, if used, must appear on the same line as the term IF. Hence, it is invalid to
write:
Rewrite the IF statement you created in Activity 4.12 to use this alternative
version of the IF statement.
It is probably best to avoid this version of the IF statement, since the requirement
to place the IF and ELSE terms on the same line does not allow a good layout for
the program code.
Activity 4.17
Summary
l Conditional statements are created using the IF statement.
l Conditions linked by the AND operator must all be true for the overall result to
be true.
l Only one of the conditions linked by the OR operator needs to be true for the
overall result to be true.
l When the NOT operation is applied to a condition, it reverses the overall result.
l The statements following a condition are only executed if that condition is true.
l Statements following the term ELSE are only executed if the condition is false.
IF
condition 1:
action1
condition 2:
action 2
ELSE
action 3
ENDIF
However, this structure is not available in DarkBASIC Pro and hence we must find
some other way to implement multi-way selection.
Nested IF Statements
One method is to use nested IF statements - where one IF statement is placed within
another. For example, let’s assume in our number guessing game that we want to
display one of three messages: Correct, Your guess is too high, or Your guess is too
low. Our previous solution allowed for two alternative messages: Correct or Wrong
and was coded as:
IF guess = number
PRINT “Correct”
ELSE
PRINT “Wrong”
ENDIF
In this new problem the PRINT “Wrong” statement needs to be replaced by the two
alternatives: Your guess is too high, or Your guess is too low. But we already know
how to deal with two alternatives - use an IF statement. In this case, our IF statement
If we now remove the PRINT “Wrong” statement from our earlier code and substitute
the four lines given above, we get:
IF guess = number
PRINT “Correct”
ELSE
IF guess > number
PRINT “Your guess is too high”
ELSE
PRINT “Your guess is too low”
ENDIF
ENDIF
Modify your guess.dbpro project so that the game will respond with one of
three messages as shown in the code given above.
Activity 4.19
Technically, the number zero is neither positive nor negative, hence we should
really produce a third message: Zero when number = 0.
Modify your earlier solution to this previous task to achieve this requirement.
We’ll start by working out the difference between our guess and the computer’s
number using the line
Now, if we’ve guessed the number correctly, then difference will be zero. However,
if we’ve gone too high, then difference will be a positive number. On the other hand,
a low guess will result in difference being negative. When difference is a small value
(either positive or negative) then guess must be close to number. The complete
program is given in LISTING-4.3.
Activity 4.21
Once a value for day has been entered, the SELECT statement chooses the CASE
statement that matches that value and executes the code given within that section.
All other CASE statements are ignored and the instruction following the END
SELECT statement (not shown above) is the next to be executed. For example, if
day = 3, then the statement given beside CASE 3 will be executed (i.e. PRINT
“Tuesday” ). If day were to be assigned a value not given in any of the CASE
statements (i.e. a value outside the range 1 to 7), the whole SELECT statement
would be ignored and no part of it executed.
Optionally, a special CASE statement can be added at the end of the SELECT
CASE 7
PRINT “Saturday”
ENDCASE
CASE DEFAULT
PRINT “Invalid day”
ENDCASE
ENDSELECT
then, if a value outside the range 1 to 7 is entered, this last CASE statement will be
executed. FIG-4.6 shows how the SELECT statement is executed.
FIG-4.6 1
expression is evaluated
and reduced to a single value
How the SELECT
statement operates
SELECT expression
CASE value2
action
ENDCASE 2 - option 2
If expression matches none of
. the values given, the
DEFAULT action is executed...
.
If no DEFAULT option is given
CASE DEFAULT the whole SELECT structure is ignored
action
ENDCASE
ENDSELECT
Several values can be specified for each CASE option. If the SELECT value
matches any of the values listed, then that CASE option will be executed. For
example, using the lines
the word Odd would be displayed if any odd number between 1 and 9 was entered.
The values given beside the CASE keyword may also be a string as in the example
below:
it is a bad idea to use these since the machine cannot store real values accurately. If
a real variable contained the value 1.52000001 it would not match with the CASE
value given above.
CASE value
,
statement
ENDCASE
[
CASE DEFAULT
statement
ENDCASE
ENDSELECT
In the diagram:
Activity 4.22
Activity 4.23
Write a project (Grading) which accepts a score from the keyboard and
displays the grade assigned according to the following rules:
INPUT no
IF no <= 0
PRINT “This is a negative number”
ENDIF
then we need to have a test value for no which is less than zero and another which
is not less than zero. Perhaps the values -8 and 3.
Another important test is to find out what happens when the variable’s value is
exactly equal to the value against which it is being tested. In the above case that
would mean testing the code with no set to 0. Very often this is the only value which
will highlight a problem in the code.
Activity 4.24
Since zero is not a negative number we have discovered an error in our code. The
line
IF no <= 0
IF no < 0
We would not have detected this error if we hadn’t used zero as our test value.
When an IF statement contains more than one condition linked with AND or OR
operators, testing needs to check each possible combinations of true and false
settings. For example, if a program contained the line
then our tests should include all possible combinations for the two conditions as
shown in TABLE-4.5.
TABLE-4.5 dice1 = 6 dice2 = 6 dice1 = 6 AND dice2 = 6
dice1 = 3 dice2 = 5
dice1 = 4 dice2 = 6
dice1 = 6 dice2 = 1
dice1 = 6 dice2 = 6
dice1 = RND(5) +1
to
to allow the test to take place. Once the tests have been completed, the INPUT lines
would be replaced by the original code.
But the last two combinations in the table are impossible to achieve since the
variable dice cannot contain the values 5 and 2 at the same time. So our test data
will have test values which create only the remaining 6 combinations.
then each path through the structure must be tested. For the above code this means
that we must test for the following conditions being true:
guess = number
guess > number
guess < number
To test a SELECT structure, then every value mentioned in every CASE option
must be tested. Hence, the lines
INPUT “Enter a number ” , num
SELECT num
CASE 1, 3, 5, 7, 9
PRINT “Odd”
ENDCASE
CASE 2,4,6,8,10
Summary
l The term nested IF statements refers to the construct where one IF statement is
placed within the structure of another IF statement.
l The CASE line can have any number of values, each separated by a comma.
l The CASE DEFAULT option is executed when the value being searched for
matches none of those given in the CASE statements.
l Testing a simple IF statement should ensure that both true and false results are
tested.
l SELECT structures should be tested by using every value specified in the CASE
statements.
l SELECT should also be tested using a value that does not appear in any of the
CASE statements.
Activity 4.22
REM *** Get number ***
INPUT “Enter item number (1 - 4) : ”, no
REM *** Display appropriate message ***
SELECT no
CASE 1
PRINT “A sword”
ENDCASE
CASE 2
PRINT “A wand”
ENDCASE
CASE 3
PRINT “A bag of dragon’s teeth”
ENDCASE
CASE 4
PRINT “A water skin”
ENDCASE
CASE DEFAULT
PRINT “Unknown item”
ENDCASE
ENDSELECT
REM *** End program ***
WAIT KEY
END
Activity 4.23
REM *** Get numberRead score
INPUT “Enter your score : ”, score
REM *** Display appropriate message ***
SELECT score / 100
CASE 0
PRINT “Pathetic”
ENDCASE
CASE 1
PRINT “Beginner”
ENDCASE
CASE 2
PRINT “Apprentice”
ENDCASE
CASE 3
PRINT “Competent
ENDCASE
CASE 4
PRINT “Master”
ENDCASE
CASE 5
PRINT “Grand master”
DO .. LOOP Construct
EXIT Statement
SLEEP Statement
WAIT Statement
Introduction
Iteration is the term used when one or more statements are carried out repeatedly.
As we saw in Chapter 1, structured English has three distinct iterative structures:
FOR .. ENDFOR, REPEAT .. UNTIL and WHILE .. ENDWHILE.
DarkBASIC Pro, on the other hand, has four iterative structures. Most of these take
the same form as their structured English equivalent, but others differ slightly and
therefore care should be taken when translating structured English statements to
DarkBASIC Pro.
statement
ENDWHILE
In the diagram:
A visual representation of how this loop operates is shown in FIG-5.2. Note that
the loop body may never be executed if condition is false when first tested.
WHILE condition
2 - option 1 2 - option 2
if condition is true, if condition is false,
the loop body statements the program jumps to the
are executed end of the loop
After the loop body
has been executed, the program
returns to the start of the loop
and condition is retested
statement
ENDWHILE
Later Statements
A common use for this loop statement is validation of input. So, for example, in
our number guessing game, we might ensure that the user types in a value between
1 and 100 when entering their guess by using the logic
Get guess
WHILE guess outside the range 1 to 100 DO
Display error message
Get guess
ENDWHILE
Activity 5.1
Check that the program works correctly by attempting to make guesses which
are outside the range 1 to 100.
Activity 5.2
Activity 5.3
Get no1
Get no2
Get no2
ENDWHILE
Activity 5.4
A simple dice game involves counting how many times in a row a pair of
dice can be thrown to produce a value of 8 or less. The game stops as soon as
a value greater than 8 is thrown.
total = 0
REPEAT
INPUT “Enter a number : ”, number
total = total + number
UNTIL number = 0
statement
UNTIL condition
In the diagram:
1
REPEAT the statements in ...
the
loop body are executed
3 - option 1 statement 2
if condition is false, condition is tested
the loop body statements
are executed again
UNTIL condition
3 - option 2
if condition is true,
the program exits the loop
Later Statements
Activity 5.5
Activity 5.6
Modify project guess01.dbpro to allow the player to keep guessing until the
correct number is arrived at.
FOR 7 times DO
Deal card
ENDFOR
Sometimes the number of times the action is to be carried out is less explicit. For
example, if each player in a game is to pay a £10 fine we could write:
However, in both examples, the action specified between the FOR and ENDFOR
terms will be executed a known number of times.
In DarkBASIC Pro the FOR construct makes use of a variable to keep a count of
how often the loop is executed and takes the form:
FOR c = 1 TO 7
In this case c would be assigned the value 1 when the FOR loop is about to start.
Each time the action within the loop is performed, c will be incremented, and
eventually, once the action is performed with c equal to 7, iteration stops.
Activity 5.7
Write the first line of a FOR loop that is to be executed 10 times, using a
variable j which is to start with a value of 1.
The action to be performed within the loop (known as the loop body) can consist
of any number of statements. For example, the code
FOR k = 1 TO 10
PRINT “*”
NEXT k
contains a single statement within the loop body and will display a column of 10
asterisks.
Activity 5.8
FOR p = 1 TO 10
PRINT p
NEXT p
The loop counter in a FOR loop can be made to start and finish at any value, so it
is quite valid to start a loop with the line
FOR m = 3 TO 12
When executed, the loop counter m will contain the value 3 when the loop is first
executed and finish with the value 12. The loop will be executed exactly 10 times.
FOR r = 10 TO 10
Where the start value is greater than the finish value, the loop will not be executed
at all as in the line
FOR k = 10 TO 9
Normally, one is added to the loop counter each time the loop body is performed.
However, we can change this by adding a STEP value to the FOR loop as shown
below:
FOR c = 2 TO 10 STEP 2
In this last example the loop counter, c, will start at 2 and then increment to 4 on
the next iteration. The program in LISTING-5.1 uses the STEP option to display
the 7 times table from 1 x 7 to 12 x 7.
By using the STEP keyword with a negative value, it is even possible to create a
FOR loop that reduces the loop counter on each iteration as in the line:
FOR d = 10 TO 0 STEP -1
This last example causes the loop counter to start at 10 and finish at 0.
Activity 5.10
Modify the table.dbpro project so that the 12 times table is displayed with the
highest value first. That is, starting with 144 and finishing with 12.
It is possible that the step value given may cause the loop counter never to match
the finish value. For example, in the line
FOR c = 1 TO 12 STEP 5
the variable c will take on the values 1, 6, and 11. The loop will always stop before
the variable passes the finishing value.
The start, finish and even step values of a FOR loop can be defined using a variable
or arithmetic expression as well as a constant. For example, in LISTING-5.2 below
the user is allowed to enter the upper limit of the FOR loop.
The program will display every integer value between 1 and the number entered by
the user.
Activity 5.11
Modify the program so that the user may also specify the starting value of the
FOR loop.
Change the program a second time so that the user can specify a step size for
the FOR loop
Activity 5.12
Notice that most of the values displayed by the last Activity are slightly out. For
example, instead of the second value displayed being 1.1, it displays as
1.10000002384. This difference is caused by rounding errors when converting from
the decimal values that we use to the binary values favoured by the computer.
Although we might have expected the FOR loop to perform 11 times (1.0,1.1,1.2,
etc. to 2.0), in fact, it only performs 10 times up to 1.90000021458. Again, this
discrepancy is caused by the rounding error problem.
Activity 5.13
statement
NEXT variable
In the diagram:
Executing a FOR
.. NEXT Construct
If no incr value 2
is specified, 1 is variable is checked to
added to variable discover if it is greater than finish
statement
NEXT variable
Later Statements
TABLE-5.3 gives examples of structured English FOR loops and their DarkBASIC
Pro equivalents.
Activity 5.14
Create a new project (total.dbpro) which reads in and displays the total of 12
numbers.
The best approach would be to write down the first number you see on a piece of
paper and, every day when you are shown a new number, compare this new value
with what is written on the paper. If you are shown a smaller number than before,
erase the old number from your paper and write in the new one. Do this every day
and, by the end, the piece of paper will have a copy of the smallest number you saw
throughout the period.
This is exactly how we tackle the problem in a computer program. We set up one
variable to hold the smallest value we’ve come across and if a later value is smaller,
it is copied into this variable. The algorithm used is given below and assumes 10
numbers will be entered in total:
Activity 5.15
Modify the program to find the largest, rather than the smallest, of the
numbers entered.
Activity 5.16
In ice skating, a number of judges (N) award marks. The highest and lowest of
these are ignored and the others averaged to give a result. Write a program
(skating.dbpro) to input N (the number of judges), followed by N marks (the
mark given by each judge), and display the average score ignoring the highest
and lowest mark. (Scores range from 0.0 to 6.0 in increments of 0.1.)
The logic required by the program is:
ELSE
ENDIF
ENDIF
ENDFOR
Each time the FOR loop body is executed, the next value in the DATA statement
is retrieved by the READ statement, and so all 7 day names are displayed.
Activity 5.17
Modify your days01.dbpro project from Chapter 3 so that it makes use of the
FOR loop as described above to display the days of the week.
Activity 5.18
This doesn’t make play very exciting since the game now gives no sense of
playing against a deadline.
Modify the code so that a FOR loop is used in place of the REPEAT loop,
allowing the player 7 attempts at guessing the number.
The EXIT statement can For example, in a dice game we are allowed to throw a pair of dice 5 times and our
be used in any loop score is the total of the five throws. However, if during our throws we throw a 1,
structure, not just FOR then our turn ends and our final score becomes the total achieved up to that point
loops. (excluding the throw containing a 1). We could code this game as shown in
LISTING-5.3.
LISTING-5.3
REM ** Seed random number generator ***
Using the EXIT Statement RANDOMIZE TIMER ()
Activity 5.19
Run the program and check that the loop exits if a 1 is thrown.
Modify the program to exit only if both dice are 1's during a throw.
It has a very simple structure. In the example below, the code causes the word Hello
to be displayed over and over again:
DO
PRINT “Hello”
LOOP
Although there seems little likelihood that such a loop would be useful, it is, in fact,
often used to implement the main part of a game program with logic often following
the pattern:
DO
Get players command
Update players situation in the game
Update video display
LOOP
LOOP
DarkBASIC Pro will allow the user to escape from a DO .. LOOP structure by
pressing the Escape key.
Alternatively, an EXIT statement can be included within the loop to allow the loop
to be exited when a given condition occurs.
Activity 5.20
DO
Set the cursor to a random position
Before you test the program, make sure that the screen resolution is set to an
appropriate value for the random position you have created.
You’ll have to press the Escape key to get the program to stop.
In the diagram:
WAIT 1000
Activity 5.21
FIG-5.10
The SLEEP Statement SLEEP time
Modify the program to pause for one second before the message is displayed.
Since a player could predict when the message is going to appear on the
screen, he might be able to press a key just as the message appears. To stop
this, change the delay before the message appears to be anything between 1
and 2 seconds.
(HINT: You’ll need to use RND when setting the pause time.)
Nested Loops
A common requirement is to produce nested loops, that is situations where one loop
control structure appears within another. For example, to read in six game scores
(each between 0 and 100) and then calculate their average, the logic required is:
This appears to have only a single loop structure beginning at statement 2 and ending
at statement 5. However, if we add detail to statement 3, this gives us
which, if placed in the original solution, results in a nested loop structure, where a
WHILE loop appears inside a FOR loop.
Activity 5.23
0 1 On each iteration,
the units counter
... ...
is incremented...
0 2
...eventually reaching
its upper limit...
...
1 2
... units is repeated...
...eventually reaching
its upper limit once more...
...
2
...
0
FOR tens = 0 TO 9
FOR units = 0 TO 9
PRINT tens,units
NEXT units
NEXT tens
The tens loop is known as the outer loop, while the units loop is known as the inner
loop. A few points to note about nested FOR loops:
FOR no1 = -2 TO 1
FOR no2 = 0 TO 3
PRINT no1," “,no2
NEXT no2
NEXT no1
Activity 5.25
Do this by adding an outer FOR loop which executes four times (once for each
player).
To test the WHILE loop in this section of code we could use the test data shown in
TABLE-5.4.
TABLE-5.4 Test Run Test Data Iterations
2 guess = 0
guess = 98 1
3 guess = 101
guess = -9
guess = 50 2
The WHILE loop is only executed if guess is outside the range 1 to 100, so Test 1,
which uses a value in that range, will skip the WHILE loop - giving zero iterations.
Test 2 uses an invalid value for guess, causing the WHILE loop body to be executed,
and then uses a valid value. This loop is therefore exited after only one iteration.
Activity 5.26
total = 0
count = 0
INPUT “Enter number (end with 0) : ”, num
WHILE num <> 0
total = total + num
count = count + 1
INPUT “Enter number (end with 0): ”, num
ENDWHILE
average = total / count
PRINT average
WAIT KEY
END
Create a new project (average.dbpro) containing the code given above and use
the test data to find out if the code functions correctly.
All three tests are not always possible. For example, a REPEAT loop cannot execute
zero times and, in this case, we have to satisfy ourselves with single and multiple
iteration tests.
A FOR loop, when written for a fixed number of iterations can only be tested for
that number of iterations. So a loop beginning with the line
FOR c = 1 TO 10
can only be tested for multiple iterations (10 iterations in this case). The exception
being if the loop body contains an EXIT statement, in which case zero and one
iteration tests may also be possible.
FOR c = 1 TO max
may be fully tested by making sure max has the values 0, 1, and more than 1 during
testing.
A DO loop can only be tested for zero and one iterations if it contains an EXIT
statement.
Summary
l DarkBASIC Pro contains four iteration constructs:
WHILE . . ENDWHILE
REPEAT . . UNTIL
l The REPEAT..UNTIL construct executes at least once and exits when the
specified condition is true.
l A STEP size may be included in the FOR statement. The value specified by the
STEP term is added to the loop counter on each iteration.
l The start, finish and STEP values in a FOR loop can be defined using variables
or arithmetic expressions.
l If the start value is equal to the finish value, a FOR loop will execute only once.
l If the start value is greater than the finish value and the STEP size is a positive
value, a FOR loop will execute zero times.
l One loop structure can be placed within another loop structure. Such a structure
is known as a nested loop.
l Loops should be tested by creating test data for zero, one and multiple iterations
during execution whenever possible.
Activity 5.17
REM *** Set up day names ***
Activity 5.20
DATA “Sunday”, “Monday”, “Tuesday”,
First version:
“Wednesday”, “Thursday”, “Friday”,"Saturday"
REM *** Read and display each day ***
REM *** Seed random number generator ***
FOR c = 1 TO 7
RANDOMIZE TIMER()
READ day$
DO
PRINT day$
REM *** Generate random position ***
NEXT c
x = RND(799)
REM *** End program ***
y = RND(599)
WAIT KEY
REM *** Move cursor to position ***
END
SET CURSOR x,y
REM *** Create random foreground colour ***
INK RGB(RND(255) ,RND(255) ,RND(255) ) ,0
Activity 5.18 REM *** Display full stop ***
REM *** Generate random value *** PRINT “.”
RANDOMIZE TIMER() LOOP
number = RND(99)+1 REM *** End program ***
FOR c = 1 TO 7 WAIT KEY
REM *** Guess the number *** END
INPUT “Enter your guess (1 to 100) : ”,
guess Second version:
WHILE guess < 1 OR guess > 100
PRINT “Your guess must be between 1 REM *** Seed random number generator ***
and 100" RANDOMIZE TIMER()
INPUT “Enter your guess again (1-100):”, DO
guess REM *** Generate random position ***
ENDWHILE x = RND(799)
REM *** Respond to guess *** y = RND(599)
IF guess = number REM *** IF (100,100) THEN Exit loop ***
PRINT “Correct” IF x = 100 AND y = 100
ELSE EXIT
1 num = 0 0
2 num = 50
num = 0 1
3 num = 12
num = 8
num = 0 2
will be calculated as
average = 0 / 0
In the diagram:
To draw a yellow pixel at position (100,80) on the screen we would use the
following statements:
Activity 6.1
Activity 6.2
Modify dots01.dbpro to make sure the random dots occupy the whole screen
no matter what resolution is being used.
integer
In the diagram:
Colours are represented by large integer values (as we saw when using the RGB
statement back in Chapter 2). Therefore, to check if a pixel is a specific colour, say,
red, then we need to use a statement such as:
IF POINT(100,100) = RGB(255,0,0)
PRINT ”The pixel is red"
Alternatively, we might use the colour returned by the POINT statement to set the
foreground (or background) colour with a statement such as:
INK POINT(200,5),0
Modify dots01.dbpro so that once the 10,000 dots are showing on the screen,
the program picks a pixel position at random and displays one of two
messages:
The pixel at {position given here} is black
or
The pixel at {position given here} is not black
In the diagram:
CLS RGB(0,0,255)
The background colour is INK RGB(255,255,0),0
not used when drawing LINE 80,50,300,90
shapes.
Activity 6.5
BOX 100,120,400,180
FIG-6.5 (100,120)
Activity 6.6
The second, longer version of the BOX statement can create a much more colourful
rectangle. This statement takes four additional colour parameters which are used to
fill in the four corners of the rectangle. Away from the corners the colours merge
into each other. The effect is rather psychedelic!
c1 = RGB(255,0,0)
c2 = RGB(0,255,0)
c3 = RGB(0,0,255)
c4 = RGB(255,255,0)
BOX 10,10,100,100,c1,c2,c3,c4
Activity 6.7
Modify your gallows01.dbpro project so that the box is filled with various
colours.
Feel free to experiment with the colours you use.
BOX x1 , y1 , x2 , y2
[ , c1 , c2 , c3 , c4
In the diagram:
Activity 6.8
CIRCLE 100,120,50
In the diagram:
Activity 6.9
Modify your gallows01.dbpro program so that your display now displays the
figure shown below.
ELLIPSE 300,200,120,80
FIG-6.10
The ELLIPSE Statement ELLIPSE x , y , hradius , vradius
Activity 6.10
Using an ellipse and four more lines, complete the “hangman” symbol as
shown below.
Summary
l The DOT x,y statement places a single pixel on the screen at position (x,y) using
the current foreground colour.
l The POINT (x,y) statement returns the colour currently showing at position (x,y)
on the screen.
l Use BOX x1,y1,x2,y2 to draw a filled rectangle with top-left corner at the point
(x1,y1) and bottom-right corner at (x2,y2).
l Use BOX x1,y1, x2, y2,c1,c2,c3,c4 to draw a filled box using colours c1, c2, c3
and c4 which radiate from the four corners of the rectangle.
l Use CIRCLE x,y,r to draw the outline of a circle with centre (x,y) radius r.
l Use ELLIPSE x,y,hr,vr to draw the outline of an ellipse with centre (x,y),
horizontal radius hr and vertical radius vr.
REM *** Set foreground colour, clear screen and draw shape ***
INK foreground,0
CLS
SELECT choiceshape
CASE 1 ‘*** Pixel ***
DOT 300,250
ENDCASE
CASE 2 ‘*** Line ***
LINE 20,50,300,120
ENDCASE
CASE 3 ‘*** Rectangle ***
BOX 20,50,300,150
ENDCASE
CASE 4 ‘*** Circle ***
CIRCLE 300,250,50
ENDCASE
CASE 5 ‘*** Ellipse ***
ELLIPSE 300,250,50,15
ENDCASE
ENDSELECT
Activity 6.11
Modify the program so that, once a shape has been displayed, the user can
select other shapes and colours. To do this add a loop structure to the code and
insert a QUIT option to the shapes menu. The program should terminate when
this quit option is chosen.
If we draw a yellow circle on a black background, we can make that circle disappear
by drawing a black circle in exactly the same place. This technique is demonstrated
in LISTING-6.4 which employs the following logic:
Activity 6.12
Notice that the circle in project disappear.dbpro is not removed until a key is
pressed. However, an alternative approach is to remove the circle automatically
after a given amount of time has passed. We have two statements that can make the
Activity 6.13
Modify your last program by removing the WAIT KEY statement between
displaying and hiding the yellow circle and replacing it with a SLEEP
statement that waits 1 second before making the circle disappear.
y = 250
FOR x = 1 TO 600 DO
Show circle at position (x,y)
Wait 20 milliseconds
Hide circle at position (x,y)
ENDFOR
then we should see the circle travel across the middle of the screen. This logic is
coded in LISTING-6.5.
Activity 6.14
Modify the program so that the circle moves vertically rather than horizontally.
This gives you some idea of how we can give the impression of movement on the
screen. However, we don’t want too spend too much time using this approach to
animation since DarkBASIC Pro has a much better way of doing this type of
operation using sprites which we’ll find out about in a later chapter.
REM *** Set foreground to yellow *** REM *** End program ***
foreground = RGB(255,255,0) WAIT KEY
INK foreground,0 END
Activity 6.14
To increase the speed, the delay should be reduced:
Creating Functions
Global Variables
GOSUB Statement
Local Variables
Mini-Specs
Modular Programming
Parameter Passing
Pre-Conditions
Post-Conditions
Return Values
Why are computers made this way, as a collection of separate pieces rather than
have everything encased in a single frame?
Well, there are several reasons. Firstly, by using separate components each can be
designed to perform just one specific task such as: get information from the user
(keyboard); display information (the screen); store information (the disk) etc. This
allows all of these items to be made and tested separately.
Why is all of this relevant to creating games programs? Years of experience have
shown that the advantages of this modular approach to construction doesn’t just
apply to physical items such as computers, it also applies to software.
Rather than create programs as one continuous set of instructions, we can split the
program into several routines (also known as modules or subroutines), each
routine being designed to perform just one specific function. This is particularly
important in long programs and when several programmers are involved in creating
the software.
In fact, routines in DarkBASIC Pro are often referred to as functions, and that’s the
term we’ll use from here on in.
Functions
Designing a Function
The first stage in creating a function is to decide on what task the function has to
perform. For example, we might want a function to display a set of menu options
(look back at LISTING-6.3 and you’ll see examples of several simple menus).
When a team of people is involved in creating the software, it is important that the
exact purpose of each routine is written out in detail so there can be no
misconceptions between the people designing the routine and those programming
it.
Functions must also be given a name. This name should reflect the purpose of the
function and usually starts with a verb, since functions perform tasks.
FUNCTION ShowShapeMenu()
PRINT “Choose from the following options”
PRINT “1 - Pixel”
PRINT “2 - Line”
PRINT “3 - Box”
PRINT “4 - Circle”
PRINT “5 - Ellipse”
ENDFUNCTION
Notice that the module begins with the keyword FUNCTION and ends with the
keyword ENDFUNCTION.
The first line also contains the name of the function, ShowShapesMenu, and an
empty set of parentheses.
Between the first and last lines go the set of instructions that perform the task the
function has been designed to do.
Calling a Function
When you type in a program’s code, place any functions you have at the end of that
code (see LISTING-7.1).
LISTING-7.1 REM *** Display a message ***
PRINT “Shape drawing program”
Adding a Function
REM *** End program ***
WAIT KEY
END
Activity 7.1
NOTE: The menu will not appear when you run the program.
As you’ve just had demonstrated, functions are totally ignored when you run your
program. You might as well have saved yourself some typing for all the good it did!
It’s only the code before the function, known as the main section, that is executed.
The code within a function is only executed if you make a call to that function.
Calling a function is taken as a request to execute the code within a function, and
ShowShapeMenu()
Activity 7.2
Modify your project to match LISTING-7.2 and check that the menu is
displayed.
Notice that when you ran the program the message Shape drawing program
appeared before the menu options. This is because the PRINT statement appears
before the line
ShowShapeMenu()
1 2
Execution starts in When a call to ShowShapeMenu
the main section is made, control passes to the routine
Main ShowShapeMenu
REM *** Display a message *** REM *** Display shape options ***
3
PRINT “Shape drawing program” FUNCTION ShowShapeMenu ()
The function is then executed
PRINT “Choose from the following options”
REM *** Call function *** PRINT “1 - Pixel”
ShowShapeMenu() PRINT “2 - Line”
PRINT “3 - Box”
REM *** End program *** PRINT “4 - Circle”
WAIT KEY PRINT “5 - Ellipse”
END ENDFUNCTION
4
5 When the function is complete,
The remainder of main control returns to the main section at the
is then executed first command following the function call
Another Example
We’ll leave the shape program for the moment and have a look at another example.
The function in LISTING-7.3 (DrawTextLine()) draws a line of asterisks on the
screen.
Activity 7.4
Activity 7.5
*****
*****
*****
*****
*****
Create a project (testbox.dbpro) which calls up this function and check that the
box is drawn successfully.
You can call a function as often as you want from the main program. All you have
to do is repeat the calling line. Hence, if we change the main program in project
testline.dbpro to
DrawTextLine()
PRINT “ Hello”
DrawTextLine()
the DrawTextLine() function will be called twice and we will see a row of asterisks
both above and below the word Hello.
Modify your testline.dbpro project to draw a line of asterisks both above and
below the word Hello.
Make a second change so that two lines of asterisks appear below Hello.
Parameters
Sometimes we need to supply information to a function. For example, the
DarkBASIC Pro statement DOT is actually a function and, when it is called, we
need to supply it with details of where we want the pixel to be displayed. Each piece
of information that we give to a function is known as a parameter to that function.
We’ll see how parameters work by rewriting the DrawTextLine() so that the number
of asterisks that are to appear in the line can be specified.
FUNCTION DrawTextLine(size)
To make use of this information we’ll have to rewrite the code for our function so
that a single asterisk is output size times. Our new version of the routine is coded
as:
FUNCTION DrawTextLine(size)
FOR c = 1 TO size
PRINT “*”;
NEXT c
PRINT
ENDFUNCTION
Now, if we’re going to call the function, we need to supply a value for size. Hence,
DrawTextLine (25)
FIG-7.2 causes the DrawTextLine() function to be executed and sets the value of size to 25
Passing a Parameter to a
(thereby drawing a line of 25 asterisks). The mechanism involved is shown visually
Function in FIG-7.2.
1 2
Execution starts in When a call to DrawTextLine
the main section is made, control passes to the routine
3
The parameter and local
Main DrawTextLine variables are created
6
When the function is complete,
7
control returns to the main section at the
The remainder of main
first command following the function call
is then executed
Change the main program so that the line above Hello contains 5 asterisks,
while the last two rows contain 15 asterisks.
Activity 7.8
Modify your DrawTextBox() function so that the height of the box is passed as
a parameter (it will remain 5 asterisks wide).
To test the function, read in a value from the keyboard and use this value as
the parameter to your routine.
A function can have as many parameters as you require and these parameters can
be of any type: integer, real or string. To demonstrate this we’ll write yet another
version of the DrawTextLine() function in which the character used to construct the
line is also passed as a parameter.
Notice that parameters are separated from each other by commas. We can tell that
the second parameter is a string by the fact that its name ends with the dollar ($).
We have to supply two values when we call the function; one to be given to size,
the other to char$. A typical call would be
which would assign the value 20 to size and the string “=” to char$ and thereby
produce a line on the screen created from twenty = symbols.
It’s important that you put the values in the correct order when you call up the
function. For example, the line
would be invalid since the function expects the first value given in the parentheses
is the integer to be assigned to the size parameter.
Activity 7.9
Modify your DrawTextBox() function so that the character used can be passed
as a parameter.
Check that it works by drawing a box 10 lines high constructed from the #
character.
When we place limitations on the conditions under which a function can operate
successfully, these limitations are known as the pre-conditions of the function. We
can therefore state that the pre-condition for DrawTextLine() is that size lies between
0 and 80.
Now we need some way of enforcing this limit. We do this by adding an IF statement
at the beginning of the DrawTextLine() function which causes that function to be
aborted if the value of size is outside the acceptable range.
We can make use of this statement to terminate execution of a function when its
parameter(s) fall outside an acceptable range. In the case of DrawTextLine(), we
would add the following statement to check the value of size:
the function will abort since the value assigned to size will be outside the range 0
to 80, and no line will be drawn on the screen.
Check that the function now operates only within the limits set by running the
program using size values of -1, 0, 80 and 81.
Activity 7.11
Assuming the pre-condition for DrawTextBox() is that height should lie within
the range 0 to 24, add the appropriate IF structure to the function and test that
the new code operates correctly.
Activity 7.12
A pre-condition for this routine is that number should lie between 1 and 50.
Get number
Call SumIntegers(number)
Get number
ENDWHILE
Return Types
Not only can we supply values to a function (in the form of parameters), but some
functions also return results. For example, in the Sumlntegers() function that we
designed earlier, we actually limit the usefulness of the routine by displaying the
result rather than returning it. After all, the main program may have wanted to use
the answer in some calculation rather than have it displayed on the screen.
To return a value from a DarkBASIC Pro function we add the value to be returned
immediately after the term ENDFUNCTION. A new version of Sumlntegers() is
shown below:
FUNCTION SumIntegers(number)
total = 0
FOR c = 1 TO number
total = total + c
NEXT c
ENDFUNCTION total
Notice that the pre-condition check has been removed from the function - more
about that later.
PRINT SumIntegers(10)
This line causes the SumIntegers() function to be executed and then displays the
value returned by the function.
We could store the value returned in a variable with a line such as:
ans = SumIntegers(10)
or in an IF statement:
Activity 7.13
If a function returns a string value, then the name of the function must end with a
dollar sign. For example, the function FilledString$(ch$, num) returns a string
containing num copies of ch$:
A function that returns a FUNCTION FilledString$ (ch$, num)
string is often referred to result$ = ""
as a string function. FOR c = 1 TO num
result$ = result$ + ch$
NEXT c
ENDFUNCTION result$
Why was the pre-condition check for SumIntegers() removed? Well, by creating a
return value, we introduced a problem. It is no longer sufficient to write
We can return any value we like, but usually this is handled by returning some
special value which cannot occur when the function’s pre-conditions are met. For
EXITFUNCTION -1
This allows us to add back the pre-condition to our routine, the final version of the
code being:
FUNCTION SumIntegers(number)
IF number < 1 OR number > 50
EXITFUNCTION -1
total = 0
FOR c = 1 TO number
total = total + c
NEXT c
ENDFUNCTION total
Activity 7.14
Modify your Factorial() function from the last Activity so that it implements
the pre-condition that v must lie between 1 and 25.
Better still, the program should make sure the value passed is acceptable before
making a call to Sumlntegers (). We could do this with the code:
We’ve introduced three new function-related statements in this section; the format
of these are given in FIG-7.3, FIG-7.4 and FIG-7.5.
FIG-7.3
The FUNCTION
Statement
In the diagram:
FUNCTION function name (
[ parameter
,
)
In the diagram:
In the diagram:
Local Variables
When you make use of a variable inside a function (other than a parameter), that
variable exists only within that function. If you look at the code for SumIntegers()
you’ll see two variables which are used within the function: c and total. This type
of variable is known as a local variable: it exists only while the function is being
executed. Once the function has been executed, these local variables cease to exist.
We can prove this with a little experiment shown in the code below:
FUNCTION Test()
num = 15
ENDFUNCTION
Function Test() assigns the value 15 to a variable called num. The main program
assigns the value 10 to num, executes Test() and then displays the value in num.
What value do you think appears on the screen?
Activity 7.15
Type in the code given above (local.dbpro) and check out what value is
displayed on the screen.
There are in fact two variables called num. One of these exists only within Test()
and, although it is assigned the value 15, that variable ceases to exist when Test()
has been completed. When execution returns from the function back to the main
program, we have come back to the part of the program where the other variable
called num exists - and that variable still contains the value 10 as assigned to it.
The program doesn’t have a problem with there being two variables of the same
There is no way to access the main program’s variable called num from within Test()
and there is no way to access Test()‘s num from within the main program (although
you could access it’s value by returning num at the end of the function).
Global Variables
It is possible to make a variable available anywhere in a program by using the term
GLOBAL when the variable is created. So, if we change the previous example to
now read
FUNCTION Test()
num = 15
ENDFUNCTION
GLOBAL num = 10
num = 15
PRINT num
Activity 7.16
Add the word GLOBAL to the appropriate line in your local.dbpro program
and find out what difference this makes to the value displayed.
NAME : SumIntegers
PARAMETERS
IN : num : integer
OUT : result : integer
PRE-CONDITION : 1 <= num <= 50
DESCRIPTION : The routine sets result to the sum of all integer values
between 1 and num.
OUTLINE LOGIC : Set result to zero
FOR c = 1 TO num DO
Add c to result
ENDFOR
The Description explains in English what the routine should do, while the Outline
Logic describes in structured English how the task should be done.
Specifying a Post-Condition
Some mini-specs make use of a post-condition statement which specifies what
should be true when the routine has been successfully executed. For example, the
pre-condition for SumIntegers would be:
Often a post-condition will be very similar to the description. When used, the
post-condition statement follows immediately after the pre-condition statement.
NAME : DrawTextLine
PARAMETERS
IN : None
OUT : None
NAME : DrawTextLine
PARAMETERS
IN : size : integer
ch : character
OUT : None
PRE-CONDITION : 0<=size<=80
DESCRIPTION : The routine draws a horizontal line constructed
from size occurrences of ch.
OUTLINE LOGIC : FOR c = 1 TO size DO
ENDFOR
In the last example, notice that the second parameter does not contain a dollar sign
as part of its name and that its type is declared as character, not string. This is
because a design should be independent of the programming language that you
finally use to implement that design. DarkBASIC Pro-specific requirements, such
as ending string variable names with a dollar symbol, or reals with the hash
character, having string functions end their name with a dollar sign, or using only
integer, real and string types, should be avoided in your designs.
So, just what are you allowed to use in a design? Names (functions and variables)
should conform to the following rules:
Ø integer
Ø real
Ø string
Ø character (a single character)
Ø Boolean (a variable that is set to true or false)
Even the main section of the program should be designed in the form of a mini-spec.
For example, in order to test the DrawTextLine() function, we could create a main
program which implements the following specification:
NAME : Main
PARAMETERS
IN : None
OUT : None
PRE-CONDITION : None
DESCRIPTION : The routine is designed to test DrawTextLine(). It
allows the length and character making up the line
Get size
Get character
LISTING-7.4 REPEAT
INPUT “Enter size of line (-99 to end) : ”, size
Displaying the Menu INPUT “Enter character used in line creation : ”, ch$
DrawTextLine(size,ch$)
UNTIL size = -99
END
Activity 7.17
NAME : Smallest
PARAMETERS
IN : no1 : integer
no2 : integer
no3 : integer
OUT : result : integer
PRE-CONDITION : None
DESCRIPTION : The routine sets result equal to the the smallest
of the values no1, no2, and no3.
IF all three values are the same, that value
should be returned in result.
OUTLINE LOGIC : IF no1 < no2 AND no1 < no3 THEN
result := no1
ELSE
result := no2
ELSE
result := no3
ENDIF
ENDIF
Since the code is already divided into obvious sections, each doing a specific job,
it’s quite easy to see what functions are required. The mini-spec for each identified
routine is shown below.
NAME : Main
PARAMETERS
IN : None
OUT : None
PRE-CONDITION : None
DESCRIPTION : The program displays a selected shape in a specified
colour. The user selects which shape is required.
(pixel, line, rectangle, circle or ellipse) and the colour
to be used (red, green, blue, yellow, cyan or magenta).
OUTLINE LOGIC : Display shapes menu
NAME : ShowShapeMenu
PARAMETERS
IN : None
OUT : None
PRE-CONDITION : None
DESCRIPTION : The routine displays the option available to the user
when choosing a shape to be displayed.
The display should show the following options:
1 - Pixel; 2 - Line; 3 - Box; 4 - Circle; 5 - Ellipse
OUTLINE LOGIC : Display 1 - Pixel
Display 2 - Line
Display 3 - Box
Display 4 - Circle
Display 5 - Ellipse
Get choice
Get choice
ENDWHILE
Notice that the above specification is flexible enough to be used to get the user’s
choice of both shape and colour.
NAME : ShowColourMenu
PARAMETERS
IN : None
OUT : None
PRE-CONDITION : None
DESCRIPTION : The routine displays the option available to the user
when choosing the colour of the shape.
The display should show the following options:
1 - Red; 2 - Green; 3 - Blue; 4 - Yellow; 5 - Cyan;
6 - Magenta.
OUTLINE LOGIC : Display 1 - Red
Display 2 - Green
Display 3 - Blue
Display 4 - Yellow
Display 5 - Cyan"
Display 6 - Magenta
NAME : SetInkColour
PARAMETERS
IN : choice : integer
OUT : result : integer (colour value)
PRE-CONDITION : 1 <= choice <= 6
DESCRIPTION : The routine sets result to a colour value based on
choice. Settings are as follows:
choice colour
1 red
2 green
3 blue
ENDIF
NAME : DisplayChosenShape
PARAMETERS
IN : choice : integer
colour : integer
OUT : None
PRE-CONDITION : 1 <= choice <= 5
DESCRIPTION : The routine displays the shape chosen by the user.
The screen is cleared and the foreground colour set
to colour.
If choice is 1, a pixel is drawn at (300,250)
If choice is 2, a line is drawn from (20,50) to
(300,120)
If choice is 3, a rectangle is drawn with top-left at
(20,50) and bottom-right at (300,150)
If choice is 4, a circle is drawn with its centre at
(300,250). Its radius is 50.
If choice is 5, an ellipse is drawn. Its centre is at
(300,250). The horizontal radius is 50; the vertical
radius, 15.
OUTLINE LOGIC : Set foreground colour to colour
IF
(300,120)
centred at (300,250)
ENDIF
There are various ways to tackle this. If we had several people working on the
program, we could give each a separate routine to work on at the same time. It would
then just be a matter of bringing together the separate routines to give us the final
program.
On the other hand, if only one person is working on the coding, the routines are
Top-Down Programming
When we code our routines one at a time, starting with Main, this is known as
top-down programming. The name is used because we start with the main part of
the program (the top) and then work our way through the routines called by that
main part. We’ll see how it’s done below.
Step 1
We start by turning the outline logic given in the mini-spec for Main into
DarkBASIC Pro program code. An important point to note is that the program code
must match that logic in the mini-spec exactly. If we find we have to deviate from
this logic then we must go back and modify the details given in that mini-spec.
Actually, the code for Main becomes little more than a set of calls to the other
routines:
Notice that Main really doesn’t do any of the detailed work, it leaves that to the
routines. Main only has to call up each of the routines in the correct order and save
any values returned by one function to pass it on to another function. For example,
it saves the user’s choice of shape (in shapeoption) from GetUserOption() and then
passes that value on to DisplayChosenShape().
In order to write Main you need to know the names and purposes of the other
routines as well as what parameters are passed and what values are returned from
those routines. We should test our program, even at this early stage in its
development, to ensure that the routines are executed in the correct order and that
the proper parameters are passed between the routines. But there’s a problem. The
program can’t run without the routines that Main is attempting to call. The compiler
will simply complain about calls to non-existent routines.
Activity 7.19
Step 2
To get Main to run we must write code for the routines that are called. And yet, if
we do that, it would appear that the whole program will need to be completed before
the program can be executed for the first time.
The way round this problem is to write empty routines with the required names,
parameters and return values as shown below.
Activity 7.20
Step 3
Now we can begin to remove the stubs in our project and replace them with the final
version of each routine, always testing as each new routine is added to make sure
the new routine, and the program as a whole, are working correctly.
Activity 7.21
Replace the stub for this routine with its full code.
Run the program again and check that the appropriate menu is displayed on
the screen.
Add the code for GetUserOption() and check that it operates correctly.
Activity 7.23
Enter the code for each of the remaining routines, checking that the program
operates correctly at each stage.
Bottom-Up Programming
If you’re working as part of a team of programmers, then you’re likely to get landed
with having to code a specific routine which, when completed, will be handed over
to the team leader. He will then add your routine to the main program.
So let’s assume we’ve just been landed with the job of writing the GetUserOption()
function. How do we go about doing this job? Well, it’s just a matter of getting hold
of the mini-spec for the routine and turning it into a coded function. In the case of
GetUserOption() we should end up with the following code:
FUNCTION GetUserOption(max)
INPUT “Enter option : ”, choice
WHILE choice < 1 OR choice > max
PRINT “That was an invalid choice. 1 to ”,max," only."
INPUT “Enter option : ”, choice
ENDWHILE
ENDFUNCTION choice
Although we might be tempted to think our job is done at this point, we really need
to check that our routine is operating correctly. It won’t do your reputation as a
programmer any good if you hand over code which contains obvious faults.
To test a routine, we start by making sure that what we’ve written conforms to the
requirements of the mini-spec. Once we’re happy with that, then the code itself must
be tested. Since a function only executes when called by another piece of code, we
need to write a main program which will call up the function we want to test. This
main program, known as a test driver, needs to perform four main tasks:
DO
REM *** Get a value for parameter ***
INPUT “Enter a value for max : ”,max
REM *** IF -1 entered, exit loop ***
IF max = -1
EXIT
ENDIF
REM *** Call function being tested ***
returnedvalue = GetUserOption(max)
REM *** Display function parameters ***
PRINT “max = ”,max
Notice that the main code is in a loop so that several tests can be carried out in a
single run.
Activity 7.24
Run the program and check that GetUserOption() is returning the expected
results.
Structure Diagrams
As we begin to develop more complex programs containing several routines, it can
be useful to retain an overview of the program’s structure, showing which routine
is called by which, and the values that pass between them. This is done with a
structure diagram.
FIG-7.7 A structure diagram contains one rectangle for each routine in a program, including
a rectangle representing Main. These rectangles contain the name of the routine they
A Graphical represent. The collection of rectangles for the shapes2.dbpro project is shown in
Representation of the FIG-7.7.
Routines in the System
Only Main has been renamed, with a new title to reflect the overall purpose of the
system.
The rectangles are now set in a series of levels, with Shapes System (the renamed
Main) at the top. On the second level are routines called by Shapes System. On the
third level are any routines called by second level routines. In addition, lines are
drawn between the rectangles to reflect which routine calls which (see FIG-7.8).
FIG-7.8
Shapes System
The Calling
Hierarchy of the
Routines
SetInkColour
Another point to note is that GetUserOption has been included twice. This is
because that routine is used to get two different items of data: on its first call it
returns the choice of shape, on the second call, the choice of colour.
Finally, we add any parameters passed between the routines (see FIG-7.9).
FIG-7.9
Shapes System
The Complete
Structure Diagram choice
Showing Parameters colour
max
max
choice colour
colour
SetInkColour
The circle with arrowed line symbol in the diagram is used to show the direction in
which data is passed, with IN values pointing towards a routine and OUT parameters
pointing away from the routine.
Summary
l Good programming technique requires program code to be partitioned into
routines.
l A mini-spec should include the name of the routine, its parameters, restrictions
of the range of values a parameter may take, a detailed description of the routine’s
purpose, and an outline logic specifying how the routine is to operate.
l A mini-spec may contain a post-condition which states what should be true once
the routine has been successfully executed.
l The term GLOBAL can be used to create a variable which can be accessed
anywhere within a program.
l Bottom-up programming uses test drivers to check that completed routines are
operating correctly.
l A structure diagram shows every routine in a program, how they are called, and
the values that pass between them.
Creating a Subroutine
The fact that we are going to use DarkBASIC Pro subroutines rather than functions
makes no difference to the design stage of a project - we still need to create
mini-specs identical to those shown earlier. But when we come to implement these
designs in DarkBASIC Pro, we will use subroutines instead of functions.
The start of a subroutine is marked with a label giving the name of the subroutine.
This will be the name given in the mini-spec.
ShowShapeMenu:
ShowShapeMenu:
PRINT “Choose from the following shapes”^
PRINT “1 - Pixel ”
PRINT “2 - Line”
PRINT “3 - Box”
PRINT “4 - Circle”
PRINT “5 - Ellipse”
ShowShapeMenu:
PRINT “Choose from the following shapes”^
PRINT “1 - Pixel ”
PRINT “2 - Line”
PRINT “3 - Box”
PRINT “4 - Circle”
PRINT “5 - Ellipse”
RETURN
FIG-7.10
label :
The Subroutine Construct
instruction
RETURN
In the diagram:
GOSUB ShowShapesMenu
When the execution reaches the RETURN statement, the program jumps back from
the subroutine and continues by executing the line following the call to the
subroutine.
Activity 7.25
Run the program and check that the subroutine is correctly executed.
Subroutines are quite restricting since they cannot accept parameters nor return a
value.
This means that a routine such as GetUserChoice which has both an IN parameter
and a return value (OUT parameter) cannot be coded efficiently using a subroutine.
Variables in a Subroutine
Also, it is not possible to create local variables within a subroutine. When variables
of the same name are used in both the main program and a subroutine, these are
assumed be one and the same variable.
Execute the program and check out what value is displayed on the screen.
As a general rule, it is best to avoid the use of DarkBASIC Pro's subroutines and
stick with functions since they offer a much greater flexibility.
Summary
l Subroutines are a group of instructions which begin with a label and end with
the term RETURN.
Activity 7.6
Line above and below text:
Activity 7.9
REM *** Get values from user ***
REM *** Execute function *** INPUT “Enter number : ”, num
DrawTextLine() INPUT “Enter character : ”, c$
REM *** Display a message *** REM *** Call function; use values input ***
PRINT “ Hello” DrawTextBox(num,c$)
REM *** Execute function again *** REM *** End program ***
DrawTextLine() WAIT KEY
REM *** End program *** END
WAIT KEY REM *** Draw box of characters ***
END FUNCTION DrawTextBox(height,ch$)
FOR c = 1 TO height
REM *** Draw a line of asterisks *** FOR k = 1 TO 5
FUNCTION DrawTextLine() PRINT ch$;
PRINT “************************” NEXT k
ENDFUNCTION PRINT
NEXT c
Line above and two lines below text: ENDFUNCTION
The ShowShapeMenu() function now displays the list of REM *** Change to selected colour ***
user options on the screen. FUNCTION SetInkColour(choice)
SELECT choice
CASE 1
Activity 7.22 result = RGB (255,0,0)
ENDCASE
No solution required. CASE 2
result = RGB (0,255,0)
ENDCASE
Activity 7.23 CASE 3
result = RGB (0,0,255)
The complete solution is given below: ENDCASE
CASE 4
REM *** Main program *** result = RGB (255,255,0)
ShowShapeMenu() ENDCASE
shapeoption = GetUserOption(5) CASE 5
ShowColourMenu() result = RGB (0,255,255)
colouroption = GetUserOption(6) ENDCASE
DisplayChosenShape(shapeoption,colouroption) CASE 6
REM *** End program *** result = RGB (255, 0,255)
WAIT KEY ENDCASE
END ENDSELECT
ENDFUNCTION result
REM *** Display menu of possible shapes ***
FUNCTION ShowShapeMenu()
PRINT “Choose from the following shapes” Activity 7.24
PRINT “1 - Pixel ”
PRINT “2 - Line” REM *** Test driver ***
PRINT “3 - Box” DO
PRINT “4 - Circle” REM *** Get a value for parameter ***
PRINT “5 - Ellipse” INPUT “Enter a value for max : ”,max
ENDFUNCTION IF max = -1
FUNCTION GetUserOption(max)
INPUT “Enter option : ” ,choice
WHILE choice < 1 OR choice > max
PRINT “That was an invalid choice. 1 to ”,
max," only"
INPUT “Enter option : ”,choice
ENDWHILE
ENDFUNCTION choice
Activity 7.25
No solution required.
Activity 7.26
The value 15 is displayed. This is because the num referred to in the
main program and num in the subroutine are the same variable.
Because a string can contain so many characters, there are several operations that
programmers find themselves needing to do with strings. For example, we might
want to find out how many characters are in the string, convert a string to uppercase,
or extract part of a string.
DarkBASIC Pro contains many statements to help us perform some of these tasks,
as we shall see in the following pages.
String Operations
The LEN Statement
The LEN statement is a function which returns the number of characters in a string.
The string to be examined is given in parentheses. For example, the expression
LEN(“Hello”)
would return the value 5 since there are 5 characters in the word Hello.
integer
In the diagram:
As with any function that returns a value, this value can be displayed, assigned to
a variable, or used in an expression. Hence each of the following lines are valid:
Of course, it’s much more likely that you’ll use a string variable as an argument
rather than a string constant. For example, the code
Activity 8.1
Create a project (stringlength.dbpro) containing the two lines given above and
test out the program.
Activity 8.2
Any characters in the string that are not letters are returned unchanged by this
statement. Hence,
PRINT UPPER$(“abc123")
As in all of these statements in this section, the argument can be a string constant,
variable or expression. The value returned by the function can be stored in a string
variable.
Activity 8.3
What value would be stored in b$ after the following statements are executed?
a$ = “1-by-1"
b$ = UPPER$(a$)
string
In the diagram:
string
In the diagram:
would display ab on the screen, LEFT$ having returned the left two characters from
the string abcdef.
If the number given is larger than the number of characters in the string as in
ans$ = LEFT$(“abcdef”,10)
result$ = LEFT$(“abcdef”,0)
then the returned string contains no characters. That is, result$ will hold an empty
string.
FIG-8.4
LEFT$ ( string , value )
The LEFT$ Statement
string
PRINT RIGHT$(“abcdef”,2)
FIG-8.5
The RIGHT$ Statement RIGHT$ ( string , value )
string
In the diagram: