Pick Random Number Based on Preceding Number

Good morning all;

I’m trying to write a random number generator that generates twelve different random numbers and displays them in a column. However, what random number can follow each other one is limited to certain numbers. For example, if the first random number is 6, then the second random number can only be 1, 2, 5, 6, 7, 10, or 11. If that second random number is 11, then the third random number can only be 6, 7, 10, 11, or 12. And, so on…

I can’t think of a way to write this outside of a series of nested if statements, which I understand is poor coding. I thought that a two-dimensional array would be the way to go but can’t think of how to reference the selected number in the array in the second iteration.

Edit: Thank you in advance and apologies if this is somewhere – I tried wording it in a way that I could find it in the forums but no luck!

1 Like

what is the rule which decides the values available after a number is chosen? i’m not following the logic. or is it just a set of predefined numbers?

if there is a rule it is much easier. if it is predefined you could have a nested array
so if 0-n is chosen that is used as an index into the available numbers to chose something like

int[][] sequences;

void setup() {
  sequences = new int[10][];
  
  //build a random set of sequences as i don't have your list
  for(int i = 0; i < sequences.length; i++) {
    sequences[i] = new int[int(random(10))];
    for(int j = 0; j < sequences[i].length; j++) {
      sequences[i][j] = int(random(10));
    }
  }
  
  //do some random selections
  int lastSelected = int(random(sequences.length));
  println(lastSelected);
  for(int i = 0; i < 20; i++) {
    lastSelected = sequences[lastSelected][int(random(sequences[lastSelected].length))];
    println(lastSelected);
  }
}
2 Likes

I suppose the list would help! So, I’m working off of a hexagonal grid. So, whatever the starting number, the second number can only be either the same number or a number of an adjacent hexagon, and so on. So, the rule isn’t so exact…

Image below.

Screen Shot 2021-10-02 at 00.56.44

so if you know the index of the cell you are in which is the selected number you could just have an array of the offsets of the six surrounding hexagons.

[-1, +1, -4, +4, -5, +5]

select from that array randomly and add it to the current index

… at least at first look

edit: i guess the edges of the board/grid might be problematic but you could just add a few conditionals to account for that

3 Likes

He could use constrain() to keep the random value + offset within range 1 to 13:

Something like this:

static final byte[] OFFSETS = { 0, -1, 1, -4, 4, -5, 5 };
static final int LOWEST = 1, HIGHEST = 13;

static final boolean isValidNext(final int next, final int prev) {
  for (final byte offset : OFFSETS)
    if (next == constrain(prev + offset, LOWEST, HIGHEST))  return true;
  return false;
}
4 Likes

This is probably the chunkiest way I could have done it. But, after your help and trying to remember my Processing after almost a year away from it (and only a few months at it at that time), it works as I need it to. Now that it’s working, I’ll read up how to clean this up but thank you for your help!

@GoToLoop I’ll take a look at your response to and see if I can shorten and clarify the code with that!

// Reproduction of a program by Francisco Sagasti (March 14, 1968 at PSU)
// Originally built on Fortran IV programming language on an IBM 360/65 (1MB RAM)
// ***USE***
// Program tells 12 dancers where to be in space based on a hexagonal floor plan
// Dancers are told where to move (or stay) each measure
// Dancers can do any movement, any effort, etc.
// This is more of a "spatial score" as per Sagasti

IntList hexagon = new IntList();
IntList factorn1 = new IntList(), factor1 = new IntList(), factor23 = new IntList(), factor4 = new IntList(), factorn4 = new IntList(), factor5 = new IntList(), factorn5 = new IntList(), factor678 = new IntList(), factor9 = new IntList(), factorn9 = new IntList(), factor10 = new IntList(), factorn10 = new IntList(), factor1112 = new IntList(), factor13 = new IntList(), factorn13 = new IntList();
int start, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, twelfth;

int textSpacing = 35;
int fade = 145;

float r = PI/1.98;
int hexSize = 40, xLoc = 250, yLoc = 75, xSpacing = 69, ySpacing = 60;

String[] dancers = {"Dancer A", "Dancer B", "Dancer C", "Dancer D", "Dancer E", "Dancer F", "Dancer G", "Dancer H", "Dancer I", "Dancer J", "Dancer K", "Dancer L"};

Floor[] floor1 = new Floor[4];
Floor[] floor2 = new Floor[5];
Floor[] floor3 = new Floor[4];

void setup() {
  size(1280, 720);
  
  hexagon.append(1);
  hexagon.append(new int[] {-1, 2, 3, -4, 4, -5, 5, 6, 7, 8, -9, 9, -10, 10, 11, 12, -13, 13});
  factorn1.append(new int[] {0, +2, +6}); // can go to space 1 or 5
  factor1.append(new int[] {0, -2, +1, +4, +5}); // -2 goes to off SR space -1
  factor23.append(new int[] {0, -1, +1, +4, +5});
  factor4.append(new int[] {0, -8, -1, +4, +5}); // -4 goes to off SR space -4
  factorn4.append(new int[] {0, +8, +13}); //can go to space 4 or 9
  factor5.append(new int[] {0, -15, -10, -6, -4, +1, +5}); // moves to any off SL position
  factorn5.append(+10); // can only move to space 5
  factor678.append(new int[] {0, -1, -4, -5, +1, +4, +5});
  factor9.append(new int[] {0, -22, -18, -13, -5, -1, +4}); // moves to any off SR position
  factorn9.append(new int[] {0, +18}); // can only move to space 9
  factor10.append(new int[] {0, -20, -4, -5, +1});
  factorn10.append(new int[] {0, +15, +20}); // can only move to spaces 5 & 10
  factor1112.append(new int[] {0, -1, -4, -5, +1});
  factor13.append(new int[] {0, -26, -5, -4, -1});
  factorn13.append(new int[] {0, +22, +26});
  
  fill(0);
  for (int i = 0; i < 12; i++) {
    theScore();
    text(dancers[0+i], 120 + textSpacing * (i * 2.75), 300);
    text(start, 135 + textSpacing * (i * 2.75), 325);
    text(second, 135 + textSpacing * (i * 2.75), 325 + textSpacing * 1);
    text(third, 135 + textSpacing * (i * 2.75), 325 + textSpacing * 2);
    text(fourth, 135 + textSpacing * (i * 2.75), 325 + textSpacing * 3);
    text(fifth, 135 + textSpacing * (i * 2.75), 325 + textSpacing * 4);
    text(sixth, 135 + textSpacing * (i * 2.75), 325 + textSpacing * 5);
    text(seventh, 135 + textSpacing * (i * 2.75), 325 + textSpacing * 6);
    text(eighth, 135 + textSpacing * (i * 2.75), 325 + textSpacing * 7);
    text(ninth, 135 + textSpacing * (i * 2.75), 325 + textSpacing * 8);
    text(tenth, 135 + textSpacing * (i * 2.75), 325 + textSpacing * 9);
    text(eleventh, 135 + textSpacing * (i * 2.75), 325 + textSpacing * 10);
    text(twelfth, 135 + textSpacing * (i * 2.75), 325 + textSpacing * 11);
  }
  
  text("Measure", 30, 300);
  for (int i = 0; i < 12; i++) {
    text(i + 1, 30, 325 + textSpacing * i);
  }
  
  text("Downstage", 100 + xSpacing * 3 + 15, 20);
  text("Upstage", 100 + xSpacing * 3 + 20, yLoc + 60 + ySpacing * 2);
  text("Stage Right", 185 + 435, 140);
  text("Stage Left", 15 + 15, 140);
  
  noFill();
  stroke(0);
  
  // Downstage Row
  for (int x = xLoc; x < xLoc + xSpacing * 4; x += xSpacing) {
  pushMatrix();
  translate(x, yLoc);
  rotate(r);
  polygon(0, 0, hexSize, 6);
  popMatrix();
  }
  
  // Spot -10
  stroke(fade);
  fill(fade);
  text("-10", xLoc - hexSize - 30 - 15, yLoc);
  noFill();
  pushMatrix();
  translate(xLoc - hexSize - 30, yLoc);
  rotate(r);
  polygon(0, 0, hexSize, 6);
  popMatrix();
  
  // Spot -13
  stroke(fade);
  fill(fade);
  text("-13", xLoc + 1 + xSpacing * 4 - 15, yLoc);
  noFill();
  pushMatrix();
  translate(xLoc + 1 + xSpacing * 4, yLoc);
  rotate(r);
  polygon(0, 0, hexSize, 6);
  popMatrix();
  
  stroke(0);
  // Midstage Row
  for (int x = xLoc - 34; x < xLoc + xSpacing * 4; x += xSpacing) {
  pushMatrix();
  translate(x, yLoc + ySpacing);
  rotate(r);
  polygon(0, 0, hexSize, 6);
  popMatrix();
  }
  
  // Spot -5
  stroke(fade);
  fill(fade);
  text("-5", xLoc - hexSize -30 - 34 - 10, yLoc + ySpacing);
  noFill();  
  pushMatrix();
  translate(xLoc - hexSize - 30 - 34, yLoc + ySpacing);
  rotate(r);
  polygon(0, 0, hexSize, 6);
  popMatrix();
  
  // Spot -9
  stroke(fade);
  fill(fade);
  text("-9", xLoc + 2 + 34 + xSpacing * 4 - 10, yLoc + ySpacing);
  noFill();    
  pushMatrix();
  translate(xLoc + 2 + 34 + xSpacing * 4, yLoc + ySpacing);
  rotate(r);
  polygon(0, 0, hexSize, 6);
  popMatrix();

  // Upstage Row
  stroke(0);
  for (int x = xLoc; x < xLoc + xSpacing * 4; x += xSpacing) {
  pushMatrix();
  translate(x, yLoc + ySpacing * 2);
  rotate(r);
  polygon(0, 0, hexSize, 6);
  popMatrix();
  }
  
  // Spot -1
  stroke(fade);
  fill(fade);
  text("-1", xLoc - hexSize - 30 - 10, yLoc + ySpacing * 2);
  noFill();    
  pushMatrix();
  translate(xLoc - hexSize - 30, yLoc + ySpacing * 2);
  rotate(r);
  polygon(0, 0, hexSize, 6);
  popMatrix();
  
  // Spot -4
  stroke(fade);
  fill(fade);
  text("-4", xLoc + 1 + xSpacing * 4 - 10, yLoc + ySpacing * 2);
  noFill();     
  pushMatrix();
  translate(xLoc + 1 + xSpacing * 4, yLoc + ySpacing * 2);
  rotate(r);
  polygon(0, 0, hexSize, 6);
  popMatrix();

  stroke(0);
  fill(0);
  for (int i = 0; i < floor1.length; i++) {
    floor1[i] = new Floor(i+1, (xLoc - 3) + xSpacing * i, yLoc + 3 + ySpacing * 2);
    floor3[i] = new Floor(i+10, (xLoc - 8) + xSpacing * i, yLoc + 3);
  }
  
  for (int i = 0; i < floor2.length; i++) {
    floor2[i] = new Floor(i+5, (xLoc - 34 - 3) + xSpacing * i, yLoc + 3 + ySpacing);
  }

  for (int i = 0; i < floor1.length; i++) {
    floor1[i].disFloor();
  }
  
   
  for (int i = 0; i < floor2.length; i++) {
    floor2[i].disFloor();
  }
  
   
  for (int i = 0; i < floor3.length; i++) {
    floor3[i].disFloor();
  }  
  
}

void draw() {
}

void polygon(float x, float y, float radius, int npoints) {
  float angle = TWO_PI / npoints;
  beginShape();
  for (float a = 0; a < TWO_PI; a += angle) {
    float sx = x + cos(a) * radius;
    float sy = y + sin(a) * radius;
    vertex(sx, sy);
  }
  endShape(CLOSE);
}

class Floor {
  int t, x, y;
  Floor(int t_, int x_, int y_) {
    t = t_;
    x = x_;
    y = y_;
  }
  void disFloor() {
    text(t, x, y);
  }
}

void theShuffle() {
  factorn1.shuffle();
  factor1.shuffle();
  factor23.shuffle();
  factor4.shuffle();
  factorn4.shuffle();
  factor5.shuffle();
  factorn5.shuffle();
  factor678.shuffle();
  factor9.shuffle();
  factorn9.shuffle();
  factor10.shuffle();
  factorn10.shuffle();
  factor1112.shuffle();
  factor13.shuffle();
  factorn13.shuffle();
}

void theScore() {
  // First Measure
  hexagon.shuffle();
  start = hexagon.get(0);
  
  // Second Measure
  theShuffle();
  switch(start) {
    case -1: second = start + factorn1.get(0); break;
    case 1: second = start + factor1.get(0); break;
    case 2: second = start + factor23.get(0); break;
    case 3: second = start + factor23.get(0); break;
    case 4: second = start + factor4.get(0); break;
    case -4: second = start + factorn4.get(0); break;
    case 5: second = start + factor5.get(0); break;
    case -5: second = start + factorn5.get(0); break;
    case 6: second = start + factor678.get(0); break;
    case 7: second = start + factor678.get(0); break;
    case 8: second = start + factor678.get(0); break;
    case 9: second = start + factor9.get(0); break;
    case -9: second = start + factorn9.get(0); break;
    case 10: second = start + factor10.get(0); break;
    case -10: second = start + factorn10.get(0); break;
    case 11: second = start + factor1112.get(0); break;
    case 12: second = start + factor1112.get(0); break;
    case 13: second = start + factor13.get(0); break;
    case -13: second = start + factorn13.get(0); break;
  }

  // Third Measure
  theShuffle();
  switch(second) {
    case -1: third = second + factorn1.get(0); break;
    case 1: third = second + factor1.get(0); break;
    case 2: third = second + factor23.get(0); break;
    case 3: third = second + factor23.get(0); break;
    case 4: third = second + factor4.get(0); break;
    case -4: third = second + factorn4.get(0); break;
    case 5: third = second + factor5.get(0); break;
    case -5: third = second + factorn5.get(0); break;
    case 6: third = second + factor678.get(0); break;
    case 7: third = second + factor678.get(0); break;
    case 8: third = second + factor678.get(0); break;
    case 9: third = second + factor9.get(0); break;
    case -9: third = second + factorn9.get(0); break;
    case 10: third = second + factor10.get(0); break;
    case -10: third = second + factorn10.get(0); break;
    case 11: third = second + factor1112.get(0); break;
    case 12: third = second + factor1112.get(0); break;
    case 13: third = second + factor13.get(0); break;
    case -13: third = second + factorn13.get(0); break;
  }
  
  // Fourth Measure
  theShuffle();
  switch(third) {
    case -1: fourth = third + factorn1.get(0); break;
    case 1: fourth = third + factor1.get(0); break;
    case 2: fourth = third + factor23.get(0); break;
    case 3: fourth = third + factor23.get(0); break;
    case 4: fourth = third + factor4.get(0); break;
    case -4: fourth = third + factorn4.get(0); break;
    case 5: fourth = third + factor5.get(0); break;
    case -5: fourth = third + factorn5.get(0); break;
    case 6: fourth = third + factor678.get(0); break;
    case 7: fourth = third + factor678.get(0); break;
    case 8: fourth = third + factor678.get(0); break;
    case 9: fourth = third + factor9.get(0); break;
    case -9: fourth = third + factorn9.get(0); break;
    case 10: fourth = third + factor10.get(0); break;
    case -10: fourth = third + factorn10.get(0); break;
    case 11: fourth = third + factor1112.get(0); break;
    case 12: fourth = third + factor1112.get(0); break;
    case 13: fourth = third + factor13.get(0); break;
    case -13: fourth = third + factorn13.get(0); break;
  }
  
  // Fifth Measure
  theShuffle();
  switch(fourth) {
    case -1: fifth = fourth + factorn1.get(0); break;
    case 1: fifth = fourth + factor1.get(0); break;
    case 2: fifth = fourth + factor23.get(0); break;
    case 3: fifth = fourth + factor23.get(0); break;
    case 4: fifth = fourth + factor4.get(0); break;
    case -4: fifth = fourth + factorn4.get(0); break;
    case 5: fifth = fourth + factor5.get(0); break;
    case -5: fifth = fourth + factorn5.get(0); break;
    case 6: fifth = fourth + factor678.get(0); break;
    case 7: fifth = fourth + factor678.get(0); break;
    case 8: fifth = fourth + factor678.get(0); break;
    case 9: fifth = fourth + factor9.get(0); break;
    case -9: fifth = fourth + factorn9.get(0); break;
    case 10: fifth = fourth + factor10.get(0); break;
    case -10: fifth = fourth + factorn10.get(0); break;
    case 11: fifth = fourth + factor1112.get(0); break;
    case 12: fifth = fourth + factor1112.get(0); break;
    case 13: fifth = fourth + factor13.get(0); break;
    case -13: fifth = fourth + factorn13.get(0); break;
  }
  
  // Sixth Measure
  theShuffle();
  switch(fifth) {
    case -1: sixth = fifth + factorn1.get(0); break;
    case 1: sixth = fifth + factor1.get(0); break;
    case 2: sixth = fifth + factor23.get(0); break;
    case 3: sixth = fifth + factor23.get(0); break;
    case 4: sixth = fifth + factor4.get(0); break;
    case -4: sixth = fifth + factorn4.get(0); break;
    case 5: sixth = fifth + factor5.get(0); break;
    case -5: sixth = fifth + factorn5.get(0); break;
    case 6: sixth = fifth + factor678.get(0); break;
    case 7: sixth = fifth + factor678.get(0); break;
    case 8: sixth = fifth + factor678.get(0); break;
    case 9: sixth = fifth + factor9.get(0); break;
    case -9: sixth = fifth + factorn9.get(0); break;
    case 10: sixth = fifth + factor10.get(0); break;
    case -10: sixth = fifth + factorn10.get(0); break;
    case 11: sixth = fifth + factor1112.get(0); break;
    case 12: sixth = fifth + factor1112.get(0); break;
    case 13: sixth = fifth + factor13.get(0); break;
    case -13: sixth = fifth + factorn13.get(0); break;
  }
  
  // Seventh Measure
  theShuffle();
  switch(sixth) {
    case -1: seventh = sixth + factorn1.get(0); break;
    case 1: seventh = sixth + factor1.get(0); break;
    case 2: seventh = sixth + factor23.get(0); break;
    case 3: seventh = sixth + factor23.get(0); break;
    case 4: seventh = sixth + factor4.get(0); break;
    case -4: seventh = sixth + factorn4.get(0); break;
    case 5: seventh = sixth + factor5.get(0); break;
    case -5: seventh = sixth + factorn5.get(0); break;
    case 6: seventh = sixth + factor678.get(0); break;
    case 7: seventh = sixth + factor678.get(0); break;
    case 8: seventh = sixth + factor678.get(0); break;
    case 9: seventh = sixth + factor9.get(0); break;
    case -9: seventh = sixth + factorn9.get(0); break;
    case 10: seventh = sixth + factor10.get(0); break;
    case -10: seventh = sixth + factorn10.get(0); break;
    case 11: seventh = sixth + factor1112.get(0); break;
    case 12: seventh = sixth + factor1112.get(0); break;
    case 13: seventh = sixth + factor13.get(0); break;
    case -13: seventh = sixth + factorn13.get(0); break;
  }
  
  // Eighth Measure
  theShuffle();
  switch(seventh) {
    case -1: eighth = seventh + factorn1.get(0); break;
    case 1: eighth = seventh + factor1.get(0); break;
    case 2: eighth = seventh + factor23.get(0); break;
    case 3: eighth = seventh + factor23.get(0); break;
    case 4: eighth = seventh + factor4.get(0); break;
    case -4: eighth = seventh + factorn4.get(0); break;
    case 5: eighth = seventh + factor5.get(0); break;
    case -5: eighth = seventh + factorn5.get(0); break;
    case 6: eighth = seventh + factor678.get(0); break;
    case 7: eighth = seventh + factor678.get(0); break;
    case 8: eighth = seventh + factor678.get(0); break;
    case 9: eighth = seventh + factor9.get(0); break;
    case -9: eighth = seventh + factorn9.get(0); break;
    case 10: eighth = seventh + factor10.get(0); break;
    case -10: eighth = seventh + factorn10.get(0); break;
    case 11: eighth = seventh + factor1112.get(0); break;
    case 12: eighth = seventh + factor1112.get(0); break;
    case 13: eighth = seventh + factor13.get(0); break;
    case -13: eighth = seventh + factorn13.get(0); break;
  }
  
  // Ninth Measure
  theShuffle();
  switch(eighth) {
    case -1: ninth = eighth + factorn1.get(0); break;
    case 1: ninth = eighth + factor1.get(0); break;
    case 2: ninth = eighth + factor23.get(0); break;
    case 3: ninth = eighth + factor23.get(0); break;
    case 4: ninth = eighth + factor4.get(0); break;
    case -4: ninth = eighth + factorn4.get(0); break;
    case 5: ninth = eighth + factor5.get(0); break;
    case -5: ninth = eighth + factorn5.get(0); break;
    case 6: ninth = eighth + factor678.get(0); break;
    case 7: ninth = eighth + factor678.get(0); break;
    case 8: ninth = eighth + factor678.get(0); break;
    case 9: ninth = eighth + factor9.get(0); break;
    case -9: ninth = eighth + factorn9.get(0); break;
    case 10: ninth = eighth + factor10.get(0); break;
    case -10: ninth = eighth + factorn10.get(0); break;
    case 11: ninth = eighth + factor1112.get(0); break;
    case 12: ninth = eighth + factor1112.get(0); break;
    case 13: ninth = eighth + factor13.get(0); break;
    case -13: ninth = eighth + factorn13.get(0); break;
  }
  
  // Tenth Measure
  theShuffle();
  switch(ninth) {
    case -1: tenth = ninth + factorn1.get(0); break;
    case 1: tenth = ninth + factor1.get(0); break;
    case 2: tenth = ninth + factor23.get(0); break;
    case 3: tenth = ninth + factor23.get(0); break;
    case 4: tenth = ninth + factor4.get(0); break;
    case -4: tenth = ninth + factorn4.get(0); break;
    case 5: tenth = ninth + factor5.get(0); break;
    case -5: tenth = ninth + factorn5.get(0); break;
    case 6: tenth = ninth + factor678.get(0); break;
    case 7: tenth = ninth + factor678.get(0); break;
    case 8: tenth = ninth + factor678.get(0); break;
    case 9: tenth = ninth + factor9.get(0); break;
    case -9: tenth = ninth + factorn9.get(0); break;
    case 10: tenth = ninth + factor10.get(0); break;
    case -10: tenth = ninth + factorn10.get(0); break;
    case 11: tenth = ninth + factor1112.get(0); break;
    case 12: tenth = ninth + factor1112.get(0); break;
    case 13: tenth = ninth + factor13.get(0); break;
    case -13: tenth = ninth + factorn13.get(0); break;
  }
  
  // Eleventh Measure
  theShuffle();
  switch(tenth) {
    case -1: eleventh = tenth + factorn1.get(0); break;
    case 1: eleventh = tenth + factor1.get(0); break;
    case 2: eleventh = tenth + factor23.get(0); break;
    case 3: eleventh = tenth + factor23.get(0); break;
    case 4: eleventh = tenth + factor4.get(0); break;
    case -4: eleventh = tenth + factorn4.get(0); break;
    case 5: eleventh = tenth + factor5.get(0); break;
    case -5: eleventh = tenth + factorn5.get(0); break;
    case 6: eleventh = tenth + factor678.get(0); break;
    case 7: eleventh = tenth + factor678.get(0); break;
    case 8: eleventh = tenth + factor678.get(0); break;
    case 9: eleventh = tenth + factor9.get(0); break;
    case -9: eleventh = tenth + factorn9.get(0); break;
    case 10: eleventh = tenth + factor10.get(0); break;
    case -10: eleventh = tenth + factorn10.get(0); break;
    case 11: eleventh = tenth + factor1112.get(0); break;
    case 12: eleventh = tenth + factor1112.get(0); break;
    case 13: eleventh = tenth + factor13.get(0); break;
    case -13: eleventh = tenth + factorn13.get(0); break;
  }
  
  // Twelfth Measure
  theShuffle();
  switch(eleventh) {
    case -1: twelfth = eleventh + factorn1.get(0); break;
    case 1: twelfth = eleventh + factor1.get(0); break;
    case 2: twelfth = eleventh + factor23.get(0); break;
    case 3: twelfth = eleventh + factor23.get(0); break;
    case 4: twelfth = eleventh + factor4.get(0); break;
    case -4: twelfth = eleventh + factorn4.get(0); break;
    case 5: twelfth = eleventh + factor5.get(0); break;
    case -5: twelfth = eleventh + factorn5.get(0); break;
    case 6: twelfth = eleventh + factor678.get(0); break;
    case 7: twelfth = eleventh + factor678.get(0); break;
    case 8: twelfth = eleventh + factor678.get(0); break;
    case 9: twelfth = eleventh + factor9.get(0); break;
    case -9: twelfth = eleventh + factorn9.get(0); break;
    case 10: twelfth = eleventh + factor10.get(0); break;
    case -10: twelfth = eleventh + factorn10.get(0); break;
    case 11: twelfth = eleventh + factor1112.get(0); break;
    case 12: twelfth = eleventh + factor1112.get(0); break;
    case 13: twelfth = eleventh + factor13.get(0); break;
    case -13: twelfth = eleventh + factorn13.get(0); break;
  }
}
1 Like

I believe we were too naïve to rely on offsets as a solution. :woozy_face:

A possible approach is to explicitly have an array of valid adjacents[] for each Hexagon value: :bulb:

// https://Discourse.Processing.org/t/
// pick-random-number-based-on-preceding-number/32558/7

// GoToLoop (2021/Oct/02)

static final byte[][] ADJACENTS = {
  { 2, 5, 6 }, // 1
  { 1, 3, 6, 7 }, // 2
  { 2, 4, 7, 8 }, // 3
  { 3, 8, 9 }, // 4
  { 1, 6, 10 }, // 5
  { 1, 2, 5, 7, 10, 11 }, // 6
  { 2, 3, 6, 8, 11, 12 }, // 7
  { 3, 4, 7, 9, 12, 13 }, // 8
  { 4, 8, 13 }, // 9
  { 5, 6, 11 }, // 10
  { 6, 7, 10, 12 }, // 11
  { 7, 8, 11, 13 }, // 12
  { 8, 9, 12 } // 13
};

final Hexagon[] hexagons = new Hexagon[ADJACENTS.length];

void setup() {
  createHexagons();
  printArray(hexagons);
  exit();
}

void createHexagons() {
  for (int i = 0; i < ADJACENTS.length; ++i)
    hexagons[i] = new Hexagon(i + 1, ADJACENTS[i]);
}

class Hexagon {
  int value;
  byte[] adjacents;

  Hexagon(final int val, final byte[] neighbors) {
    value = val;
    adjacents = neighbors;
  }

  boolean isNeighborOrSame(final int val) {
    return val == value? true : isNeighbor(val);
  }

  boolean isNeighbor(final int val) {
    for (final byte neighbor : adjacents)  if (val == neighbor)  return true;
    return false;
  }

  String toString() {
    return value + ": { " + join(str(adjacents), ", ") + " }";
  }
}
4 Likes

Ah, wonderful.

Which documentation would be best to read through to understand how to access these values? For example, if the first number is 6, then how do I randomly pick one of its adjacents from the array?

  1. select the list of available options from the array byte[] options = ADJACENTS[6]
  2. select a random value from the available options: byte newhex = options[(int)random(options.length)];

In that line, if there are 6 options (0-5), random(options.length) produces a random number 0-4.999, then rounds it to 0, 1, 2, 3, 4, 5. It then looks up options[#] with that number, and returns the value.

Like this (my example uses int rather than byte):

// based on sketch by GoToLoop
// https://discourse.processing.org/t/pick-random-number-based-on-preceding-number/32558/7

int[][] ADJACENTS = {
  { 2, 5, 6 }, // 1
  { 1, 3, 6, 7 }, // 2
  { 2, 4, 7, 8 }, // 3
  { 3, 8, 9 }, // 4
  { 1, 6, 10 }, // 5
  { 1, 2, 5, 7, 10, 11 }, // 6
  { 2, 3, 6, 8, 11, 12 }, // 7
  { 3, 4, 7, 9, 12, 13 }, // 8
  { 4, 8, 13 }, // 9
  { 5, 6, 11 }, // 10
  { 6, 7, 10, 12 }, // 11
  { 7, 8, 11, 13 }, // 12
  { 8, 9, 12 }, // 13
};

int hex = 6;
int[] options = ADJACENTS[hex-1];
// pick a random new hex 100 times
for(int i=0; i<100; i++) {
  int newhex = options[(int)random(options.length)];
  print(newhex, " ");
}
3 Likes

Well, I think the below is an improvement. I went from 500 lines of code to 200 lines and was able to add more to the canvas. I think this might be the best I can get with this at my level but as I keep learning, I hope I can find more efficient ways to code this interpretation of a '60s program!

Thanks all! @hotfooted @GoToLoop @jeremydouglass

IntList start = new IntList();
int ts = 35, txx = 135, txy = 325, fade = 145;
int hexSize = 40, xLoc = 250, yLoc = 75, xSpac = 69, ySpac = 60;
float txf = 2.75, r = PI/1.98;
String[] dancers = {"Dancer A", "Dancer B", "Dancer C", "Dancer D", "Dancer E", "Dancer F", "Dancer G", "Dancer H", "Dancer I", "Dancer J", "Dancer K", "Dancer L"};
int[][] ADJACENTS = {
  {0, 1, 5, 10}, // 0, Off Stage Left
  {0, 1, 2, 5, 6}, // 1
  {1, 2, 3, 6, 7}, //2
  {2, 3, 4, 7, 8}, //3
  {3, 4, 8, 9, 14}, //4
  {0, 1, 5, 6, 10}, //5
  {1, 2, 5, 6, 7, 10, 11}, //6
  {2, 3, 6, 7, 8, 11, 12}, //7
  {3, 4, 7, 8, 9, 12, 13}, //8
  {4, 8, 9, 13, 14}, //9
  {0, 5, 6, 10, 11}, //10
  {6, 7, 10, 11, 12}, //11
  {7, 8, 11, 12, 13}, //12
  {8, 9, 12, 13, 14}, //13
  {4, 9, 13, 14}, // 14, Off Stage Right
};

void setup() {
  size(1280, 720);
  background(255);

  spatialScore();
  onstageHex();
  offstageHex();
  hexagonText();
  otherText();
  instructions();
}

void spatialScore() {
  start.append(new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14});

  fill(0);
  for (int i = 0; i < 12; i++) {
    start.shuffle();
    int mes1 = start.get(0); // hexagon location for measure one
    int[] mes2get = ADJACENTS[mes1]; // retrieves number from previous measure to produce same or adjacent number for current measure
    int mes2 = mes2get[(int)random(mes2get.length)]; // hexagon location for measure two
    int[] mes3get = ADJACENTS[mes2]; // retrieves number from previous measure to produce same or adjacent number for current measure
    int mes3 = mes3get[(int)random(mes3get.length)]; // hexagon location for measure three and so on for the rest
    int[] mes4get = ADJACENTS[mes3];
    int mes4 = mes4get[(int)random(mes4get.length)];
    int[] mes5get = ADJACENTS[mes4];
    int mes5 = mes5get[(int)random(mes5get.length)];
    int[] mes6get = ADJACENTS[mes5];
    int mes6 = mes6get[(int)random(mes6get.length)];
    int[] mes7get = ADJACENTS[mes6];
    int mes7 = mes7get[(int)random(mes7get.length)];
    int[] mes8get = ADJACENTS[mes7];
    int mes8 = mes8get[(int)random(mes8get.length)];
    int[] mes9get = ADJACENTS[mes8];
    int mes9 = mes9get[(int)random(mes9get.length)];
    int[] mes10get = ADJACENTS[mes9];
    int mes10 = mes10get[(int)random(mes10get.length)];
    int[] mes11get = ADJACENTS[mes10];
    int mes11 = mes11get[(int)random(mes11get.length)];
    int[] mes12get = ADJACENTS[mes11];
    int mes12 = mes12get[(int)random(mes12get.length)];

    text(dancers[i], txx - 15 + ts * (i * txf), txy - 25);
    text(mes1, txx + ts * (i * txf), txy);
    text(mes2, txx + ts * (i * txf), txy + ts);
    text(mes3, txx + ts * (i * txf), txy + ts * 2);
    text(mes4, txx + ts * (i * txf), txy + ts * 3);
    text(mes5, txx + ts * (i * txf), txy + ts * 4);
    text(mes6, txx + ts * (i * txf), txy + ts * 5);
    text(mes7, txx + ts * (i * txf), txy + ts * 6);
    text(mes8, txx + ts * (i * txf), txy + ts * 7);
    text(mes9, txx + ts * (i * txf), txy + ts * 8);
    text(mes10, txx + ts * (i * txf), txy + ts * 9);
    text(mes11, txx + ts * (i * txf), txy + ts * 10);
    text(mes12, txx + ts * (i * txf), txy + ts * 11);
  }
}

void polygon(float x, float y, float radius, int npoints) {
  float angle = TWO_PI / npoints;
  beginShape();
  for (float a = 0; a < TWO_PI; a += angle) {
    float sx = x + cos(a) * radius;
    float sy = y + sin(a) * radius;
    vertex(sx, sy);
  }
  endShape(CLOSE);
}

void onstageHex() {
  noFill();
  for (int x = xLoc; x < xLoc + xSpac * 4; x += xSpac) { // Downstage Row of Hexagons
    pushMatrix();
    translate(x, yLoc);
    rotate(r);
    polygon(0, 0, hexSize, 6);
    popMatrix();
  }

  for (int x = xLoc - 34; x < xLoc + xSpac * 4; x += xSpac) { // Midstage Row of Hexagons
    pushMatrix();
    translate(x, yLoc + ySpac);
    rotate(r);
    polygon(0, 0, hexSize, 6);
    popMatrix();
  }

  for (int x = xLoc; x < xLoc + xSpac * 4; x += xSpac) { // Upstage Row of Hexagons
    pushMatrix();
    translate(x, yLoc + ySpac * 2);
    rotate(r);
    polygon(0, 0, hexSize, 6);
    popMatrix();
  }
}

void offstageHex() {
  stroke(fade);
  noFill();

  pushMatrix();
  translate(xLoc - hexSize - 30, yLoc); // Stage Left of 10
  rotate(r);
  polygon(0, 0, hexSize, 6);
  popMatrix();

  pushMatrix();
  translate(xLoc + 1 + xSpac * 4, yLoc); // Stage Right of 13
  rotate(r);
  polygon(0, 0, hexSize, 6);
  popMatrix();

  pushMatrix();
  translate(xLoc - hexSize - 64, yLoc + ySpac); // Stage Left of 5
  rotate(r);
  polygon(0, 0, hexSize, 6);
  popMatrix();

  pushMatrix();
  translate(xLoc + 36 + xSpac * 4, yLoc + ySpac); // Stage Right of 9
  rotate(r);
  polygon(0, 0, hexSize, 6);
  popMatrix();

  pushMatrix();
  translate(xLoc - hexSize - 30, yLoc + ySpac * 2); // Stage Left of 1
  rotate(r);
  polygon(0, 0, hexSize, 6);
  popMatrix();

  pushMatrix();
  translate(xLoc + 1 + xSpac * 4, yLoc + ySpac * 2); // Stage Right of 4
  rotate(r);
  polygon(0, 0, hexSize, 6);
  popMatrix();
}

void hexagonText() {
  fill(0);
  for (int i = 0; i < 4; i++) {
    text(i + 1, (xLoc - 3) + xSpac * i, yLoc + 3 + ySpac * 2);
    text(i + 10, (xLoc - 8) + xSpac * i, yLoc + 3);
  }

  for (int i = 0; i < 5; i++) {
    text(i + 5, (xLoc - 37) + xSpac * i, yLoc + 3 + ySpac);
  }

  fill(fade);
  text("0", xLoc - hexSize - 33, yLoc + 5); // Stage Left of 10
  text("14", xLoc + xSpac * 4 - 8, yLoc + 5); // Stage Right of 13
  text("0", xLoc - hexSize - 33 - 34, yLoc + ySpac + 5); // Stage Left of 5
  text("14", xLoc + 34 + xSpac * 4 - 8, yLoc + ySpac + 5); // Stage Right of 9
  text("0", xLoc - hexSize - 33, yLoc + ySpac * 2 + 5); // Stage Left of 1
  text("14", xLoc + xSpac * 4 - 8, yLoc + ySpac * 2 + 5); // Stage Right of 4
}

void otherText() {
  fill(0);
  text("Measure", 30, 300);
  for (int i = 0; i < 12; i++) {
    text(i + 1, 50, txy + ts * i);
  }

  text("Downstage", 115 + xSpac * 3, 20);
  text("Upstage", 120 + xSpac * 3, yLoc + 60 + ySpac * 2);
  text("Stage Right", 620, 140);
  text("Stage Left", 30, 140);
}

void instructions() {
  int x = width / 2 + 90;
  int y = 50;
  noFill();
  rect(x - 15, 0, x, y * 5.5);
  fill(0);
  line(x, y - 23, x + 140, y - 23);
  line(0, height / 2 - 55, width, height / 2 - 55);
  text("Credits and Instructions", x, y - 25);
  text("Reproduction of a program by Francisco Sagasti (March 14, 1968 at PSU.)", x, y);
  text("Originally coded using Fortran IV programming language and reinterpreted using\nProcessing 4.0b1 with the support of hotfooted, GoToLoop, and jeremydouglass.", x, y * 2);
  text("Hexagons labelled 1 to 13 represents a location onstage. O and 14 represent the offstage.", x, y * 3);
  text("Each dancer will occupy a hexagon as noted in their column. Each row represents a measure.", x, y * 4);
  text("Dancers can do any movement, interact with others in any way. This is a 'spatial score.'", x, y * 5);
}
3 Likes

nice work. a very interesting program too. best of luck with it all :slight_smile:

I’m assuming you were never exposed to the Object-Oriented Programming (OOP) paradigm, right?

I guess you’ve meant my class Hexagon, is it?

In Java we rely on the . dot access operator in order to access a member of a class:

Let’s say you wanna read the field value from the Hexagon instance on index 4 of array hexagons[]:
println(hexagons[4].value);
The statement above will log the value 5.

Another example, reading the field array adjacents[] from the Hexagon instance on index 8:
println(hexagons[8].adjacents);

We’ll see the following values below logged:

[0] 4
[1] 8
[2] 13

For another way to understand OOP and classes read this article below:

I did another example w/ 2 classes: Hexagon & Dancer:

The new class Dancer has a field named floor which stores the current Hexagon it’s stepping in.

It has a method randomMove() which attempts to move into a random() Hexagon adjacent to its current 1 by invoking Hexagon::isNeighborOrSame() method in a do/while () loop until the random value is valid.

I hope you may understand how the interaction between those 2 classes work:

/**
 * Hexagon Dancers (v1.0.2)
 * GoToLoop (2021/Oct/03)
 *
 * https://Discourse.Processing.org/t/
 * pick-random-number-based-on-preceding-number/32558/13
 *
 * https://OpenProcessing.org/sketch/1292231
 */

static final byte[][] ADJACENTS = {
  { 2, 5, 6 }, // 1
  { 1, 3, 6, 7 }, // 2
  { 2, 4, 7, 8 }, // 3
  { 3, 8, 9 }, // 4
  { 1, 6, 10 }, // 5
  { 1, 2, 5, 7, 10, 11 }, // 6
  { 2, 3, 6, 8, 11, 12 }, // 7
  { 3, 4, 7, 9, 12, 13 }, // 8
  { 4, 8, 13 }, // 9
  { 5, 6, 11 }, // 10
  { 6, 7, 10, 12 }, // 11
  { 7, 8, 11, 13 }, // 12
  { 8, 9, 12 } // 13
};

final Hexagon[] hexagons = new Hexagon[ADJACENTS.length];

static final int DANCERS = 2, TXT_SIZE = 050, FPS = 1;
final Dancer[] dancers = new Dancer[DANCERS];

static final boolean JAVA = 1/2 != 1/2.;

void setup() {
  size(400, 300);
  frameRate(FPS);

  textSize(TXT_SIZE);
  textAlign(CENTER, CENTER);

  createHexagons();
  createDancers();

  if (JAVA) {
    printArray(hexagons);
    println();
    printArray(dancers);
    println();
  }
}

void draw() {
  background(0);
  for (final Dancer dancer : dancers)  dancer.randomMove().display();

  print(dancers);
  println("\tFrame: " + frameCount);
}

void createHexagons() {
  for (int i = 0; i < ADJACENTS.length; ++i)
    hexagons[i] = new Hexagon(i + Hexagon.LOWEST, ADJACENTS[i]);
}

void createDancers() {
  final int w = width, h = height;
  final int dim = h >> 1, cy = h - dim >> 1, off = 30;
  final color red = #FF0000, blue = #0000FF, yellow = #FFFF00;

  int idx;

  idx = (int) random(ADJACENTS.length);
  dancers[0] = new Dancer(hexagons[idx], off, cy, dim, red, yellow);

  idx = (int) random(ADJACENTS.length);
  dancers[1] = new Dancer(hexagons[idx], w - dim - off, cy, dim, blue, yellow);
}

class Hexagon {
  static final int LOWEST = 1, HIGHEST = 13;

  int value;
  byte[] adjacents;

  Hexagon(final int val, final byte[] neighbors) {
    value = val;
    adjacents = neighbors;
  }

  boolean isNeighborOrSame(final int val) {
    return val == value? true : isNeighbor(val);
  }

  boolean isNeighbor(final int val) {
    for (final byte neighbor : adjacents)  if (val == neighbor)  return true;
    return false;
  }

  String toString() {
    return value + ": { " + join(str(adjacents), ", ") + " }";
  }
}

class Dancer {
  Hexagon floor;
  int x, y, dim;
  color floorColor, textColor;

  Dancer(
    final Hexagon tile, 
    final int px, final int py, final int diam, 
    final color squareColor, final color txtColor
    )
  {
    floor = tile;
    x = px;
    y = py;
    dim = diam;
    floorColor = squareColor;
    textColor = txtColor;
  }

  Dancer randomMove() {
    int val;

    //do val = (int) random(Hexagon.LOWEST, Hexagon.HIGHEST + 1);
    //while (!floor.isNeighborOrSame(val));

    while (!floor.isNeighborOrSame(
      val = (int) random(Hexagon.LOWEST, Hexagon.HIGHEST + 1)));

    floor = hexagons[val - Hexagon.LOWEST];

    return this;
  }

  Dancer display() {
    fill(floorColor);
    rect(x, y, dim, dim);

    fill(textColor);
    text(floor.value, x + dim/2, y + dim/2);

    return this;
  }

  String toString() {
    return "Floor: " + floor.value;
  }
}