How I can add(label) random in JFrame? - random

I try to make the memoryCard Game...
Is there a way to add(labels) in a JFrame window RANDOM?
I use FlowLayout and I have:
add(l1);add(l2);add(l3);add(l4);
If I write somthing like this:
add(l3);add(l4);add(l1);add(l2);
changing series of images.. That's what I want... to add the labels with different position every time..
If not, is there a way to put with different row (random) the images in labels?
I have this way to put the images:
imageOfLabel1 = imageOfLabel2 = "im1.jpg";
imageOfLabel3 = imageOfLabel4 = "im2.jpg";
Sorry about my English! : )

I'm not sure what's the type of l1, l2, l3 and l4. Suppose they all are JLabel instances. Then you can create an array, shuffle it and then add:
JLabel[] ls = new JLabel[] {l1, l2, l3, l4};
// shuffle
Random rand = new Random();
for (int i = 0; i < ls.length; i++) {
int randIndex = rand.nextInt(ls.length);
JLabel temp = ls[i];
ls[i] = ls[randIndex];
ls[randIndex] = temp;
}
for (int i = 0; i < ls.length; i++) add(ls[i]);

Related

Separate stream of numbers into groups of closer integers

I have a stream of numbers such as
[2872, 2997, 3121, 13055, 14178, 14302, 23134, 23382, 23507, 32832, 33677, 34017, 43415, 44246, 44374, 52866, 54035, 54158, 62835, 64243, 64936, 73110, 73890, 74014, 82809, 83771, 83899, 93436, 94765, 94891].
I would like to split it as follows:
[[2872, 2997, 3121], [13055, 14178, 14302], [23134, 23382, 23507], [32832, 33677, 34017], [43415, 44246, 44374], [52866, 54035, 54158], [62835, 64243, 64936], [73110, 73890, 74014], [82809, 83771, 83899], [93436, 94765, 94891]].
It is to be noted that the distance between the groups could be closer to each other, also the digits within a group could be farther away.
This is not an answer, but a way to look at your data, which should be insightful.
Original values:
Deltas:
Can't you just create a list of list of integers (or array of array) with size N/3 (N being the total of your numbers), and then just loop on this length and put the minimal number in it?
Something like this (I don't know what language you are using so I use c# as exemple):
int len = numbersStream.count();
List<List<int>> BigList = new List<List<int>>();
List<int> smallList = new List<int>();
for (int i = 0; i < len; ++i)
{
smallList = new List<int>();
for (int j = 0; j < 3; ++i)
{
int value = Math.Min(numbersStream);
smallList.Add(value);
numbersStream.remove(value);
}
BigList.Add(smallList);
}
BigList will be : (2872, 2997, 3121), (13055, 14178, 14302) etc...
*Assuming you always have exactly %3 numbers, otherwise you just tune the algorithm to avoid exceptions
The solution is in java but basically what this does is find the average delta and groups everything in a subset if the difference between the two elements is smaller then that average. You can fine tune this process by changing how the averageDelta operates
ps. this solution assumes your input is at least 1 large and called temp
int[] diffrence = new int[temp.length-1];
for (int i=1; i < temp.length; i++) {
diffrence[i-1] = temp[i]-temp[i-1];
}
int averageDelta = (int) Math.round(Arrays.stream(diffrence).average().orElse(1.0));
List<List<Integer>> resultList = new ArrayList<>();
List<Integer> currentList = new ArrayList<>();
currentList.add(temp[0]);
for (int i=1; i < temp.length; i++) {
if (temp[i]-temp[i-1] > averageDelta) {
resultList.add(currentList);
currentList = new ArrayList<>();
}
currentList.add(temp[i]);
}
resultList.add(currentList);
System.out.println(resultList.toString());

Iterating over an ArrayList<Object> using a for loop

Im having a problem with my for loop for iterating over an ArrayList that hold objects. I make an ArrayList that hold these items, LumberItem is just a String for the name and an int for the amount.
ArrayList<LumberItem> lumberList = new ArrayList<LumberItem>();
LumberItem wood1 = new LumberItem("Oak", 1500);
lumberList.add(0, wood1);
LumberItem b = new LumberItem("Pine", 1500);
lumberList.add(1,b);
LumberItem c = new LumberItem("Cedar", 1500);
lumberList.add(2, c);
LumberItem d = new LumberItem("Maple", 1500);
lumberList.add(3, d);
LumberItem exp = new LumberItem("Birch", 1500);
lumberList.add(4, exp);
I try to use a for loop like so
for(int i = 0; i < lumberList.size(); i++) {
contentTA.setText(lumberList.get(i).getType());
contentTA.append("\n at index" + i + "\n");
}
My output consists of only the last element in my ArrayList so,
Birch is outputted. I have tried using different methods of looping like
for(LumberItem l : lumberList)
I am still at the end of my ArrayList when I try and output. I wondering why this is happening since I haven't figured it out.
So I'm an idiot, I was using .setText() which will clear the JTextArea every time I call it, so it should be .append()!
for(LumberItem L : lumberList) {
contentTA.append("\n" + L.getType());
}
or
for(int i = 0; i < lumberList.size(); i++) {
contentTA.append(lumberList.get(i).getType());
Will work.
Hopefully my poor reading skills help out someone else!

Rearranging data for quadtree/octree

I am working on implementing a voxel octree raycaster, and the only thing left is rearranging the data to populate the leaf level of the octree, so that the data then can be averaged to build the lower levels of the tree.
I'm thinking in 2D (quadtree) initially for convenience. I have the data ordered like in the left in the drawing, and I am currently able to rearrange it like to the right. Example is 8x8.
However, I realized that I need to order the data in node order, like in the drawing below:
In other words, I want to go from an array where the data correspond to indices like this:
[0 1 2 3 4 5 6 7 8 9 ... 63]
to an array that would have the data in this order:
[0 1 4 5 16 17 20 21 2 3 ... 63]
for an 8x8 quadtree example.
I can't figure out how to do it. My main problem is dealing with an arbitrary tree size. I could probably hard-code a set of nested loops if I knew the size beforehand, but that it obviously not a great or elegant solution. I'm thinking there might be a recursive way achieve it.
This it what my quick and dirty sketch for sorting the data in the way described in picture one. It basically works by keeping track of four positions in the original data, and then stepping these forward as the new array gets filled. As far as I have been able to tell, this works fine but is not extendable to my needs:
int w = 8;
int[] before = new int[w*w*w];
int[] after = new int[w*w*w];
for (int i=0; i<w*w*w; i++) {
before[i] = i;
}
int toFill = 0;
int front = 0;
int back = w;
int frontZ = w*w;
int backZ = w*w + w;
do {
for (int i=0; i<w/2; i++) {
for (int j=0; j<w/2; j++) {
after[toFill++] = front++;
after[toFill++] = front++;
after[toFill++] = back++;
after[toFill++] = back++;
after[toFill++] = frontZ++;
after[toFill++] = frontZ++;
after[toFill++] = backZ++;
after[toFill++] = backZ++;
}
front += w;
back += w;
frontZ += w;
backZ += w;
}
front += w*w;
back += w*w;
frontZ += w*w;
backZ += w*w;
} while (toFill < w*w*w);
for (int i=0; i<w*w*w; i++) {
println("after " + i + " " + after[i]);
}
For the problem I stated, phs hinted me that it is called a Z-order curve. Thanks to that, I found this question: Z-order-curve coordinates where an algorithm for the 2D case is presented. I tried it, and it works.
Here are a few implementations of the 3D case as well: How to compute a 3D Morton number (interleave the bits of 3 ints)

How to generate random numbers with out repetition in windows phone app

here is the code for generating random numbers,but I am getting duplicate numbers,how can I overcome this.
void getnumbers()
{
Random r = new Random();
int[] trubyte = new int[4];
for (var x = 0; x < 4; ++x)
{
trubyte[x] = r.Next(1, 5);
}
b1.Content = trubyte[0];
b2.Content = trubyte[1];
b3.Content = trubyte[2];
b4.Content = trubyte[3];
}
Just get another random number if the method returns one that you already have.
void getnumbers()
{
Random r = new Random();
int num;
var trubyte = new List<int>();
for (var x = 0; x < 4; ++x)
{
do
{
num = r.Next(1, 5);
} while(trubyte.Contains(num));
trubyte[x] = num;
}
b1.Content = trubyte[0];
b2.Content = trubyte[1];
b3.Content = trubyte[2];
b4.Content = trubyte[3];
}
I'm using List instead of an array just because it offers the Contains method right away, not any other special reason.
This is not efficient if you want to generate a big list of random, unrepeated numbers (it's O(n^2) in the worst case) but for 4 numbers it's more than enough ;)
A random number generator function can return duplicates, because the output is random.
If you are using an RNG to generate numbers which must be unique, you will need to verify that they have not already been generated before using them.
Can't you use something like this [0] on Windows Mobile? It seems more practical than writing your own RNG.
0: http://msdn.microsoft.com/en-us/library/system.security.cryptography.randomnumbergenerator(v=vs.90).aspx
You have to do it by yourself, that means checking if a number was already generated.
You can do it like gjulianm said, but it is a long list of numbers, say 1000 you would be wasting a lot of time. So if you want a randomized list of 1000 you could proceed the following way
Initialize an array trubyte of size 1000 with trubyte[0]=1,trubyte[1]=2 and so on...
Initialize a variable arraysize=1000
run a loop 1000 times in which first extract a random number k btw 0-(arraysize-1). Your random number is a[k] which you can separately in a list. Now swap trubyte[k] with trubyte[arraysize]. And finally decrease the arraysize by one.
Another way, if you don't want the numbers while in the loop is just to use the changed list after the execution of loop
void getnumbers(){
Random r = new Random();
int num;
int[] trubyte = new int[1000];
int finalList[] = new int[1000]
for (int x = 0; x < 1000; ++x)
{
trubyte[x]=x+1;
}
int arraysize=1000;
for (var x = 0; x < 1000; ++x)
{
int k=r.Next(0, arraysize);
finalList[x]=trubyte[k];
trubyte[k]=trubyte[arraysize-1];
arraysize--;
}
//use the finalList
}
we can use dictionary instead of hash-set in windows phone application.
below is the code for generating distinct random numbers.
static int[] GetRandomNumbersNonrepeat(int noOfRandomNumbers, int maxValue)
{
Dictionary<int, int> randomnumbers = new Dictionary<int, int>();
while (randomnumbers.Count < maxValue)
{
Random r = new Random();
int rnum = r.Next(1, maxValue+1);
if (!randomnumbers.ContainsValue(rnum))
{
randomnumbers.Add(randomnumbers.Count + 1, rnum);
}
}
int[] rnums = randomnumbers.Values.ToArray<int>();
return rnums;
}

Running times for sorting methods over multple arrays

I have various sorting methods that are all sorting the same 100,000 random number array.
I'm using the following method to find the runtimes of each
long insertionStart = System.currentTimeMillis();
arr.Clone(iniArr);
arr.insertionSort();
long insertionFinal = System.currentTimeMillis() - insertionStart;
And the following for the random number arrary
int maxSize = 100000; // array size
Sortarr arr, iniArr; // reference to array
arr = new Sortarr(maxSize); // create the array
iniArr = new Sortarr(maxSize);
// insert random numbers
Random generator = new Random();
for (int i = 0; i < maxSize; i++) iniArr.insert(generator.nextInt());
How can I modify this so that I can have each of them sort 100 arrays rather than just one, and count the time of each array? Eg. Run1 - 23ms; Run2 - 25ms; ... Run100 - 22ms
EDIT:
I have one final thing to do.
So each iteration sorts the array a few ways, let's say insertion, merge, and quick sort.
So say insertion = 300ms, merge = 200ms, and quick = 100ms. I need to, for each iteration, find which method sorted the fastest.
I know this is a simple min/max type thing that you do a thousand times in lower programming classes.
Would it be easier to throw each value into an array and use an array.min call? (Whatever it actually is, new to java syntax..)
Currently, it looks like you are creating the array and then repeatedly sorting using different functions.
You simply need to put all of that in a loop.
int maxRuns = 100;
int maxSize = 100000; // array size
for (int run=0; run<maxRuns; run++) {
Sortarr arr, iniArr; // reference to array
arr = new Sortarr(maxSize); // create the array
iniArr = new Sortarr(maxSize);
// insert random numbers
Random generator = new Random();
for (int i = 0; i < maxSize; i++) iniArr.insert(generator.nextInt());
long insertionStart = System.currentTimeMillis();
arr.Clone(iniArr);
arr.insertionSort();
long insertionFinal = System.currentTimeMillis() - insertionStart;
/* <more code goes here> */
}
You can use the index run while printing out your results.
You probably would be doing something like:
for (int try = 0; try < 100; try++) {
iniArr = new Sortarr(maxSize);
// insert random numbers
Random generator = new Random();
for (int i = 0; i < maxSize; i++) iniArr.insert(generator.nextInt());
long insertionStart = System.currentTimeMillis();
arr.Clone(iniArr);
arr.insertionSort();
long insertionFinal = System.currentTimeMillis() - insertionStart;
// print out the time, and/or add up the total
}
you'd still need the initialization beforehand. I guess I don't know why the array is cloned before it is sorted. Can you directly sort that array?

Resources