SRL Archive - SRL Suggestions

A Load Of Functions


Rich

2010-04-15 17:01:01

Well I've compiled some of the functions I made which never really got noticed, so I want to give them a second chance at living. Here they are:

{*******************************************************************************
function PercentProc(Proc : procedure; Percent : Integer) : Boolean;
By: R1ch
Description: Has a Percent/100 chance of calling a procedure (Proc)
Example: PercentProc(@Write, 60);
*******************************************************************************}
function PercentProc(Proc : procedure; Percent : Integer) : Boolean;
begin
if not InRange(Percent, 1, 99) then
begin
srl_Warn('PercentProc', 'Percent should be within 1 and 99 ', warn_AllVersions);
Exit;
end;
Result:= Random(100) <= Percent;
if Result then
Proc();
end;

{*******************************************************************************
function PercentBool(Func : function : Boolean; Percent : Integer) : Boolean;
By: R1ch
Description: Has a Percent/100 chance of calling a Boolean Function (Func)
*******************************************************************************}
function PercentBool(Func : function : Boolean; Percent : Integer) : Boolean;
begin
if not InRange(Percent, 1, 99) then
begin
srl_Warn('PercentBool', 'Percent should be within 1 and 99 ', warn_AllVersions);
Exit;
end;
Result:= Random(100) <= Percent;
if Result then
Func();
end;

{*******************************************************************************
function PercentStr(Func : function : String; Percent : Integer) : Boolean;
By: R1ch
Description: Has a Percent/100 chance of calling a String Function (Func)
*******************************************************************************}
function PercentStr(Func : function : String; Percent : Integer) : Boolean;
begin
if not InRange(Percent, 1, 99) then
begin
srl_Warn('PercentStr', 'Percent should be within 1 and 99 ', warn_AllVersions);
Exit;
end;
Result:= Random(100) <= Percent;
if Result then
Func();
end;

{*******************************************************************************
function PercentInt(Func : function : Integer; Percent : Integer) : Boolean;
By: R1ch
Description: Has a Percent/100 chance of calling an Integer Function (Func)
*******************************************************************************}
function PercentInt(Func : function : Integer; Percent : Integer) : Boolean;
begin
if not InRange(Percent, 1, 99) then
begin
srl_Warn('PercentInt', 'Percent should be within 1 and 99 ', warn_AllVersions);
Exit;
end;
Result:= Random(100) <= Percent;
if Result then
Func();
end;

{*******************************************************************************
function PercentStrEx(Func : function : string; Percent : Integer) : string;
By: R1ch
Description: Has a Percent/100 chance of calling a String Function (Func), and
Result is Result of Func.
*******************************************************************************}
function PercentStrEx(Func : function : string; Percent : Integer) : string;
begin
if not InRange(Percent, 1, 99) then
begin
srl_Warn('PercentStr', 'Percent should be within 1 and 99 ', warn_AllVersions);
Exit;
end;
if Random(100) <= Percent then
Result:= Func();
end;

{*******************************************************************************
function PercentIntEx(Func : function : Integer; Percent : Integer) : Integer;
By: R1ch
Description: Has a Percent/100 chance of calling a Integer Function (Func), and
Result is Result of Func.
*******************************************************************************}
function PercentIntEx(Func : function : Integer; Percent : Integer) : Integer;
begin
if not InRange(Percent, 1, 99) then
begin
srl_Warn('PercentStr', 'Percent should be within 1 and 99 ', warn_AllVersions);
Exit;
end;
if Random(100) <= Percent then
Result:= Func();
end;

{*******************************************************************************
function PercentBoolEx(Func : function : Boolean; Percent : Integer) : Boolean;
By: R1ch
Description: Has a Percent/100 chance of calling a Boolean Function (Func), and
Result is Result of Func.
*******************************************************************************}
function PercentBoolEx(Func : function : Boolean; Percent : Integer) : Boolean;
begin
if not InRange(Percent, 1, 99) then
begin
srl_Warn('PercentStr', 'Percent should be within 1 and 99 ', warn_AllVersions);
Exit;
end;
if Random(100) <= Percent then
Result:= Func();
end;

{*******************************************************************************
procedure function PercentChance(Percent : Integer) : Boolean;
By: R1ch
Description: Has a Percent/100 chance of returning True
*******************************************************************************}
function PercentChance(Percent : Integer) : Boolean;
begin
Result:= Random(100) <= Percent;
end;

{*******************************************************************************
procedure MakeNorth;
By: R1ch
Description: Makes the compass North, with a 70% chance of ClickNorth, else MakeCompass
*******************************************************************************}
procedure MakeNorth;
begin
if not PercentProc(@ClickNorth, 75) then
MakeCompass('N');
end;
//If PercentProc doesn't get committed, then this MakeNorth:
procedure MakeNorth;
begin
if Random(4) = 1 then
MakeCompass('N')
else
ClickNorth
end;

{*******************************************************************************
procedure TypeMistakesExPC(Text : string; PressEnter : Boolean; PC_Chance : Integer);
By: R1ch
Description: Types Text with mistakes, then fixes them. Presses enter depending
on PressEnter. PC_Chance = % of making a mistake.
*******************************************************************************}
procedure TypeMistakesExPC(Text : string; PressEnter : Boolean; PC_Chance : Integer);
var
I, Q : Integer;
L : TStringArray;

begin
L:= ['q','r','t','y','u','i','o','p','a','s','d','f','g','h','j','k','l','z','x','c','v','b','n','m','1','2','3','4','5','6','7','8','9','0','[',']',';','#',',','.','/','\'];
I:= Length(Text);
for I:= 1 to (High(Text) - 1) do
begin
case Random(100) of
PC_Chance..100 : TypeSendEx(Text[i], False);
0..(PC_Chance-1) : begin
Q:= Random(High(L));
if (L[Q] <> Text[i]) then
begin
TypeSendEx(L[Q], False);
Wait(250 + Random(1000));
TypeByte(VK_BACK);
Wait(RandomRange(250, 850));
end;
TypeSendEx(Text[i], False);
end;
end;
end;
TypeSendEx(Text[i], PressEnter);
end;

{*******************************************************************************
procedure TypeMistakesEx(Text : string; PressEnter : Boolean);
By: R1ch
Description: Types Text with mistakes and fixes them.
Presses enter depending on PressEnter
*******************************************************************************}
procedure TypeMistakesEx(Text : string; PressEnter : Boolean);
begin
TypeMistakesExPC(Text, PressEnter, RandomRange(4, 16));
end;

{*******************************************************************************
procedure TypeMistakesPC(Text : string; Chance : Integer);
By: R1ch
Description: Types Text with mistakes and fixes them. Presses enter.
Chance = % of making a mistake.
*******************************************************************************}
procedure TypeMistakesPC(Text : string; Chance : Integer);
begin
TypeMistakesExPC(Text, True, Chance);
end;

{*******************************************************************************
procedure TypeMistakes(Text : string);
By: R1ch
Description: Types Text with mistakes and fixes them. Presses enter.
*******************************************************************************}
procedure TypeMistakes(Text : string);
begin
TypeMistakesEx(Text, True);
end;

Thanks,
Richard

Timer

2010-04-15 17:03:24

Looks sexy.
Something I noticed..
procedure TypeMistakesExPC(Text : string; PressEnter : Boolean; PC_Chance : Integer);
var
I, Q : Integer;
L : TStringArray;

begin
L:= ['q','r','t','y','u','i','o','p','a','s','d','f','g','h','j','k','l','z','x','c','v','b','n','m','1','2','3','4','5','6','7','8','9','0','[',']',';','#',',','.','/','\'];
I:= Length(Text);
for I:= 1 to (High(Text) - 1) do
begin
case Random(100) of
PC_Chance..100 : TypeSendEx(Text[i], False);
0..(PC_Chance-1) : begin
Q:= Random(High(L));
if (L[Q] <> Text[i]) then
begin
TypeSendEx(L[Q], False);
Wait(250 + Random(1000));
TypeByte(VK_BACK);
Wait(RandomRange(250, 850));
end;
TypeSendEx(Text[i], False);
end;
end;
end;
TypeSendEx(Text[i], PressEnter);
end;
{
Q:= Random(High(L));
should be
Q:= Random(Length(L));

I suggest, although, change
I:= Length(Text);
to
I:= Length(Text);
II := Length(L);
then
Q:= Random(High(L));/Q:= Random(Length(L));
to
Q:= Random(LL);

sooo..
This!
}

procedure TypeMistakesExPC(Text: string; PressEnter: Boolean; PC_Chance: Integer);
var
I, II, Q: Integer;
L: TStringArray;
begin
L := ['q', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'a', 's', 'd', 'f', 'g', 'h',
'j', 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n', 'm', '1', '2', '3', '4',
'5', '6', '7', '8', '9', '0', '[', ']', ';', '#', ', ', '.', '/', '\'];

I := Length(Text);
II := Length(L);
for I := 1 to (High(Text) - 1) do
begin
case Random(100) of
PC_Chance..100: TypeSendEx(Text[i], False);
0..(PC_Chance-1):
begin
Q:= Random(LL);
if (L[Q] <> Text[i]) then
begin
TypeSendEx(L[Q], False);
Wait(250 + Random(1000));
TypeByte(VK_BACK);
Wait(RandomRange(250, 850));
end;
TypeSendEx(Text[i], False);
end;
end;
end;
TypeSendEx(Text[i], PressEnter);
end;

Bionicle

2010-04-15 17:06:36

Glad to see your back :)
I think the percentage's are overkill, because it isn't that hard to do
If Not InRange(Random(100), 0, 25) Then
Exit;
at the beginning of the procedure/function. (this is a 1/4 chance, easily edited)

Nava2

2010-04-15 17:08:29

Hmm, I like the ideas, but I would have to say they might be better placed directly into the program then exported into PS. (The percent stuff)

I like the type mistakes though!

Naum

2010-04-15 17:28:19

From: Nava2
Hmm, I like the ideas, but I would have to say they might be better placed directly into the program then exported into PS. (The percent stuff)

I like the type mistakes though!


I agree. Also, the type mistakes thing is in SRL Text.scar, no?
Found it, made by dearest Zeph (<3)

{*******************************************************************************
function AddMistakes(Orig: string; Chance: Integer): string;
By: ZephyrsFury
Description: Adds human mistakes to Orig such as mistypes, missing letters,
wrong cases. Probability that a character is typed wrong is 1 / Chance. ie.
Higher 'Chance' = less mistakes (I know thats stupid but oh well...).
Probability is the chance that an individual character is typed incorrectly.
That is if you have more characters in a string you will get more mistakes overall.
20 - 30 is usually good but it varies depending on your string so experiment!
Use: TypeSend(AddMistakes('Hello', 20));
*******************************************************************************}

Rich

2010-04-15 17:41:53

From: Naum
I agree. Also, the type mistakes thing is in SRL Text.scar, no?
Found it, made by dearest Zeph (<3)

{*******************************************************************************
function AddMistakes(Orig: string; Chance: Integer): string;
By: ZephyrsFury
Description: Adds human mistakes to Orig such as mistypes, missing letters,
wrong cases. Probability that a character is typed wrong is 1 / Chance. ie.
Higher 'Chance' = less mistakes (I know thats stupid but oh well...).
Probability is the chance that an individual character is typed incorrectly.
That is if you have more characters in a string you will get more mistakes overall.
20 - 30 is usually good but it varies depending on your string so experiment!
Use: TypeSend(AddMistakes('Hello', 20));
*******************************************************************************}


But mine is shmexy :p Also, with Zephy's you need to call the AddMistakes inside TypeSend, but not in mine. Mine also has four variations…As if that matters.

What about MakeNorth?

PS: Bionicle, nice to be back!

Nava2

2010-04-15 20:25:14

Naum, his corrects mistakes.

Zeph's just makes them.

trecool999

2010-04-15 20:45:23

From: bionicle1800
Glad to see your back :)
I think the percentage's are overkill, because it isn't that hard to do
If Not InRange(Random(100), 0, 25) Then
Exit;
at the beginning of the procedure/function. (this is a 1/4 chance, easily edited)



if(Random(1) = 1) then
{50% chance of this happening}
Surely? Unless Random() excludes 0, in which case you would replace Random(1) with Random(2).

Sir R. M8gic1an

2010-04-15 21:44:08

if RBoolEx(30) then Result := Function;

so no to the percent functions. They can be done in one line.

Mistakes that get corrected sounds cool, I'd consider adding it to the include.

MakeNorth is more of an antiban-ish thing which doesn't really fit in antiban… I guess it could go. 50/50 on it.

~RM

Tim0suprem0

2010-04-15 23:37:51

The type mistakes thing is sweet, but does Jagex see what we type before we hit enter?

i luffs yeww

2010-04-15 23:56:07

They said they can, and sometimes do. It was in a thread once, but he said he didn't want to say when/why/how much. Could be an troll.

Sex

2010-04-16 00:08:34

From: trecool999
Code:
[LEFT]if(Random(1) = 1) then
{50% chance of this happening}
[/LEFT]

Surely? Unless Random() excludes 0, in which case you would replace Random(1) with Random(2).

Random(1) always returns 0. 0% chance of it happening ;).
However,
if Boolean(Random(2)) then
writeln('wat');
50% chance of it action happening.

marpis

2010-04-16 01:19:50

From: Nava2
Naum, his corrects mistakes.

Zeph's just makes them.


So obvisouly R1ch's is way better! :spongebob:

Sir R. M8gic1an

2010-04-16 04:36:02

From: marpis
So obvisouly R1ch's is way better! :spongebob:


Not necessarily… Zeph's makes the legit players believe a person made a typo. = human

~RM

Rich

2010-04-16 05:24:10

But when I type mistakes, I usually correct them. Since some people do and some people don't, this could be used:

{*******************************************************************************
RandMistakesExPc(Text : string; PressEnter : Boolean; MisChance, FixChance, AMChance : Integer);
By: R1ch
Description: Adds mistakes and fixes them depending on FixChance. MisChance is
chance of making a mistake with it being fixed with TypeMistakesExPc, and AMChance
is using AddMistakes, so check that out. Text is the text you want typed, and
PressEnter is for pressing enter or not.
Example: RandMistakesExPc('Hello!', True, 20, 50, 23);
*******************************************************************************}
RandMistakesExPc(Text : string; PressEnter : Boolean; MisChance, FixChance, AMChance : Integer);
begin
if (InRange(Random(100), 0, FixChance)) then
TypeMistakesExPc(Text, PressEnter, MisChance)
else
TypeSendEx(AddMistakes(Text, AMChance), PressEnter);
end;

{*******************************************************************************
RandMistakesEx(Text : string; PressEnter : Boolean);
By: R1ch
Description: May add mistakes, and may fix them. Text is the text you want
typed, and PressEnter is for pressing enter or not. The Chances are preset.
Example: RandMistakesEx('Hello!', True);
*******************************************************************************}
RandMistakesEx(Text : string; PressEnter : Boolean);
begin
RandMistakesExPc(Text, PressEnter, RandomRange(4, 16), 50, RandomRange(20, 30));
end;

{*******************************************************************************
RandMistakesPc(Text : string; MisChance, FixChance, AMChance : Integer);
By: R1ch
Description: Adds mistakes and fixes them depending on FixChance. MisChance is
chance of making a mistake with it being fixed with TypeMistakesExPc, and AMChance
is using AddMistakes, so check that out. Text is the text you want typed. Enter
gets pressed.
Example: RandMistakesPc('Hello!', 20, 50, 23);
*******************************************************************************}
RandMistakesPc(Text : string; MisChance, FixChance, AMChance : Integer);
begin
RandMistakesExPc(Text, True, MisChance, FixChance, AMChance);
end;

{*******************************************************************************
RandMistakes(Text : string);
By: R1ch
Description: May add mistakes, and may fix them. Text is the text you want
typed, and enter is pressed. Chances are preset.
Example: RandMistakes('Hello!');
*******************************************************************************}
RandMistakes(Text : string);
begin
RandMistakesEx(Text, True);
end;

EDIT: MakeNorth could go into MapWalk.scar couldn't it?

nielsie95

2010-04-16 05:32:24

Instead of Proc : procedure; and all the equivalents, you can also consider using callproc, so people can use any type of function (with params).

Rich

2010-04-16 05:34:10

CallProc? How would I use that? I've never heard of it :o

nielsie95

2010-04-16 05:41:49

Should be in the latest SCAR:


program New;

function a(b, c: Integer; d: string): Extended;
begin
Result := b * c + StrToFloatDef(d, 1.2);
end;


var
v: TVariantArray;
begin
v := [1, 2, '3'];
WriteLn(CallProc('a', v));
end.

ZephyrsFury

2010-04-16 06:56:42

Does your type mistakes just replace characters with random other ones throughout the keyboard? Cos that's not really human tbh. My function only replaces them with chars close to the actual char as well as missing out chars, accidently holding the shift key for extra chars or adding extra chars (as far as I can remember).

Rich

2010-04-16 07:12:06

With just random keys.

Nava2

2010-04-16 11:40:36

Before adding it, I was going to modularize Zeph's code, then use it in yours.

Rich

2010-04-16 12:18:49

From: Nava2
Before adding it, I was going to modularize Zeph's code, then use it in yours.


Okies.

Nava2

2010-04-16 14:58:41

const
srl_Mistake_prevChar = 0;
srl_Mistake_curChar = 1;
srl_Mistake_nextChar = 2;
srl_Mistake_nullChar = '';

{*******************************************************************************
function mistakeChar(chars: array [0..2] of byte;
Chance: Integer;
out mistakeMade: Boolean): byte;
By: ZephyrsFury and Nava2
Description: Adds human mistakes to the second byte passed such as mistypes,
missing letters, wrong cases. Probability that a character is typed wrong is
1 / Chance. ie. Higher 'Chance' = less mistakes.
Probability is the chance that an individual character is typed incorrectly.
That is if you have more characters in a string you will get more mistakes overall.
20 - 30 is usually good but it varies depending on your string so experiment!
Note: If you have no previous, or post char, set them to srl_Mistake_nullChar.
Use: mistake := mistakeChar([' ', 'Z', 'e'], 30, mistakeMade);
*******************************************************************************}
function mistakeChar(chars: array [0..2] of char;
Chance: Integer;
out mistakeMade: Boolean): char;
var
Norm, Caps, Excp, TLine: String;
Line1, Line2, Line: array [0..3] of string;
firstChar: boolean;
currentChar, prevChar, nextChar: char;
j, TPos: Integer;
begin
mistakeMade := false;
Norm := '`1234567890-=qwertyuiop[]\asdfghjkl;''zxcvbnm,./';
Caps := '~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:"ZXCVBNM<>?';
Excp := '`1234567890-=[]\;'',./~!@#$%^&*()_+{}|:"<>?';
Line1[0] := '`1234567890-= '; Line2[0] := '~!@#$%^&*()_+ ';
Line1[1] := ' qwertyuiop[]\'; Line2[1] := ' QWERTYUIOP{}|';
Line1[2] := ' asdfghjkl;'' '; Line2[2] := ' ASDFGHJKL:" ';
Line1[3] := ' zxcvbnm,./ '; Line2[3] := ' ZXCVBNM<>? ';

{
Set the chars to be manipulated.
}
currentChar := chars[srl_Mistake_curChar];
prevChar := chars[srl_Mistake_prevChar];
nextChar := chars[srl_Mistake_nextChar];
firstChar := (prevChar <> srl_Mistake_nullChar);

{
Check if there are any irregular occurances to check for.
-Harder chars
-FirstChar
}
if (Pos(currentChar, Excp) <> 0) then Chance := Chance - 2;
if (firstChar) then Chance := Chance + 5;

if (currentChar <> ' ') and (Random(Max(Chance, 0)) = 0) then
begin
if (Pos(currentChar, Norm) <> 0) then
Line := Line1
else
if (Pos(currentChar, Caps) <> 0) then
Line := Line2;
for j := 0 to 3 do
begin
TPos := Pos(currentChar, Line[j]);
if (TPos <> 0) then
case Random(19) of
0..5: //Same line
begin
TLine := Line[j];
try
Result := TLine[TPos - 1 + Random(3)];
except end;
if (Result = '') or (Result = ' ') then
Result := TLine[TPos];
end;
6..8: //Line above
begin
TLine := Line[Max(j - 1, 0)];
try
Result := Line[j - 1][TPos + Random(2)];
except end;
if (Result = '') or (Result = ' ') then
Result := TLine[TPos];
end;
9..11: //Line below
begin
TLine := Line[Min(j + 1, High(Line))];
try
Result := TLine[TPos - 1 + Random(2)]; //Wrong case
except end;
if (Result = '') or (Result = ' ') then
Result := TLine[TPos];
end;
12..16:
begin
if (prevChar <> srl_Mistake_nullChar) then
begin
if (Pos(prevChar, Caps) <> 0) then
Result := Line2[j][TPos]
else
if (Pos(prevChar, Norm) <> 0) then
Result := Line1[j][TPos]
end else
if (nextChar <> srl_Mistake_nullChar) then
begin
if (Pos(nextChar, Caps) <> 0) then
Result := Line2[j][TPos]
else
if (Pos(nextChar, Norm) <> 0) then
Result := Line1[j][TPos];
end;
end;
17, 18: if (not firstChar) then Result := srl_Mistake_nullChar;//Missing letters
end;
end;
mistakeMade := true;
end else
Result := currentChar;
end;

{*******************************************************************************
function AddMistakes(Orig: string; Chance: Integer): string;
By: ZephyrsFury and Nava2
Description: Adds human mistakes to Orig such as mistypes, missing letters,
wrong cases. Probability that a character is typed wrong is 1 / Chance. ie.
Higher 'Chance' = less mistakes (I know thats stupid but oh well...).
Probability is the chance that an individual character is typed incorrectly.
That is if you have more characters in a string you will get more mistakes overall.
20 - 30 is usually good but it varies depending on your string so experiment!
Use: TypeSend(AddMistakes('Hello', 20));
*******************************************************************************}
function AddMistakes(Orig: string; Chance: Integer): string;
var
i, j, Mist, L: Integer;
mistakeBoolean: Boolean;
chars: array [0..2] of char;
newKey: char;
begin
L := length(orig);
for i := 1 to L do
begin
{
Set the chars to pass into the mistaceChar function.
}
if (i = 1) then
chars[srl_Mistake_prevChar] := srl_Mistake_nullChar
else
chars[srl_Mistake_prevChar] := orig[i-1];

chars[srl_Mistake_curChar] := orig[i];

if (i = L) then
chars[srl_Mistake_nextChar] := srl_Mistake_nullChar;
else
chars[srl_Mistake_nextChar] := orig[i+1];

{
Create the mistake result. Also, check if a mistake has been made, thus
making it less likely to make another mistake.
}
newChar := mistakeChar(chars, chance + mist, mistakeBoolean);
if (newChar <> srl_Mistake_nullChar) then
Result := Result + newChar;
if (mistakeBoolean) then inc(mist);
end;

Check that out, I can't seem to fix the errors in it..

Rich

2010-04-17 11:19:56

What are the errors?

Nava2

2010-04-17 11:55:21

Type mismatch ususally…

nielsie95

2010-04-17 12:32:16

The result is a char and '' is not a char, try #0 as nullchar..

edit: there you go:


const
srl_Mistake_prevChar = 0;
srl_Mistake_curChar = 1;
srl_Mistake_nextChar = 2;
srl_Mistake_nullChar = #0;

{*******************************************************************************
function mistakeChar(chars: array [0..2] of byte;
Chance: Integer;
out mistakeMade: Boolean): byte;
By: ZephyrsFury and Nava2
Description: Adds human mistakes to the second byte passed such as mistypes,
missing letters, wrong cases. Probability that a character is typed wrong is
1 / Chance. ie. Higher 'Chance' = less mistakes.
Probability is the chance that an individual character is typed incorrectly.
That is if you have more characters in a string you will get more mistakes overall.
20 - 30 is usually good but it varies depending on your string so experiment!
Note: If you have no previous, or post char, set them to srl_Mistake_nullChar.
Use: mistake := mistakeChar([' ', 'Z', 'e'], 30, mistakeMade);
*******************************************************************************}
function mistakeChar(chars: array [0..2] of char;
Chance: Integer;
out mistakeMade: Boolean): char;
var
Norm, Caps, Excp, TLine: String;
Line1, Line2, Line: array [0..3] of string;
firstChar: boolean;
currentChar, prevChar, nextChar: char;
j, TPos: Integer;
begin
mistakeMade := false;
Norm := '`1234567890-=qwertyuiop[]\asdfghjkl;''zxcvbnm,./';
Caps := '~!@#$%^&*()_+QWERTYUIOP{}|ASDFGHJKL:"ZXCVBNM<>?';
Excp := '`1234567890-=[]\;'',./~!@#$%^&*()_+{}|:"<>?';
Line1[0] := '`1234567890-= '; Line2[0] := '~!@#$%^&*()_+ ';
Line1[1] := ' qwertyuiop[]\'; Line2[1] := ' QWERTYUIOP{}|';
Line1[2] := ' asdfghjkl;'' '; Line2[2] := ' ASDFGHJKL:" ';
Line1[3] := ' zxcvbnm,./ '; Line2[3] := ' ZXCVBNM<>? ';

{
Set the chars to be manipulated.
}
currentChar := chars[srl_Mistake_curChar];
prevChar := chars[srl_Mistake_prevChar];
nextChar := chars[srl_Mistake_nextChar];
firstChar := (prevChar <> srl_Mistake_nullChar);

{
Check if there are any irregular occurances to check for.
-Harder chars
-FirstChar
}
if (Pos(currentChar, Excp) <> 0) then Chance := Chance - 2;
if (firstChar) then Chance := Chance + 5;

if (currentChar <> ' ') and (Random(Max(Chance, 0)) = 0) then
begin
if (Pos(currentChar, Norm) <> 0) then
Line := Line1
else
if (Pos(currentChar, Caps) <> 0) then
Line := Line2;
for j := 0 to 3 do
begin
TPos := Pos(currentChar, Line[j]);
if (TPos <> 0) then
case Random(19) of
0..5: //Same line
begin
TLine := Line[j];
try
Result := TLine[TPos - 1 + Random(3)];
except end;
if (Result = '') or (Result = ' ') then
Result := TLine[TPos];
end;
6..8: //Line above
begin
TLine := Line[Max(j - 1, 0)];
try
Result := Line[j - 1][TPos + Random(2)];
except end;
if (Result = '') or (Result = ' ') then
Result := TLine[TPos];
end;
9..11: //Line below
begin
TLine := Line[Min(j + 1, High(Line))];
try
Result := TLine[TPos - 1 + Random(2)]; //Wrong case
except end;
if (Result = '') or (Result = ' ') then
Result := TLine[TPos];
end;
12..16:
begin
if (prevChar <> srl_Mistake_nullChar) then
begin
if (Pos(prevChar, Caps) <> 0) then
Result := Line2[j][TPos]
else
if (Pos(prevChar, Norm) <> 0) then
Result := Line1[j][TPos]
end else
if (nextChar <> srl_Mistake_nullChar) then
begin
if (Pos(nextChar, Caps) <> 0) then
Result := Line2[j][TPos]
else
if (Pos(nextChar, Norm) <> 0) then
Result := Line1[j][TPos];
end;
end;
17, 18: if (not firstChar) then Result := srl_Mistake_nullChar;//Missing letters
end;
end;
mistakeMade := true;
end else
Result := currentChar;
end;

{*******************************************************************************
function AddMistakes(Orig: string; Chance: Integer): string;
By: ZephyrsFury and Nava2
Description: Adds human mistakes to Orig such as mistypes, missing letters,
wrong cases. Probability that a character is typed wrong is 1 / Chance. ie.
Higher 'Chance' = less mistakes (I know thats stupid but oh well...).
Probability is the chance that an individual character is typed incorrectly.
That is if you have more characters in a string you will get more mistakes overall.
20 - 30 is usually good but it varies depending on your string so experiment!
Use: TypeSend(AddMistakes('Hello', 20));
*******************************************************************************}
function AddMistakes(Orig: string; Chance: Integer): string;
var
i, Mist, L: Integer;
mistakeBoolean: Boolean;
chars: array [0..2] of char;
newChar: char;
begin
L := length(orig);
for i := 1 to L do
begin
{
Set the chars to pass into the mistaceChar function.
}
if (i = 1) then
chars[srl_Mistake_prevChar] := srl_Mistake_nullChar
else
chars[srl_Mistake_prevChar] := orig[i-1];

chars[srl_Mistake_curChar] := orig[i];

if (i = L) then
chars[srl_Mistake_nextChar] := srl_Mistake_nullChar
else
chars[srl_Mistake_nextChar] := orig[i+1];

{
Create the mistake result. Also, check if a mistake has been made, thus
making it less likely to make another mistake.
}
newChar := mistakeChar(chars, chance + mist, mistakeBoolean);
if (newChar <> srl_Mistake_nullChar) then
Result := Result + newChar;
if (mistakeBoolean) then inc(mist);
end;
end;