My script is caught in an infinite loop and I cannot figure out why. I have an array with 40 pawns and need to put these randomly on a board. So, I have a random number that chooses a random pawn from the array, but if the pawn has already been chosen, it has to pick a new random number, but that last part seems to bug for some reason. I cannot figure out why.
Random rand = new Random();
int[] availablePawnsArray = {1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9, 10, 11, 12, 12, 12, 12, 12, 12 };
// this array contains 40 integers
int[] chosenPawns = new int[40];
//this array contains the index numbers of already selected pawnsfrom the previous array
int counter = 0;
//counts how many pawns have been selected already
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 10; j++) {
//this refers to my board, 40 locations for my 40 pawns
int chosenPawn = rand.nextInt(40);
//a random numder from 0 to 40
boolean found = false;
//a boolean to say if i have already selected this pawn before or not
do {
for (int n : chosenPawns) {
if (n == chosenPawn) {
found = true;
chosenPawn = rand.nextInt(40);
} else {
found = false;
}
}
} while(found == true);
board[i][j].rank = availablePawnsArray[chosenPawn];
chosenPawns[counter] = chosenPawn;
counter++;
}
}
You can have two arrays, and second one keep for selected integers, then do loop in second array check if there is any number equal to given one return false or true.
int [] selectedInts = new int[40];
boolean contains(int num) {
for (int i = 0 ; i < selectedInts.length; i++) {
if (i == num) return true;
}
return false;
}
Also you can use like
Arrays.asList().contains(yourInt);
You can simplify this by modifying the random number selection in the same way that one might shuffle a deck of cards. It is a slight variation of Fisher-Yates. I believe this should always work in linear time.
Random rand = new Random();
int[] availablePawnsArray = {
1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6,
6, 6, 6, 7, 7, 7, 8, 8, 9, 10, 11, 12, 12, 12, 12, 12, 12
};
int start = 39;
for (int i = 0; i < 4; i++) {
for (int k = 0; k < 10; k++) {
int chosenPawn = rand.nextInt(start + 1);
// chose the pawn
board[i][k].rank = availablePawnsArray[chosenPawn];
// copy the pawn from the end of the list to the
// chosen pawn location.
availablePawnsArray[chosenPawn] = availablePawnsArray[start];
// update the random number to ignore the last slot
// in the array (the pawn in that slot has
// been moved to occupy the chosenPawn's location)
start--;
}
}
for (int i = 0; i < 4; i++) {
for (int k = 0; k < 10; k++) {
System.out.print(board[i][k].rank + " ");
}
System.out.println();
}
}
Unless you need to implement it as an exercise you could use the built in shuffle
method, wrapping your array of available pawns in a list:
Collections.shuffle(Arrays.asList(availablePawnsArray));
for (int i = 0, k = 0; i < 4; i++)
for (int j = 0; j < 10; j++, k++)
board[i][j].rank = availablePawnsArray[k];
The chosenPawns array should only be searched upto counter. Using repeatedly random to find a free spot when almost all is used, could take several thousands of steps to find the final last open spots. There is not even a guarantee to find an open spot.
Simply consider the random position as starting point to find the first free pawn, going round-robin from ... 36, 37, 38, 39, 0, 1, ....
int[] pawnsArray = {1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4,
5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9, 10, 11, 12, 12, 12, 12, 12, 12 };
// this array contains 40 integers
boolean[] pawnsChosen = new boolean[40];
// this array tells wether the i'th pawn was chosen.
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 10; j++) {
int pawnIndex = rand.nextInt(40);
while (pawnsChosen[pawnIndex]) {
pawnIndex = (pawnIndex + 1) % 40;
}
pawnsChosen[pawnIndex] = true;
board[i][j].rank = availablePawnsArray[pawnIndex];
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.