Random function

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?

You could start by posting this question in the forum category for Rapid programming. This one is for robotstudio feedback. :stuck_out_tongue:

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.

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]];

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

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

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. :s

Nowadays you can use Rand()