从 Java RNG 的范围中删除一个数字?
Removing a number from a Java RNG's range?
我目前正在使用 Java 的 RNG Random r = new Random()
,并让它在 while 循环中生成一个介于 0 和 5 之间的新整数。
while (someBoolean == false) {
int i = r.nextInt(6);
....
}
我想做的是从范围中删除一个数字(例如 4),以便 RNG 仍然生成一个介于 0 和 5 之间的新数字,不包括其中一个值。
我目前最好的选择如下:
while (someBoolean == false) {
int i = r.nextInt(6);
if (i == removedInt) { continue; }
....
}
但是我担心这会导致我的代码长时间运行,其中 RNG 不断返回我不想要的数字。
[为清楚起见; 返回的数字是 Connect4 网格中的一列,或 2D int 数组。该方法是在列中随机放置移动,直到列填满,此时我不再希望能够在该列中进行游戏。 ]
感谢任何帮助:)
虽然您可以使用 List
枚举您想要生成的数字和 exclude/remove 您想要排除的数字,但这仅对小范围有效。如果要生成大范围内的随机数,这个方案就变得相当低效和不可行.
仅使用 1 Random.nextInt()
调用的解决方案
如果您想生成 0..5
范围内的随机数,您可以使用 r.nextInt(6)
。
如果您想排除一个数字,例如4
,这意味着范围小了1,所以使用r.nextInt(5)
,如果结果是被排除的数字,那么return允许的最大值是5
(因为它永远不会生成,因为你使用了 max - 1).
看起来像这样:
// Returns a random number in the range 0..5 (0 and 5 included), 4 excluded
public int nextRand() {
int i = r.nextInt(5);
return i == 4 ? 5 : i;
}
一般解决方案
这里有一个通用的解法,以min
、max
和可排除的数字为参数:
/**
* Returns a random number in the range min..max both included, but never the excluded.
*/
public int nextRand(int min, int max, int excluded) {
if (max <= min || excluded < min || excluded > max)
throw new IllegalArgumentException(
"Must be: min <= excluded <= max AND min < max");
int i = min + r.nextInt(max - min); // r is a java.util.Random instance
return i == excluded ? max : i;
}
因此,例如,如果您调用 nextRand(0, 5, 3)
,它只会 return 一个随机数,它是 0, 1, 2, 4, 5
之一。
ArrayList<Integer> myInts = new ArrayList<Integer>();
myInts.add(1);
myInts.add(2);
myInts.add(3);
myInts.add(4);
int i = myInts.get(r.nextInt(myInts.size())); // 1,2,3,4
myInts.remove(3);
int j = myInts.get(r.nextInt(myInts.size())); // 1,2,4
代码从允许的整数列表中选择随机条目。
PS请注意,如果您的数字范围很大,那么创建一个包含成千上万个整数的 ArrayList 可能不是最好的主意。
希望这对您的情况有所帮助。它并没有真正排除任何数字,而是制作
根据随机数赋予它的初始值决定在哪个位置移动。
//Change these to what you want
int numberColumns = 7;
int numberRows = 6;
/**
* A way for my snippet to determine what column has a piece in its very top spot.
*/
boolean[][] hasPiece = new boolean[numberRows][numberColumns];
/**
* Get a random number between 0 and numberColumns - 1 and set it equal
* to the column you want the computer to place it in.
*/
int columnToPlace = (int) (0 +Math.random()*numberColumns);
/**
* A boolean check to determine what side of the chosen column to check first.
* This way it doesn't always check to the left or right first.
*/
if(Math.random() < 0.5){
//Forwards for loop to start at the initial random number given.
for(int runner = columnToPlace; runner < numberColumns; runner++){
if(!hasPiece[0][runner]){/**Check First Row And Next Column To The Right For A Piece.*/
columnToPlace = runner;/**If there is no piece their set it equal to that number/empty column.*/
break;/**Break out of the loop*/
}
}
}else{
//Reversed for loop to start at the initial random number given.
for(int backwardsRunner = columnToPlace; backwardsRunner > 0; backwardsRunner--){
if(!hasPiece[0][backwardsRunner]){/**Check First Row And Next Column To The Left For A Piece.*/
columnToPlace = backwardsRunner;/**If there is no piece their set it equal to that number/empty column.*/
break;/**Break out of the loop*/
}
}
}
//The final number/empty column the computer will make it's move in.
System.out.println(columnToPlace);
使用这种方法,您可能会得到一个不错的 AI,它不仅会随机移动。
这是开始注意 "runner" 循环的好地方。如果你有办法检查它是否
随机列左侧或右侧的计算机部分,您可以添加逻辑
会做出更明智的决定。
您的大脑固执地认为 random() 中的数字必须与您实际用于行或其他内容的数字相同。使用小数组将纯序数与其表示的内容分开:
Vector validColumns = new Vector(6);
for (int i = 0; i < 6; i += 1) { validColumns.add(i); }
. . .
c = validColumns[r.nextInt(validColumns.size())]
在 ... 中,您可以根据需要删除和添加列。
我目前正在使用 Java 的 RNG Random r = new Random()
,并让它在 while 循环中生成一个介于 0 和 5 之间的新整数。
while (someBoolean == false) {
int i = r.nextInt(6);
....
}
我想做的是从范围中删除一个数字(例如 4),以便 RNG 仍然生成一个介于 0 和 5 之间的新数字,不包括其中一个值。
我目前最好的选择如下:
while (someBoolean == false) {
int i = r.nextInt(6);
if (i == removedInt) { continue; }
....
}
但是我担心这会导致我的代码长时间运行,其中 RNG 不断返回我不想要的数字。
[为清楚起见; 返回的数字是 Connect4 网格中的一列,或 2D int 数组。该方法是在列中随机放置移动,直到列填满,此时我不再希望能够在该列中进行游戏。 ]
感谢任何帮助:)
虽然您可以使用 List
枚举您想要生成的数字和 exclude/remove 您想要排除的数字,但这仅对小范围有效。如果要生成大范围内的随机数,这个方案就变得相当低效和不可行.
仅使用 1 Random.nextInt()
调用的解决方案
如果您想生成 0..5
范围内的随机数,您可以使用 r.nextInt(6)
。
如果您想排除一个数字,例如4
,这意味着范围小了1,所以使用r.nextInt(5)
,如果结果是被排除的数字,那么return允许的最大值是5
(因为它永远不会生成,因为你使用了 max - 1).
看起来像这样:
// Returns a random number in the range 0..5 (0 and 5 included), 4 excluded
public int nextRand() {
int i = r.nextInt(5);
return i == 4 ? 5 : i;
}
一般解决方案
这里有一个通用的解法,以min
、max
和可排除的数字为参数:
/**
* Returns a random number in the range min..max both included, but never the excluded.
*/
public int nextRand(int min, int max, int excluded) {
if (max <= min || excluded < min || excluded > max)
throw new IllegalArgumentException(
"Must be: min <= excluded <= max AND min < max");
int i = min + r.nextInt(max - min); // r is a java.util.Random instance
return i == excluded ? max : i;
}
因此,例如,如果您调用 nextRand(0, 5, 3)
,它只会 return 一个随机数,它是 0, 1, 2, 4, 5
之一。
ArrayList<Integer> myInts = new ArrayList<Integer>();
myInts.add(1);
myInts.add(2);
myInts.add(3);
myInts.add(4);
int i = myInts.get(r.nextInt(myInts.size())); // 1,2,3,4
myInts.remove(3);
int j = myInts.get(r.nextInt(myInts.size())); // 1,2,4
代码从允许的整数列表中选择随机条目。
PS请注意,如果您的数字范围很大,那么创建一个包含成千上万个整数的 ArrayList 可能不是最好的主意。
希望这对您的情况有所帮助。它并没有真正排除任何数字,而是制作 根据随机数赋予它的初始值决定在哪个位置移动。
//Change these to what you want
int numberColumns = 7;
int numberRows = 6;
/**
* A way for my snippet to determine what column has a piece in its very top spot.
*/
boolean[][] hasPiece = new boolean[numberRows][numberColumns];
/**
* Get a random number between 0 and numberColumns - 1 and set it equal
* to the column you want the computer to place it in.
*/
int columnToPlace = (int) (0 +Math.random()*numberColumns);
/**
* A boolean check to determine what side of the chosen column to check first.
* This way it doesn't always check to the left or right first.
*/
if(Math.random() < 0.5){
//Forwards for loop to start at the initial random number given.
for(int runner = columnToPlace; runner < numberColumns; runner++){
if(!hasPiece[0][runner]){/**Check First Row And Next Column To The Right For A Piece.*/
columnToPlace = runner;/**If there is no piece their set it equal to that number/empty column.*/
break;/**Break out of the loop*/
}
}
}else{
//Reversed for loop to start at the initial random number given.
for(int backwardsRunner = columnToPlace; backwardsRunner > 0; backwardsRunner--){
if(!hasPiece[0][backwardsRunner]){/**Check First Row And Next Column To The Left For A Piece.*/
columnToPlace = backwardsRunner;/**If there is no piece their set it equal to that number/empty column.*/
break;/**Break out of the loop*/
}
}
}
//The final number/empty column the computer will make it's move in.
System.out.println(columnToPlace);
使用这种方法,您可能会得到一个不错的 AI,它不仅会随机移动。 这是开始注意 "runner" 循环的好地方。如果你有办法检查它是否 随机列左侧或右侧的计算机部分,您可以添加逻辑 会做出更明智的决定。
您的大脑固执地认为 random() 中的数字必须与您实际用于行或其他内容的数字相同。使用小数组将纯序数与其表示的内容分开:
Vector validColumns = new Vector(6);
for (int i = 0; i < 6; i += 1) { validColumns.add(i); }
. . .
c = validColumns[r.nextInt(validColumns.size())]
在 ... 中,您可以根据需要删除和添加列。