Inserting random elements into random arrays

edited March 2018 in Questions about Code

Hello all!

Creating an adlib poem generator and was wondering if anyone knew how to go about inserting a random array element into another array. I looked up the join function but the issue comes when you only need to use it once. I read that java/Processing can't dynamically insert elements? Not sure if that's true or not.

String [] poem = new String[15]; // input text
String [] words = new String[0]; // empty 0 len array for words

String[] adj = {
"happy", "rotating", "red", "fast", "elastic", "smiley", "unbelievable", "infinite", "surprising", 
"mysterious", "glowing", "green", "blue", "tired", "hard", "soft", "transparent", "long", "short", 
"excellent", "noisy", "silent", "rare", "normal", "typical", "living", "clean", "glamorous", 
};

void setup(){

poem[0]="i love you much ADJECTIVE darling ";
poem[1]="i love you much ADJECTIVE darling ";
poem[2]="more than anyone on the earth and i";
poem[3]="like you better than everything in the sky";
poem[4]="-sunlight and singing welcome your coming";
poem[5]="although winter may be everywhere";
poem[6]="with such a silence and such a darkness";
poem[7]="noone can quite begin to guess";
poem[8]="(except my life)the true time of year-";
poem[9]="and if what calls itself a world should have";
poem[10]="the luck to hear such singing(or glimpse such";
poem[11]="sunlight as will leap higher than high";
poem[12]="through gayer than gayest someone's heart at your each";
poem[13]="nearness)everyone certainly would(my";
poem[14]="most beautiful darling)believe in nothing but love";

I'd like to do have it so that when the mouse is pressed, it pulls out a random line of the poem so my first try of combining all the sentences under one array name (like I did with the adjectives) doesn't quite work (unless I'm mistaken). Abridged example below.

String[] poem = {"i love you much ",". darling"}; 
String [] adj = { "happy", "rotating", "red", "fast", "elastic",  "smiley"};
int rand = int(random(adj.length));
println(join (poem,(adj[rand])));
exit();

Any pointers would help, thank you!

Answers

  • edited March 2018 Answer ✓

    You might be better off using your first idea.

    If you leave the tokens in the poem strings then you can call .replaceFirst() on the string with the token name (ADJECTIVE) and a random entry from your adjective list.

    https://beginnersbook.com/2013/12/java-string-replace-replacefirst-replaceall-method-examples/

  • Answer ✓

    Instead of println(join (poem,(adj[rand]))); use println(concat (poem,(adj[rand])));

    https://processing.org/reference/concat_.html

    Kf

    //INSTRUCTIONS:
    //         *-- Either by pressing 1 or 2 will show raw (unmodified) poem or the modified data
    //         *-- When showing modified data, you can click in a line to replace
    //         *-- the lead word for one of the adjectives.
    //         *--
    
    //===========================================================================
    // IMPORTS:
    
    
    //===========================================================================
    // FINAL FIELDS:
    final int Y_OFFSET=100;
    final String LEAD_WORD="ADJECTIVE";
    
    //===========================================================================
    // GLOBAL VARIABLES:
    
    final int TEXT_SIZE=14;
    
    final int SHOW_RAW=0;
    final int SHOW_NEW=1;
    
    String [] poem = new String[15]; // input text
    String [] words = new String[0]; // empty 0 len array for words
    String [] poemUpdated=new String[poem.length];
    ;
    int showState=SHOW_RAW;
    
    String[] adj = {
      "happy", "rotating", "red", "fast", "elastic", "smiley", "unbelievable", "infinite", "surprising", 
      "mysterious", "glowing", "green", "blue", "tired", "hard", "soft", "transparent", "long", "short", 
      "excellent", "noisy", "silent", "rare", "normal", "typical", "living", "clean", "glamorous", 
    };
    
    
    
    //===========================================================================
    // PROCESSING DEFAULT FUNCTIONS:
    
    void settings() {
      size(500, 600);
    }
    
    void setup() {
    
      textAlign(CENTER, CENTER);
      rectMode(CENTER);
    
      fill(255);
      strokeWeight(2);
      textSize(TEXT_SIZE);
    
      poem[0]="i love you much ADJECTIVE darling ";
      poem[1]="i love you much ADJECTIVE darling ";
      poem[2]="more than anyone on the earth and i";
      poem[3]="like you better than everything in the sky";
      poem[4]="-sunlight and singing welcome your coming";
      poem[5]="although winter may be everywhere";
      poem[6]="with such a silence and such a darkness";
      poem[7]="noone can quite begin to guess";
      poem[8]="(except my life)the true time of year-";
      poem[9]="and if what calls itself a world should have";
      poem[10]="the luck to hear such singing(or glimpse such";
      poem[11]="sunlight as will leap higher than high";
      poem[12]="through gayer than gayest someone's heart at your each";
      poem[13]="nearness)everyone certainly would(my";
      poem[14]="most beautiful darling)believe in nothing but love";
    
      arrayCopy(poem, poemUpdated );
    }
    
    
    
    void draw() {
      background(0);
    
      if (showState == SHOW_RAW)
        showRawData(); 
      else 
      showUpdatedData();
    }
    
    void keyReleased() {
      if (key=='1')
        showState = SHOW_RAW;
    
      if (key=='2')
        showState = SHOW_NEW;
    }
    
    void mouseReleased() {
    
      if (key!='2')
        return;
    
      int line=constrain((mouseY-Y_OFFSET)/(2*TEXT_SIZE), 0, poem.length-1);
      println(mouseY + " line selected @"+line);
    
      //Nothing to do if none of the poems lines was selected
      if (line>=poem.length)
        return; 
    
      arrayCopy(poem, poemUpdated );
    
      String ss = new String(poemUpdated[line]);
      int idx=int(random(adj.length));
    
      poemUpdated[line]=ss.replaceAll(LEAD_WORD, adj[idx]);
      println(idx + " is "+ adj[idx] + " ===> "+poemUpdated[line]);
    
    }
    
    
    
    //===========================================================================
    // OTHER FUNCTIONS:
    
    void showRawData() {
    
      fill(255);
      for (int i=0; i<poem.length; i++) {
        text(poem[i], width/2, Y_OFFSET + i*2*TEXT_SIZE);
      }
    }
    
    void showUpdatedData() { 
    
      fill(255, 150, 20);
      for (int i=0; i<poemUpdated.length; i++) {
        text(poemUpdated[i], width/2, Y_OFFSET + i*2*TEXT_SIZE);
      }
    }
    
  • @syang --

    I read that java/Processing can't dynamically insert elements? Not sure if that's true or not.

    In addition to the strategies discussed above, this about your general point: inserting elements into arrays is often more trouble than it needs to be, as you must resize the array and/or replace it with a new one (the array has a static length).

    Another approach is to use an ArrayList, which has an add method that can insert at a specified position. ArrayLists grow (or shrink) dynamically.

  • edited March 2018

    @koogs Thank you, after reading up on it, seems much more compatible than the join or append functions I was attempting

    @kfrajer What a brilliant way of visualizing and interacting with it, I will definitely use this a springboard since I'm also playing around with other parts of speech as well, which would use another lead_word (based on your code). So I'll also be reading other arrays as well. Struggling with the if statements that this would require but let me know if I'm overcomplicating it.

    I did play around with concat originally but the issue I was running into was if the part of speech was in the middle of the sentence.

    @jeremydouglass Thanks, that was good to read up on!

  • Working over this more, that would be my next question -- using replaceFirst(), how do you pull from other arrays, if one sentence is using nouns or adjectives, or pronouns? The way I've written it so far, it will just pull from one array and not recognize another one.

  • well, replaceFirst(ADJECTIVE, adjectives(random(...)); will replace the first ADJECTIVE. so just call it again with the other things - replaceFirst(NOUN, nouns(random(...)) etc. if there aren't any then it won't do anything.

    repeat until you have no more tokens in the input string. (how would you know? perhaps use {ADJECTIVE} instead of just ADJECTIVE then you can check the input string for {... )

  • edited March 2018

    @koogs thank you! That got me started on the right path.

    For future reference, I discovered the contains function (seems to be more a general java function) and have used that to easily pick up parts of speech in the adlib.

    With your arrays in mind, it looks something like this:

    if (sentence[rand].contains("ADJECTIVES")) {  
      text(sentence[rand].replaceFirst("ADJECTIVES", adjectives[adjRand]), width/2, 
    height/2);
    }
    
  • Why not have an adjective class that just hold the adjectives, another class that just holds other strings and then pick sentences and adjectives and joining them together. It would be like having to bagsof notes. Adjectives in one and sentences in the other.

    You just reach into the bag and pull out two strings/notes and put them together.

Sign In or Register to comment.