# Random function

Italy
I have to create a random function that generates a number between 1 and 100 and if the number is greater than 50, do one cycle, if less than another.
How can i do using rapid code?
Tagged:

• United States ✭✭✭
You could start by posting this question in the forum category for Rapid programming.  This one is for robotstudio feedback.

Or you can try this:

```FUNC num fRandomGenerator()
VAR num nRandom;
VAR num nMinute;
VAR num nSecond;
VAR num nArrayPointer1;
VAR num nArrayPointer2;
! you could also put numbers out of order within the array elements, allow duplicates if you like
VAR num myNumArray10x10{10,10}:=[[1,2,3,4,5,6,7,8,9,10],[91,92,93,94,95,96,97,98,99,100],[21,22,23,24,25,26,27,28,29,30],[61,62,63,64,65,66,67,68,69,70]
,[51,52,53,54,55,56,57,58,59,60],[41,42,43,44,45,46,47,48,49,50],[31,32,33,34,35,36,37,38,39,40],[71,72,73,74,75,76,77,78,79,80]
,[81,82,83,84,85,86,87,88,89,90],[11,12,13,14,15,16,17,18,19,20]];
! Random number generation based on minutes and seconds of system time
nMinute:=GetTime(\Min);
nSecond:=GetTime(\Sec);
IF nMinute = 0 THEN
! Cannot point to array index 0, will cause array index out of bounds
nArrayPointer1 := 1;
ELSEIF nMinute >= 1 AND nMinute <= 6 THEN
nArrayPointer1 := 1;
ELSEIF nMinute >= 7 AND nMinute <= 12 THEN
nArrayPointer1 := 2;
ELSEIF nMinute >= 13 AND nMinute <= 18 THEN
nArrayPointer1 := 3;
ELSEIF nMinute >= 19 AND nMinute <= 24 THEN
nArrayPointer1 := 4;
ELSEIF nMinute >= 25 AND nMinute <= 30 THEN
nArrayPointer1 := 5;
ELSEIF nMinute >= 31 AND nMinute <= 36 THEN
nArrayPointer1 := 6;
ELSEIF nMinute >= 37 AND nMinute <= 42 THEN
nArrayPointer1 := 7;
ELSEIF nMinute >= 43 AND nMinute <= 48 THEN
nArrayPointer1 := 8;
ELSEIF nMinute >= 49 AND nMinute <= 54 THEN
nArrayPointer1 := 9;
ELSEIF nMinute >= 55 AND nMinute <= 60 THEN
nArrayPointer1 := 10;
ENDIF
IF nSecond = 0 THEN
! Cannot point to array index 0, will cause array index out of bounds
nArrayPointer2 := 1;
ELSEIF nSecond >= 1 AND nSecond <= 6 THEN
nArrayPointer2 := 1;
ELSEIF nSecond >= 7 AND nSecond <= 12 THEN
nArrayPointer2 := 2;
ELSEIF nSecond >= 13 AND nSecond <= 18 THEN
nArrayPointer2 := 3;
ELSEIF nSecond >= 19 AND nSecond <= 24 THEN
nArrayPointer2 := 4;
ELSEIF nSecond >= 25 AND nSecond <= 30 THEN
nArrayPointer2 := 5;
ELSEIF nSecond >= 31 AND nSecond <= 36 THEN
nArrayPointer2 := 6;
ELSEIF nSecond >= 37 AND nSecond <= 42 THEN
nArrayPointer2 := 7;
ELSEIF nSecond >= 43 AND nSecond <= 48 THEN
nArrayPointer2 := 8;
ELSEIF nSecond >= 49 AND nSecond <= 54 THEN
nArrayPointer2 := 9;
ELSEIF nSecond >= 55 AND nSecond <= 60 THEN
nArrayPointer2 := 10;
ENDIF
nRandom:=myNumArray10x10{nArrayPointer1,nArrayPointer2};
RETURN nRandom;
ENDFUNC
```

I just put it together, it is yet untested, should work.
Lee Justice
• United States ✭✭✭
I have been testing, it works.  I like it better with the array jumbled up, like this:

```VAR num myNumArray10x10{10,10}:=[[51,22,3,14,5,86,77,8,29,70],[91,42,93,74,95,16,97,38,99,90],[21,2,23,24,35,26,37,28,9,30],[61,72,83,84,65,76,67,18,79,50]
,[1,12,33,54,75,36,57,88,59,40],[41,92,43,34,45,46,17,78,49,80],[31,82,53,44,25,56,27,98,19,20],[71,62,13,94,55,66,7,48,69,10]
,[81,32,63,4,85,6,87,58,89,100],[11,52,73,64,15,96,47,68,39,60]];
```

Lee Justice
• FRANCE ✭✭✭
edited June 2020
Hello,
Here, what I use:
!To get Ramdom more random
LOCAL VAR num callCount;

!Get a random number between 0 and 1
LOCAL FUNC num RANDOM()
VAR num val:=1;

var pos pos_current;
pos_current := CPos(\Tool:=tool0 \WObj:=wobj0);
!
!1 seeding, Seed by position
val:=val*(Abs(ROUND(pos_current.x*100, \Dec:=0)) +1); !+1 to avoid mul by 0 scenario
val := 789 + val MOD 1000; !777 is just a bogus valu, since the mod might give 0
!
!Feel free to seed with y,z, more
!
!2. seeding, Seed by time
val :=val * ( GetTime(\Sec)+1);
val :=val * ( GetTime(\Min)+1);
!
!3 seeding, increment callcount and handle large number
callCount := callCount +1;
IF callCount > 1000 THEN
callCount := 234;
ENDIF
!
!finally a division to get something interesting large float number
val := val / callCount;
!
!get a value between 0 and 1 using COS ( math)
RETURN (0.5 + COS(val)/2);
!
ENDFUNC

• United States ✭✭✭
I made a revision so that the numbers used are tracked, therefore using only once, until all have been used.  Then it will be reset.

```MODULE RANDOM_GEN
! REV 1, added bool array to track numbers already used, no duplicates.
! Added counter for total of numbers used
! Boolean array to keep track of which numbers have been used
PERS bool bUsedArray{10,10}:=[[TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE],[TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE]
,[TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE],[FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE],[FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE]
,[FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE],[FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE],[FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE]
,[FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE],[FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE]];
! Counter for how many total numbers, number range.  In this case, 1-100
PERS num nNumbersUsed;

FUNC num fRandomGenerator()
VAR num nRandom;
VAR num nMinute;
VAR num nSecond;
VAR num nArrayPointer1;
VAR num nArrayPointer2;
CONST num myNumArray10x10{10,10}:=[[51,22,83,14,5,86,77,8,29,70],[91,42,93,74,45,16,87,38,99,90],[21,2,23,24,35,26,37,28,89,30],[61,72,3,84,65,76,67,18,79,50]
,[1,12,33,54,75,36,57,88,59,40],[41,92,43,34,95,46,17,78,49,80],[31,82,53,44,25,56,27,98,19,20],[71,62,13,94,55,66,7,48,69,10]
,[81,32,63,4,85,6,97,58,9,100],[11,52,73,64,15,96,47,68,39,60]];
! Random number generation based on minutes and seconds of system time
nMinute:=GetTime(\Min);
nSecond:=GetTime(\Sec);
IF nMinute = 0 THEN
! Cannot point to array index 0, will cause array index out of bounds
nArrayPointer1 := 1;
ELSEIF nMinute >= 1 AND nMinute <= 6 THEN
nArrayPointer1 := 1;
ELSEIF nMinute >= 7 AND nMinute <= 12 THEN
nArrayPointer1 := 2;
ELSEIF nMinute >= 13 AND nMinute <= 18 THEN
nArrayPointer1 := 3;
ELSEIF nMinute >= 19 AND nMinute <= 24 THEN
nArrayPointer1 := 4;
ELSEIF nMinute >= 25 AND nMinute <= 30 THEN
nArrayPointer1 := 5;
ELSEIF nMinute >= 31 AND nMinute <= 36 THEN
nArrayPointer1 := 6;
ELSEIF nMinute >= 37 AND nMinute <= 42 THEN
nArrayPointer1 := 7;
ELSEIF nMinute >= 43 AND nMinute <= 48 THEN
nArrayPointer1 := 8;
ELSEIF nMinute >= 49 AND nMinute <= 54 THEN
nArrayPointer1 := 9;
ELSEIF nMinute >= 55 AND nMinute <= 60 THEN
nArrayPointer1 := 10;
ENDIF
IF nSecond = 0 THEN
! Cannot point to array index 0, will cause array index out of bounds
nArrayPointer2 := 1;
ELSEIF nSecond >= 1 AND nSecond <= 6 THEN
nArrayPointer2 := 1;
ELSEIF nSecond >= 7 AND nSecond <= 12 THEN
nArrayPointer2 := 2;
ELSEIF nSecond >= 13 AND nSecond <= 18 THEN
nArrayPointer2 := 3;
ELSEIF nSecond >= 19 AND nSecond <= 24 THEN
nArrayPointer2 := 4;
ELSEIF nSecond >= 25 AND nSecond <= 30 THEN
nArrayPointer2 := 5;
ELSEIF nSecond >= 31 AND nSecond <= 36 THEN
nArrayPointer2 := 6;
ELSEIF nSecond >= 37 AND nSecond <= 42 THEN
nArrayPointer2 := 7;
ELSEIF nSecond >= 43 AND nSecond <= 48 THEN
nArrayPointer2 := 8;
ELSEIF nSecond >= 49 AND nSecond <= 54 THEN
nArrayPointer2 := 9;
ELSEIF nSecond >= 55 AND nSecond <= 60 THEN
nArrayPointer2 := 10;
ENDIF
WHILE nRandom = 0 DO
IF NOT bUsedArray{nArrayPointer1,nArrayPointer2} THEN
nRandom:=myNumArray10x10{nArrayPointer1,nArrayPointer2};
bUsedArray{nArrayPointer1,nArrayPointer2}:=TRUE;
ELSE
FOR i FROM 1 TO 10 DO
FOR j FROM 1 TO 10 DO
IF bUsedArray{i,j} = FALSE THEN
bUsedArray{i,j}:= TRUE;
nRandom:=myNumArray10x10{i,j};
IF (i <= 10) AND (j <= 10) THEN
IF nRandom = 0 STOP;
Incr nNumbersUsed;
! all of the array positions have been used, this is the
! last one, time to reset all to FALSE
IF nNumbersUsed = 100 ResetBool;
RETURN nRandom;
ENDIF
ENDIF
ENDFOR
ENDFOR
ENDIF
ENDWHILE
IF nRandom = 0 STOP;
Incr nNumbersUsed;
! all of the array positions have been used, this is the
! last one, time to reset all to FALSE
IF nNumbersUsed = 100 ResetBool;
RETURN nRandom;
ENDFUNC

PROC testFunc()
VAR num nTest;

nTest:=fRandomGenerator();
TPWrite "Random number generated is: "\Num:=nTest;
WaitTime 5;
ENDPROC

PROC ResetBool()
FOR i FROM 1 TO 10 DO
FOR j FROM 1 TO 10 DO
bUsedArray{i,j}:=FALSE;
ENDFOR
ENDFOR
nNumbersUsed:=0;
ENDPROC
ENDMODULE```

Lee Justice
• United States ✭✭✭
I noticed today that I left some of the bUsed array TRUE after I had been testing.  If you would like to use this code please make sure that you make them all FALSE first.  Too late for me to edit that post.
Lee Justice
• Sweden