String Manipulation in Smart Pascal

Introduction

Although your games are likely to consist in the main of images and shapes, you might need to manipulate strings for tasks such as these:
• display of the instructions and stats;
• transfer of game data to and from local storage;
• handling colours;
• handling keyboard input from the player;
• constructing shader programs for 3D graphics.
You will have seen how the frame rate is displayed in the canvas project template with the code:
`Canvas.FillTextF('FPS:' + IntToStr(GameView.FrameRate), 10, 20, MAX_INT);`
This demonstrates the widely used IntToStr function for converting an integer to a string and the joining together (concatenation) of strings with the + operator.

Even although keyboard input in Smart Pascal uses JavaScript key codes, the usual Pascal functions ord and chr still exist to convert from character to ASCII code and from ASCII code to character, respectively. Remember that a character in Smart Pascal is a single-character string.

You may access a single character in a string by considering it to be composed of an array of single-character strings. Following the declaration var str := 'qwerty';, str[3] evaluates to 'e'.

Commonly Used Inbuilt Functions

Commonly used functions are described in the following table, taken from the corresponding page of the main String Manipulation tutorial. In the table, Str, Str1 and Str2 are strings and n and m are positive integers. The first character is numbered 1 in Pascal. Thus, the position of ‘g’ in the string ‘program’ is 4.

Function Result
Pos(Str1, Str2) Returns the start position of Str1 in Str2. Returns 0 if Str1 is not in Str2
LeftStr(Str, n) Returns the first n characters of Str as a string
MidStr(Str, m, n) Returns, as a string, the next n characters of Str, starting at the mth character
RightStr(Str, n) Returns the last n characters of Str
Length(Str) Returns the number of characters in Str

Demonstration

In this demonstration of the preparation for a game, we obtain the player's name using the inbuilt w3_prompt function. The player is greeted personally for a fixed number of frames before the game begins, during which time we could load images. Procedure ApplicationStarting demonstrates the pos, length, leftStr and rightStr functions.

We developed this example with Version 2.2 of Smart Mobile Studio. Change the line Canvas.Font := '10pt verdana'; to Canvas.FontStyle := '10pt verdana'; when using Version 3.0.

```unit Unit1;

interface

uses
System.Types, SmartCL.System, SmartCL.Components, SmartCL.Application,
SmartCL.Game, SmartCL.GameApp, SmartCL.Graphics, SmartCL.Controls.Button;

type
TCanvasProject = class(TW3CustomGameApplication)
private
forename, surname, full_name: string;
frame_num: integer;
protected
procedure ApplicationStarting; override;
procedure ApplicationClosing; override;
procedure PaintView(Canvas: TW3Canvas); override;
procedure Greeting(Canvas: TW3Canvas);
end;

implementation

procedure TCanvasProject.ApplicationStarting;
begin
inherited;
GameView.Delay := 20;
full_name := w3_prompt('Please enter your forename then surname separated by a space');
var space_pos := pos(' ', full_name);
forename := leftStr(full_name, space_pos - 1);
surname := rightStr(full_name, length(full_name) - space_pos);
GameView.StartSession(False);
end;

procedure TCanvasProject.ApplicationClosing;
begin
GameView.EndSession;
inherited;
end;

procedure TCanvasProject.Greeting(Canvas: TW3Canvas);
begin
Canvas.Font := '10pt verdana';
Canvas.FillStyle := 'rgb(255, 255, 255)';
Canvas.FillText('Hello, ' + forename + '!', 10, 20);
Canvas.FillText('Enjoy the game!', 10, 40);
Canvas.FillText('See if you can top our leader board ...', 10, 60);
Canvas.FillText('or at least be the best ' + surname + '.', 10, 80);
end;

procedure TCanvasProject.PaintView(Canvas: TW3Canvas);
begin
inc(frame_num);
//Clear background
Canvas.FillStyle := 'rgb(0, 0, 99)';
Canvas.FillRectF(0, 0, GameView.Width, GameView.Height);
if frame_num < 5000 div GameView.Delay then
Greeting(Canvas);
end;

end.```

Other Routines

From the page of internal string functions for DWScript you can see the existence of many string routines such as floatToStr, strToFloat, delete, insert, lowerCase, upperCase, posEx, revPos, trim, trimLeft, trimRight, compareText, compareStr, dupeString, strAfter and strBefore. This section of code demonstrates the syntax for the use of some of these:

```  var assessment := 'Your score is good.';
insert('quite ', assessment,  15);
ShowMessage(assessment);
delete(assessment, 15, 6);
ShowMessage(assessment);
ShowMessage(upperCase(assessment));
var firstWord := strBefore(assessment, ' ');
ShowMessage('First word: ' + firstWord);
var spacePos1 := pos(' ', assessment);
var spacePos2 := posEx(' ', assessment, spacePos1 + 1);
var secondWord := midStr(assessment, spacePos1 + 1, spacePos2 - SpacePos1 - 1);
ShowMessage('Second word: ' + secondWord);
assessment := format('Your score of %d is %s.', [90, 'excellent']);
ShowMessage(assessment);
var strCaps := 'JOE';
var strLowerCase := 'joe';
if compareText(strCaps, strLowerCase) = 0 then ShowMessage('JOE and joe same by compareText') else
ShowMessage('JOE and joe different by compareText');
if compareStr(strCaps, strLowerCase) = 0 then ShowMessage('JOE and joe same by compareStr') else
ShowMessage('JOE and joe different by compareStr');

```