Need help with Twister game with changing rules i.e if statements

Hi,

I am new to processing and I have written this code for a easy twister game. Now I want to change the rules so that the instruction like for example left hand floor does not repeat. So basically altering the random function. This code has two tabs one for the player see below.

Does anyone have an idea how to alter the rules for the random function?

Thanks in advance

Regards from Copenhagen

Jacob

PFont mFont;
int mouseClicks;

String[] bodyPart;// = {"right hand", "right foot", "left foot", "left hand"};
String[] Colour = {"red", "blue", "green", "yellow"};
String[] Plane;

final int AIR = 0;
final int FLOOR = 1;
final int WALL = 2;
final int NUMBER_OF_PLANES = 3;

final int RIGHT_HAND = 0;
final int RIGHT_FOOT = 1;
final int LEFT_FOOT = 2;
final int LEFT_HAND = 3;
final int NUMBER_OF_BODYPARTS = 4;

color mBackground;
Player mPlayer;

int mCurrentPlaneID;
int mCurrentBodyPartID;

void setup() {
  size (600, 1000);
  mFont = createFont ("HelveticaNeue", 36);

  bodyPart = new String[NUMBER_OF_BODYPARTS];
  bodyPart[RIGHT_HAND] = "right hand";
  bodyPart[RIGHT_FOOT] = "right foot";
  bodyPart[LEFT_FOOT] = "left foot";
  bodyPart[LEFT_HAND] = "left hand";

  Plane = new String[NUMBER_OF_PLANES];
  Plane[AIR] = "air";
  Plane[FLOOR] = "floor";
  Plane[WALL] = "wall";

  mPlayer = new Player();
  mBackground = color(50);
}

void draw() {
  background(mBackground);
  textFont(mFont);
  fill(50);
  textAlign(LEFT);
  textSize (70);
  text(mouseClicks+"", 20, 10, width/2, height);

  textSize(10);
  text("COUNT", 20, 100);

  textAlign(CENTER);
  textSize(70);
  text(bodyPart[mCurrentBodyPartID], width/1.5, height*0.5);
  text(Plane[mCurrentPlaneID], width/2, height*0.75);
}

void mouseClicked() {
  int colourInput = int(random(Colour.length));
  if (Colour[colourInput].equals("red")) {
    mBackground = color(255, 0, 131);
  } else if (Colour[colourInput].equals("green"))
  {
    mBackground = color(47, 155, 27);
  } else if (Colour[colourInput].equals("blue"))
  {
    mBackground = color(27, 84, 155);
  } else if (Colour[colourInput].equals("yellow"))
  {
    mBackground = color(255, 231, 81);
  }

  do {
    mCurrentBodyPartID = int(random(NUMBER_OF_BODYPARTS));
    mCurrentPlaneID = int(random(NUMBER_OF_PLANES));
  } while (!isCombinationOK());
  
  handlePlayer();

  if (mouseButton == LEFT) {
    mouseClicks++;
  } else { 
    mouseClicks = 0;
  }
  //println (bodyPart[bodyInput], Colour [colourInput], Plane [planeInput]);
}

boolean isCombinationOK() {
  return true;
}

void handlePlayer() {
  mPlayer.bodypart[mCurrentBodyPartID] = mCurrentPlaneID;
  mPlayer.print();
}

New tab: 

class Player {
  int[] bodypart;

  Player() {
    bodypart = new int[NUMBER_OF_BODYPARTS];
    bodypart[RIGHT_HAND] = AIR;
    bodypart[LEFT_HAND] = AIR;
    bodypart[RIGHT_FOOT] = AIR;
    bodypart[LEFT_FOOT] = AIR;
  }

  void print() {
    println("---");
    for (int i=0; i < bodypart.length; i++) {
      println(bodyPart[i] + "\t: " + Plane[bodypart[i]]);
    }
    println("---");
  }
}
1 Like

is there a reason you have a while loop with a conditional that will always be true? a solution to your random selection problem without repetition might be to have an arraylist which you get (and remove) items from until empty and then refill. this avoids repetitions.

Thanks for your answer :slight_smile:
Yes we thought we can use the while loop to not trigger some repetition. But maybe that was wrong… not sure how to use the array list, but i will read up on it :wink:

you could do something like this. i haven’t fully tested it and it’s not real clean but i’ll leave that upto you.

PFont mFont;
int mouseClicks;

String[] bodyPart;// = {“right hand”, “right foot”, “left foot”, “left hand”};
String[] Colour = {"red", "blue", "green", "yellow"};
String[] Plane;

final int AIR = 0;
final int FLOOR = 1;
final int WALL = 2;
final int NUMBER_OF_PLANES = 3;

final int RIGHT_HAND = 0;
final int RIGHT_FOOT = 1;
final int LEFT_FOOT = 2;
final int LEFT_HAND = 3;
final int NUMBER_OF_BODYPARTS = 4;


ArrayList<Integer> bodyPartSelectionArr = new ArrayList<Integer>();
ArrayList<Integer> planeSelectionArr = new ArrayList<Integer>();

color mBackground;
Player mPlayer;

int mCurrentPlaneID;
int mCurrentBodyPartID;

void setup() {
  size (600, 600);
  mFont = createFont ("Arial", 36);

  bodyPart = new String[NUMBER_OF_BODYPARTS];
  bodyPart[RIGHT_HAND] = "right hand";
  bodyPart[RIGHT_FOOT] = "right foot";
  bodyPart[LEFT_FOOT] = "left foot";
  bodyPart[LEFT_HAND] = "left hand";

  Plane = new String[NUMBER_OF_PLANES];
  Plane[AIR] = "air";
  Plane[FLOOR] = "floor";
  Plane[WALL] = "wall";

  mPlayer = new Player();
  mBackground = color(50);
}

void draw() {
  background(mBackground);
  textFont(mFont);
  fill(50);
  textAlign(LEFT);
  textSize (70);
  text(mouseClicks+"", 20, 10, width/2, height);

  textSize(10);
  text("COUNT", 20, 100);

  textAlign(CENTER);
  textSize(70);
  text(bodyPart[mCurrentBodyPartID], width/1.5, height * 0.5);
  text(Plane[mCurrentPlaneID], width/2, height * 0.75);
}

void refillBodyPartSelectionArr() {
  for(int i = 0; i < NUMBER_OF_BODYPARTS; i++) {
      if(bodyPartSelectionArr.indexOf(i) == -1) {   
        bodyPartSelectionArr.add(i);
      }
    }
}

void refillPlaneSelectionArr() {
  for(int i = 0; i < NUMBER_OF_PLANES; i++) {
       if(planeSelectionArr.indexOf(i) == -1) {   
        planeSelectionArr.add(i);
       }
     }
}

void mouseClicked() {
  int colourInput = int(random(Colour.length));
  if (Colour[colourInput].equals("red")) {
    mBackground = color(255, 0, 131);
  } else if (Colour[colourInput].equals("green"))
  {
    mBackground = color(47, 155, 27);
  } else if (Colour[colourInput].equals("blue"))
  {
    mBackground = color(27, 84, 155);
  } else if (Colour[colourInput].equals("yellow"))
  {
    mBackground = color(255, 231, 81);
  }

  if(bodyPartSelectionArr.size() <= 1) {
    refillBodyPartSelectionArr();
  }
  if(planeSelectionArr.size() <= 1) {
     refillPlaneSelectionArr();
  }

  //select a random index of each arraylist (bodyPart and plane)
  int bodyPartSelectionIndex = int(random(bodyPartSelectionArr.size()));
  int planeSelectionIndex = int(random(planeSelectionArr.size()));
  //set the current bodyPart and plane
  mCurrentBodyPartID = bodyPartSelectionArr.remove(bodyPartSelectionIndex);
  mCurrentPlaneID = planeSelectionArr.remove(planeSelectionIndex);

  handlePlayer();

  if (mouseButton == LEFT) {
    mouseClicks++;
  } else {
    mouseClicks = 0;
  }
  //println (bodyPart[bodyInput], Colour [colourInput], Plane [planeInput]);
}

boolean isCombinationOK() {
  return true;
}

void handlePlayer() {
  mPlayer.bodypart[mCurrentBodyPartID] = mCurrentPlaneID;
  mPlayer.print();
}

class Player {
  int[] bodypart;

  Player() {
    bodypart = new int[NUMBER_OF_BODYPARTS];
    bodypart[RIGHT_HAND] = AIR;
    bodypart[LEFT_HAND] = AIR;
    bodypart[RIGHT_FOOT] = AIR;
    bodypart[LEFT_FOOT] = AIR;
  }

  void print() {
    println("—");
    for (int i=0; i < bodypart.length; i++) {
      println(bodyPart[i] + "\t: " + Plane[bodypart[i]]);
    }
    println("—");
  }
}
1 Like

Perfect. That worked. :slight_smile: Thanks a tone! Have tried to do this for 2 days

I was also thinking of incorporating the log to the screen. So that the program knows if one leg is on the wall the second leg shouldn’t instruct the player to go to the wall. So no hand stands :wink: , as some combination will be impossible to perform. Any idea to tell the program to with a DO NOT or if (function) to not put leg on wall if the other leg is already on the wall. I was playing around with the println to track the previous steps. Maybe any suggestion how to approach that?

One easy way to do this is to validate your instruction against your current state using a list of rules.

So, you generate an instruction:

RIGHT_FOOT=WALL

Then, before applying it, your validator checks the current state:

RIGHT_HAND=AIR
LEFT_HAND=FLOOR
LEFT_FOOT=WALL

and asks if adding the proposed new instruction would violate any rules?

if(LEFT_FOOT==WALL && RIGHT_FOOT==WALL) return false; // actually mPlayer.bodypart[LEFT_FOOT] ...
if(LEFT_FOOT==AIR && RIGHT_FOOT==AIR) return false;
if( ... ) return false;
return true;

If your rule is valid, update the current state and let the player know about the new rule.

1 Like