Simple Random Events

GPC2 script programming for Titan Two. Code examples, questions, requests.

Simple Random Events

Postby USER101 » Thu Dec 13, 2018 9:01 pm

In the following code the LED only stays white when I press and hold a button. It should blink different random colors at random times between 5 and 10 seconds after any button has been held. I was just guessing on how to accomplish this so if anyone could tell me what I did wrong that would be great.
Thanks

Code: Select all
#pragma METAINFO("<author_name>", 1, 0, "")
#include "ColorLED.gph"
#include <xb1.gph>
#define irand(a,b) (((int)(rand() * (fix32)(b+1 - a))) + a)
 
        bool activity(){ // Checks if any buttons I/O, (1 thru 24) are active.
        int i = 24;
        while(i--){
            if(is_active(i)) return TRUE;
            }
        return FALSE
        }
 
        bool sleep = FALSE;
        uint8 com;
        uint32 sleep_timer;
 
main {
 
    if(activity()){ // Check if any button is being pressed.
        sleep_timer += elapsed_time();
        ColorLED(CW);
 
    if(irand(5000, 10000) == sleep_timer) {// start random combo between 5 and 10 seconds
        sleep = TRUE;
        sleep_timer = 0;
        }
 
    if(sleep) { // pick and run a random combo
        irand(1, 5) == com;
        if (com == 1) combo_run(Sleep_1);
        else if (com == 2) combo_run(Sleep_2);
        else if (com == 3) combo_run(Sleep_3);
        else if (com == 4) combo_run(Sleep_4);
        else if (com == 5) combo_run(Sleep_5);
        }
    }else{ // stop all combos
        combo_stop(Sleep_1);
        combo_stop(Sleep_2);
        combo_stop(Sleep_3);
        combo_stop(Sleep_4);
        combo_stop(Sleep_5);
        ColorLED(CR);
        }
}
 
combo Sleep_1 {
    ColorLED(CP,100,100,4,CR);
    sleep = FALSE;
}
 
combo Sleep_2 {
    ColorLED(CG,100,100,4,CR);
    sleep = FALSE;
}
 
combo Sleep_3 {
    ColorLED(CC,100,100,4,CR);
    sleep = FALSE;
}
 
combo Sleep_4 {
    ColorLED(CB,100,100,4,CR);
    sleep = FALSE;
}
 
combo Sleep_5 {
    ColorLED(CA,100,100,4,CR);
    sleep = FALSE;
}
User avatar
USER101
Sergeant Major
Sergeant Major
 
Posts: 100
Joined: Mon Dec 03, 2018 5:45 pm

Re: Simple Random Events

Postby Scachi » Fri Dec 14, 2018 1:09 am

A couple of things:

== is used to compare values
= is used to assign a value

The main { } is run every 1ms or faster.
You should run ColorLED only when the color should change, not on every main loop run.
Ignoring this may lead to reboot/disconnect of your Titan Two / connected controllers.

You want to run the random value assignment only once or you will get e new random value on every main loop run (1ms or faster).

Here is your unchanged code with comments added trying to explain the/some issues:
Code: Select all
#pragma METAINFO("<author_name>", 1, 0, "")
#include "ColorLED.gph"
#include <xb1.gph>
#define irand(a,b) (((int)(rand() * (fix32)(b+1 - a))) + a)
 
        bool activity(){ // Checks if any buttons I/O, (1 thru 24) are active.
        int i = 24;
        while(i--){
            if(is_active(i)) return TRUE;
            }
        return FALSE
        }
 
        bool sleep = FALSE;
        uint8 com;
        uint32 sleep_timer;
 
main {
 
    if(activity()){ // Check if any button is being pressed.
        sleep_timer += elapsed_time();
        ColorLED(CW); // warning: will set W over and over again when activity is TRUE (input active)
 
    // you are getting a new random time every run of the main loop (1ms or faster)
    // the chance that you get the random time in the moment the sleep_timer has that value too will almost never start this
    if(irand(5000, 10000) == sleep_timer) {// start random combo between 5 and 10 seconds
        sleep = TRUE;
        sleep_timer = 0;
        }
 
    // no problem here,
    // you are running this code on every main loop run as long as sleep is TRUE (1) but it is TRUE only for one main loop run so you are fine
    if(sleep) { // pick and run a random combo
        irand(1, 5) == com; // you have to use = here instead of ==
        if (com == 1) combo_run(Sleep_1); // here == is correct
        else if (com == 2) combo_run(Sleep_2);
        else if (com == 3) combo_run(Sleep_3);
        else if (com == 4) combo_run(Sleep_4);
        else if (com == 5) combo_run(Sleep_5);
        }
    }else{ // stop all combos
        // problem here:  you are running this code on every main loop run as long as sleep is FALSE (0)
        combo_stop(Sleep_1);
        combo_stop(Sleep_2);
        combo_stop(Sleep_3);
        combo_stop(Sleep_4);
        combo_stop(Sleep_5);
        ColorLED(CR); // again, problem here with the LED function
        }
}
 
combo Sleep_1 {
    ColorLED(CP,100,100,4,CR);
    sleep = FALSE;
}
 
combo Sleep_2 {
    ColorLED(CG,100,100,4,CR);
    sleep = FALSE;
}
 
combo Sleep_3 {
    ColorLED(CC,100,100,4,CR);
    sleep = FALSE;
}
 
combo Sleep_4 {
    ColorLED(CB,100,100,4,CR);
    sleep = FALSE;
}
 
combo Sleep_5 {
    ColorLED(CA,100,100,4,CR);
    sleep = FALSE;
}


Here is your code, modified to work:
Code: Select all
// WRONG: #pragma METAINFO("<author_name>", 1, 0, "")
// correct: #pragma METAINFO("script name", 1, 0, "author_name")
#pragma METAINFO("script name", 1, 0, "author_name")
 
// It should blink different random colors at random times between 5 and 10 seconds after any button has been held.
 
#include "ColorLED.gph"
#include <xb1.gph>
#define irand(a,b) (((int)(rand() * (fix32)(b+1 - a))) + a)
 
bool activity(){ // Checks if any buttons I/O, (1 thru 24) are active.
int i = 24;
while(i--){
    if(is_active(i)) return TRUE;
    }
return FALSE
}
 
uint8 com;
uint32 sleep_timer;
int RandomTimer;
 
bool bActivityLast; // FALSE
bool bActivity;     // FALSE
 
init {
  ColorLED(CR)// inactivity -> red
  RandomTimer = irand(5000, 10000); // start random combo between every 5 and 10 seconds -- first random time
  printf("Initial Random Time: %d", RandomTimer);
}
 
main {
 
    bActivity = activity(); // Check if any button is being pressed.
 
    // only change the color if the state has changed to avoid setting the same color again and again
    if (bActivity != bActivityLast) { // if the activity changed
 
          // activity changed
          bActivityLast=bActivity;     
          printf("State changed to: %d", bActivity);
 
          if (bActivity) { // TRUE (1)
            ColorLED(CW); // activity -> white
            combo_stop(Sleep_1); // stop all combos
            combo_stop(Sleep_2);
            combo_stop(Sleep_3);
            combo_stop(Sleep_4);
            combo_stop(Sleep_5);
          }
          else { // FALSE (0)
            ColorLED(CR)// inactivity -> red
            RandomTimer = irand(5000, 10000); // start random combo between every 5 and 10 seconds
          }
    } // end of : if the activity changed
 
 
    if(!bActivity) { // no button active
      sleep_timer += elapsed_time();
 
      if (RandomTimer == sleep_timer) { // time reached, really sleeping now
        sleep_timer=0; // reset time tracking
        RandomTimer = irand(5000, 10000); // new random time
 
        // start random action
        com = irand(1, 5);
        if      (com == 1) combo_run(Sleep_1);
        else if (com == 2) combo_run(Sleep_2);
        else if (com == 3) combo_run(Sleep_3);
        else if (com == 4) combo_run(Sleep_4);
        else if (com == 5) combo_run(Sleep_5);
        printf("Started Sleep_%d , Next Random Time: %d",com,RandomTimer);
      }
 
    }
}
 
combo Sleep_1 {
    ColorLED(CP,100,100,4,CR);
}
 
combo Sleep_2 {
    ColorLED(CG,100,100,4,CR);
}
 
combo Sleep_3 {
    ColorLED(CC,100,100,4,CR);
}
 
combo Sleep_4 {
    ColorLED(CB,100,100,4,CR);
}
 
combo Sleep_5 {
    ColorLED(CA,100,100,4,CR);
}
 



Here is another version how I would do it:
Code: Select all
// WRONG: #pragma METAINFO("<author_name>", 1, 0, "")
// correct: #pragma METAINFO("script name", 1, 0, "author_name")
#pragma METAINFO("script name", 1, 0, "author_name")
 
// It should blink different random colors at random times between 5 and 10 seconds after any button has been held.
 
#include "ColorLED.gph"
#include <xb1.gph>
#define irand(a,b) (((int)(rand() * (fix32)(b+1 - a))) + a)
 
 
bool activity(){ // Checks if any buttons I/O, (1 thru 24) are active.
int i = 24;
while(i--){
    if(is_active(i)) return TRUE;
    }
return FALSE
}
 
int RandomTimer;
uint8 com;
 
bool bActivityLast; // FALSE
bool bActivity;     // FALSE
 
init {
  ColorLED(CR)// inactivity -> red
  RandomTimer = irand(5000, 10000); // start random combo between every 5 and 10 seconds -- first random time
  printf("Initial Random Time: %d", RandomTimer);
}
 
main {
 
    bActivity = activity(); // Check if any button is being pressed.
 
    // only change the color if the state has changed to avoid setting the same color again and again
    if (bActivity != bActivityLast) { // if the activity changed
 
          // activity changed
          bActivityLast=bActivity;     
          printf("State changed to: %d", bActivity);
 
          if (bActivity) { // TRUE (1)
            ColorLED(CW); // activity -> white
            // stop all combos
            combo_stop(Sleeping);
            combo_stop(Sleep_1);
            combo_stop(Sleep_2);
            combo_stop(Sleep_3);
            combo_stop(Sleep_4);
            combo_stop(Sleep_5);
          }
          else { // FALSE (0)
            ColorLED(CR)// inactivity -> red
            RandomTimer = irand(5000, 10000); // start random combo between every 5 and 10 seconds
          }
    } // end of : if the activity changed
 
 
    if(!bActivity) { // no button active
      combo_run(Sleeping); // does the waiting and action start in this combo
    }
}
 
combo Sleeping {
  printf("Started falling asleep");
  wait(0); // only output the text once
 
  wait(RandomTimer);
 
  // start random action
  com = irand(1, 5);
  if      (com == 1) combo_run(Sleep_1);
  else if (com == 2) combo_run(Sleep_2);
  else if (com == 3) combo_run(Sleep_3);
  else if (com == 4) combo_run(Sleep_4);
  else if (com == 5) combo_run(Sleep_5);
 
  RandomTimer = irand(5000, 10000); // new random time
  printf("Started Sleep_%d -- Next Random Time: %d", com, RandomTimer);
}
 
combo Sleep_1 {
    ColorLED(CP,100,100,4,CR);
}
 
combo Sleep_2 {
    ColorLED(CG,100,100,4,CR);
}
 
combo Sleep_3 {
    ColorLED(CC,100,100,4,CR);
}
 
combo Sleep_4 {
    ColorLED(CB,100,100,4,CR);
}
 
combo Sleep_5 {
    ColorLED(CA,100,100,4,CR);
}
 
User avatar
Scachi
Brigadier General
Brigadier General
 
Posts: 3044
Joined: Wed May 11, 2016 6:25 am
Location: Germany

Re: Simple Random Events

Postby USER101 » Fri Dec 14, 2018 3:59 am

As always you have come through for me Scachi. Not only did you help me fix the issue but you helped me understand the process as a whole including additional notes that will help me prevent issues in the future. And as always, thanks you so much for your help.
User avatar
USER101
Sergeant Major
Sergeant Major
 
Posts: 100
Joined: Mon Dec 03, 2018 5:45 pm

Re: Simple Random Events

Postby Sillyasskid » Fri Dec 14, 2018 4:19 am

I fixed the activity() function, the the i variable should be 25, not 24. :whistling:
Code: Select all
bool activity(){ // Checks if any buttons I/O, (1 thru 25) are active.
int i = 25;
while(i--){
    if(is_active(i)) return TRUE;
    }
return FALSE
}
If you left i = 24. Then only Buttons 1 thru 20, and STICK_1_X, STICK_1_Y, and STICK _2_X will be checked.
If you want STICK_2_Y to also be checked, then the i variable needs to be set to 25.
User avatar
Sillyasskid
Captain
Captain
 
Posts: 574
Joined: Sat May 14, 2016 3:07 am

Re: Simple Random Events

Postby USER101 » Fri Dec 14, 2018 8:05 pm

yeah I figured that out the other day when moving forward did not start my recording lol. Thanks for following up on that. Had I not figured it out you would have saved me some mental anguish.
User avatar
USER101
Sergeant Major
Sergeant Major
 
Posts: 100
Joined: Mon Dec 03, 2018 5:45 pm


Return to GPC2 Script Programming

Who is online

Users browsing this forum: No registered users and 98 guests