Please, forgive my ignorance, as I am new to Java programming. However, I need to show a picture (at random) for each of the three behaviours listed, below. Each picture has a designated image - What would be the best method to do so?
String whatsUp()
{
double r;
int myNumber;
String behaviour="";
r = Math.random();
myNumber = (int) (r * 3.0)+1;
switch(myNumber)
{
case 1:
behaviour = "reading";
break;
case 2:
behaviour = "surfing the web";
break;
case 3:
behaviour = "interacting with other students";
break;
}
return behaviour;
}
}
First of all, your process to get a random number doesn't make a lot of sense. What you'll want to to is create a new random object "r":
Random r = new Random();
Then you can use this object to create a random number from zero to a certain index. In your case this would be three.
int randomNumber = r.nextInt(index); //replace index with three
However, this would give the numbers 0, 1, and 2 so you will want to add one to the number.
int randomNumber = r.nextInt(index) + 1;
This will now give you a random number from one to three.
To get three images into the system you could use ImageIcon or similar method, which I will let you figure out for yourself.
I would then put the ImageIcons inside an ArrayList so that they can be easily accessed like so:
ArrayList<ImageIcon> images = new ArrayList<ImageIcon>();
images.add(imageOne);
images.add(imageTwo);
images.add(imageThree);
Thus, when inside case 1, 2, or 3 you could have a reference to the ArrayList you created with the first random number you you created like this
selectedImage = images.get(r); // the random number acts as the index
This will not display any image; you will have to work out how to do that yourself, but hopefully this gives you a good idea of where to go from here.
Related
Before I start I want to state that I am learning, I am completely new. Here i have added as much detail as possible.
So, I have an array of textures of different colors, and set a Random to randomize the textures, Like this:
Texture[] bubbles;
Random random = new Random();
int lowRange = 0;
int highRange = 3;
int result = random.nextInt(highRange -lowRange) + 1; //my random
ArrayList<Integer> BubbleXs = new ArrayList<>();
ArrayList<Integer> BubbleYs = new ArrayList<>();
#Override
public void create () {
bubbles = new Texture[4];
bubbles[0] = new Texture("blue.png");
bubbles[1] = new Texture("red.png");
bubbles[2] = new Texture("green.png");
bubbles[3] = new Texture("yellow.png");
}
Then I proceed to draw the texture at a random color falling from the top of the screen using a for loop, like this:
#Override
public void render () {
if (BubbleCount < 120) {
BubbleCount++;
} else {
BubbleCount = 0;
makeBubble();
}
public void makeBubble () {
float width = random.nextFloat() * Gdx.graphics.getWidth();
BubbleXs.add((int)width);
BubbleYs.add(Gdx.graphics.getHeight());
}
for (int i=0; i < BubbleYs.size(); i++) {
batch.draw(bubbles[result], BubbleXs.get(i), BubbleYs.get(i));
BubbleYs.set(i, BubbleYs.get(i) -4);
}
and it draws the textures at a a random perfectly, but only once, when its created, I want them to be a new random each time its looped, so its a different one every time one falls. why is it not doing that? what am I missing?
Thanks in advance!
Edit: I checked out this post: Change texture with random
but its not really helping any.
The reason they're all the same is that you assign a value to result only once, when it is initialized, and you never change it. If you want it to change, you need to use your Random to assign another value.
Your formula random.nextInt(highRange -lowRange) + 1 isn't right if you're wanting a random number between lowRange and highRange inclusive. That's giving you a number between lowRange + 1 and highRange + 1. The correct formula would be random.nextInt(highRange - lowRange) + lowRange.
The way to solve this would be create an additional variable for each bubble that stores the random int. You are already keeping a list for each of the two variables you're already storing (x and y). You could theoretically add a third, but it's to the point where you really just need to create a class for each bubble, so you can expand it easily if you add more features.
class Bubble {
int x;
int y;
int textureIndex;
}
Then replace your two array lists with:
ArrayList<Bubble> bubbles = new ArrayList<>();
And your makeBubble method should look like this:
void makeBubble(){
Bubble bubble = new Bubble();
bubble.x = (int)(random.nextFloat() * Gdx.graphics.getWidth());
bubble.y = Gdx.graphics.getHeight();
bubble.textureIndex = random.nextInt(3);
}
And your for loop for drawing them would look like this. I changed your textures array name here to bubbleTextures so bubbles can be used for the list of Bubble objects.
for (Bubble bubble : bubbles) {
batch.draw(bubbleTextures[bubble.textureIndex], bubble.x, bubble.y);
bubble.y -= 4;
}
There are numerous other issues I'm seeing with your code, but I think it would be overwhelming to explain them all. This at least gets you going in the right direction.
I'm trying to write a random character using robot.keyPress.
So far I've opened the notepad, wrote in it and saved it. If I run this program in a loop it would always save the notepad with the same name and therefore replacing the previous one.
I want to save multiple notepads(with different names) possibly by typing a random letter before saving it.
To have Robot perform a random keypress in a quick and dirty fashion, you'll want to first make a list of acceptable KeyEvent constants (a-zA-Z0-9, etc.) Assuming you put that list together:
int[] keys = new int[]{KeyEvent.VK_A, KeyEvent.VK_B, ... }; // Your list of KeyEvent character constants here, adapt as desired.
// Start optional for loop here if you want more than 1 random character
int randomValue = ThreadLocalRandom.current().nextInt(0, keys.length);
Robot.keyPress(keys[randomValue]);
Tweak to your needs.
This question is not so much asbout java.awt.robot but more about random value generation. A simplke solution could be this.
Random rnd = new Random();
int key = KeyEvent.VK_UNDEFINED;
while (key < KeyEvent.VK_A || key > KeyEvent.VK_Z) {
key = rnd.nextInt();
}
robot.keyPress(key);
To avoid useless looping use this:
Random rnd = new Random();
final int range = (KeyEvent.VK_Z + 1) - KeyEvent.VK_A;
int key = Math.abs(rnd.nextInt()) % range;
robot.keyPress(key);
I'm making game, and the game is based on shuffled tab[] of Integers. Every level of game takes array with different parameters (scope of numbers is changing) and an integer for let's say length of level. For now, I made arrayFatory class which makes that arrays with given parameters.
In code there are made 6 levels and they are represented by 6 arrayFactory objects which are assigned to currentArray. The currentArray is an array chosen to be "the current for that level" by switch case. And the cases are integers determining length of levels.
array1 = new RandomArrayFactory(3, 100);
array2 = new RandomArrayFactory(101, 200);
array3 = new RandomArrayFactory(201, 310);
array4 = new RandomArrayFactory(396, 720);
array5 = new RandomArrayFactory(721, 999);
array5 = new RandomArrayFactory(1000, 1310);
array6 = new RandomArrayFactory(1396, 2000);
switch (scoreCount) {
case 0:
progressScope = 13;
currentArray = array1.getNumbertab();
break;
case 13:
progressScope = 31;
currentArray = array2.getNumbertab();
break;
case 44:
progressScope = 56;
currentArray = array3.getNumbertab();
break;
case 100:
progressScope = 106;
currentArray = array4.getNumbertab();
break;
case 206:
progressScope = 214;
currentArray = array5.getNumbertab();
break;
case 420:
progressScope = currentArray.length;
currentArray = array6.getNumbertab();
break;
}
as you can see there is a lot of hardcoded variables and this is what I want to change. I would like to have kind of class with constructor that takes tab with scopes for every level and "progressScope" int, which I could use in place where currentArray is doing it's job.
And it is possible for me only when there is final amount of levels, then I could just copy that switch statement to my new class and return tab and int. But I would like to have possibility of defining new levels on as simple way as I can, I believe the simplest way would be the constructor that takes tab[][][] parameter, two first are values for arrayScope and second one for progressScope.
But how to make body of method so flexible to carry variable amount of levels to create? Or maybe my thinking is totally wrong and I should made it totally different? I'm not looking for specific answers, rather some tips or conceptions
To be able to add/remove any new levels, you should replace the switch with hardcoded values by a loop with a Collection.
Actually you choose a level according to the score count and you associate some information to your level (progressScope, numberTab).
This approach seems to have a drawback. It supposes that the actual score reaches exactly the score associated to each level. But how to handle if the current score exceeds a score corresponding to a level without never be equal to ?
So a switch that performs a perfect matching (equals) is so maybe not the more suitable solution.
As alternative, I propose you to define a List of Level ordered by descending score where Level will contain all information to represent a Level (core level data but also side but useful information as progressScope, numberTab and requiredScore).
You could create your levels in this way :
List<Level> levels = new ArrayList<>();
levels.add(new Level(3, 100, 0, 13));
levels.add(new Level(201, 310, 13, 31));
and introduce a method to retrieve a Level "matching" to a score:
public Level findLevel(List<Level> levels, int score) {
for (Level level : levels) {
if (score >= level.getRequiredScore()) {
return level;
}
}
throw new RuntimeException("should not come here !");
}
Now you can invoke it:
Level currentLevel = findLevel(levels, currentScore);
progressScope = currentLevel.getProgressScope();
currentArray = currentLevel.getCurrentArray();
So I'm working on a program which is supposed to randomly put people in 6 rooms (final input is the list of rooms with who is in each room). So I figured out how to do all that.
//this is the main sorting sequence:
for (int srtM = 0; srtM < Guys.length; srtM++) {
done = false;
People newMove = Guys[srtM]; //Guys is an array of People
while (!done) {
newMove.rndRoom(); //sets random number from 4 to 6
if (newMove.getRoom() == 4 && !room4.isFull()) {
room4.add(newMove); //adds person into the room4 object rList
done = true;
} else if (newMove.getRoom() == 5 && !room5.isFull()) {
room5.add(newMove);
done = true;
} else if (newMove.getRoom() == 6 && !room6.isFull()) {
room6.add(newMove);
done = true;
}
}
The problem now is that the code for reasons I don't completely understand (something with the way I wrote it here) is hardly random. It seems the same people are put into the same rooms almost every time I run the program. For example me, I'm almost always put by this program into room 6 together with another one friend (interestingly, we're both at the end of the Guys array). So how can I make it "truly" random? Or a lot more random than it is now?
Thanks in advance!
Forgot to mention that "rndRoom()" does indeed use the standard Random method (for 4-6) in the background:
public int rndRoom() {
if (this.gender == 'M') {
this.room = (rnd.nextInt((6 - 4) + 1)) + 4;
}
if (this.gender == 'F') {
this.room = (rnd.nextInt(((3 - 1) + 1))) + 1;
}
return this.room;
}
if you want it to be more random try doing something with the Random method, do something like this:
Random random = new Random();
for (int i = 0; i < 6; i++)
{
int roomChoice = random.nextInt(5) + 1;
roomChoice += 1;
}
of course this is not exactly the code you will want to use, this is just an example of how to use the Random method, change it to how you want to use it.
Also, the reason I did random.nextInt(5) + 1; is because if random.nextInt(5) + 1; gets you a random number from 0 to 5, so if you want a number from 1 to 6 you have to add 1, pretty self explanatory.
On another note, to get "truly" random is not as easy as it seems, when you generate a "random" number it will use something called Pseudo random number generation, this, is basically these programs produce endless strings of single-digit numbers, usually in base 10, known as the decimal system. When large samples of pseudo-random numbers are taken, each of the 10 digits in the set {0,1,2,3,4,5,6,7,8,9} occurs with equal frequency, even though they are not evenly distributed in the sequence.
There might be something wrong with code you didn't post.
I've build a working example with what your classes might be, and it is distributing pretty randomly:
http://pastebin.com/u8sZRxi6
OK so I figured out why the results don't seem very random. So the room sorter works based on an alphabetical people list of 18 guys. There are only 3 guy rooms (rooms 4, 5 and 6) So each guy has a 1 in 3 chance to be put in say, room 6. But each person could only possibly be in 2 of the 6 spots in each room (depending on where they are in the list).
The first two people for example, could each only be in either the first or second spot of each room. By "spot" I mean their place in the room list which is printed in the end. Me on the other hand am second last on the list, so at that point I could only be in either the last or second last spot of each room.
Sorry if it's confusing but I figured out this is the reason the generated room lists don't appear very random - it's because only the same few people could be put in each room spot every time. The lists are random though, it's just the order in which people appear in each list which is not random.
So in order to make the lists look more random I had to make people's positions in the room random too. So the way I solved this is by adding a shuffler action which mixes the Person arrays:
public static void shuffle(Person[] arr) {
Random rgen = new Random();
for (int i = 0; i < arr.length; i++) {
int randPos = rgen.nextInt(arr.length);
Person tmp = arr[i];
arr[i] = arr[randPos];
arr[randPos] = tmp;
}
}
TL;DR the generated room lists were random - but since the order of the people that got put into the rooms wasn't random the results didn't look very random. In order to solve this I shuffled the Person arrays.
static int n = -1;
private static int repeatBuffer[] = new int[10];
static {
repeatBuffer[0] = 0;
//and more
repeatBuffer[9] = 9;
}
static public void randomize() {
do {
Random r = new Random();
randomNumber = r.nextInt(20);
} while (!uniqueInt(randomNumber));
Log.e(TAG, "" + randomNumber); //here I need have a unique int
}
private static Boolean uniqueInt(int random) {
for (int i = 0; i < 9; i++) {
if (random == repeatBuffer[i]) {
return false;
}
}
if (++n > 9)
n = 0;
repeatBuffer[n] = random;
return true;
}
Sometimes I'm getting same int twice, I'm wondering where is the problem? And is it even work? I spend quite a lot of time on this, and I give up. I think I need some minor tweaks in code :)
An easier way to get a random int is to create a List of integers List<Integer>, adding it with numbers that you would like to have. Then shuffling the List using Collections.shuffle(list);. Now start reading from the beginning of the list and you will get a unique random int each time.
Just make sure that each time you "read" a number from the list, either remove it from the list or increase the index for where you read.
That's the normal behavior of a random number generator, it's correct to generate repeated numbers as long as the number distribution remains uniform.
If you need a set of unique random numbers, you can generate them inside a loop and ask at every iteration if the newly generated number is present in the set of generated numbers. If not, add it, if yes, keep iterating - until the set has the desired size.
Er, a unique random between 1 and 20? What happens when it runs the 21st time?
Try making a List of the Integers between 1 and 20. Use Collections.shuffle() to shuffle the list. Then pop the first item off the front of the list and use that.