我正在制作专注游戏。
我有一个缓冲的图像数组,我加载了25张图像精灵表。
public static BufferedImage[] card = new BufferedImage[25];
0指数是回卡。如果卡匹配,则1 - 24是要检查的卡面值。
我要做的就是这将使我有4个困难Easy,Normal,Hard和Extreme。每个难度都会有一定数量的牌需要抽取,然后加倍选择的牌。例如,默认级别为NORMAL,即12个匹配,因此需要从Buffered Image阵列中随机选择12个唯一的卡,然后将每个值加倍,使每个卡只有2个,然后将结果随机播放。
这是我到目前为止所得到的,但似乎总有99%的时间都有重复。
//generate cards
Random r = new Random();
int j = 0;
int[] rowOne = new int[12];
int[] rowTwo = new int[12];
boolean[] rowOneBool = new boolean[12];
for(int i = 0; i < rowOneBool.length; i++)
rowOneBool[i] = false;
for(int i = 0; i < rowOne.length; i++){
int typeId = r.nextInt(12)+1;
while(rowOneBool[typeId]){
typeId = r.nextInt(12)+1;
if(rowOneBool[typeId] == false);
}
rowOne[i] = typeId;
j=0;
}
我需要生成的3个数量是Easy 6,Normal 12和Hard 18 extreme将使用除了索引0之外的所有图像。
答案 0 :(得分:1)
这或多或少具有随机数的性质。有时它们是重复的。如果您希望它们更独特,您可以轻松地将其考虑在内。如果它不是唯一的,只需丢弃该号码并再次生成。
这是一种生成具有指定重复余量的唯一随机数的简单方法:
public static void main(String[] args) {
int[] randoms = uniqueRandoms(new int[16], 1, 25, 3);
for (int r : randoms) System.out.println(r);
}
public static int[] uniqueRandoms(int[] randoms, int lo, int hi, int allowance) {
// should do some error checking up here
int range = hi - lo, duplicates = 0;
Random gen = new Random();
for (int i = 0, k; i < randoms.length; i++) {
randoms[i] = gen.nextInt(range) + lo;
for (k = 0; k < i; k++) {
if (randoms[i] == randoms[k]) {
if (duplicates < allowance) {
duplicates++;
} else {
i--;
}
break;
}
}
}
return randoms;
}
编辑:经过测试和更正。现在它有效。 :)
答案 1 :(得分:0)
根据我对你的问题的理解,答案应该是这样的:
有2个类,一个叫Randp
,另一个叫Main
。运行Main
,然后根据需要编辑代码。
package randp;
public class Main {
public static void main(String[] args) {
Randp randp = new Randp(10);
for (int i = 0; i < 10; i++) {
System.out.print(randp.nextInt());
}
}
}
package randp;
public class Randp {
private int numsLeft;
private int MAX_VALUE;
int[] chooser;
public Randp(int startCounter) {
MAX_VALUE = startCounter; //set the amount we go up to
numsLeft = startCounter;
chooser = new int[MAX_VALUE];
for (int i = 1; i <= chooser.length; i++) {
chooser[i-1] = i; //fill the array up
}
}
public int nextInt() {
if(numsLeft == 0){
return 0; //nothing left in the array
}
int a = chooser[(int)(Math.random() * MAX_VALUE)]; //picking a random index
if(a == 0) {
return this.nextInt(); //we hit an index that's been used already, pick another one!
}
chooser[a-1] = 0; //don't want to use it again
numsLeft--; //keep track of the numbers
return a;
}
}
答案 2 :(得分:0)
这就是我处理它的方式。您可以将BufferedImage对象移动到List,但我会考虑为您正在使用的“卡片”创建一个对象...
int removalAmount = 3; //Remove 3 cards at random... Use a switch to change this based upon difficulty or whatever...
List<BufferedImage> list = new ArrayList<BufferedImage>();
list.addAll(Arrays.asList(card)); // Add the cards to the list, from your array.
Collections.shuffle(list);
for (int i = 0; i < removalAmount; i++) {
list.remove(list.size() - 1);
}
list.addAll(list);
Collections.shuffle(list);
for (BufferedImage specificCard : list) {
//Do something
}
答案 3 :(得分:0)
好的,我说我会给你更好的东西,我会的。首先,让我们改进Jeeter的解决方案。
StackOverflowException
。因此,我提出了该算法的改进版本:
class Randp {
private int MAX_VALUE;
private int numsLeft;
private boolean[] used;
public Randp(int startCounter) {
MAX_VALUE = startCounter;
numsLeft = startCounter;
// All false by default.
used = new boolean[MAX_VALUE];
}
public int nextInt() {
if (numsLeft <= 0)
return 0;
numsLeft--;
int index;
do
{
index = (int)(Math.random() * MAX_VALUE);
} while (used[index]);
return index;
}
}
我相信这更容易理解,但现在很明显算法不是很好。找到一个未使用的索引可能需要很长时间,特别是当我们想要很多值并且只剩下少量时。我们需要从根本上改变我们处理这个问题的方式。最好从一开始就随机生成值:
class Randp {
private ArrayList<Integer> chooser = new ArrayList<Integer>();
private int count = 0;
public Randp(int startCounter) {
for (int i = 0; i < startCounter; i++)
chooser.add(i);
Collections.shuffle(chooser);
}
public int nextInt() {
if (count >= chooser.size())
return 0;
return chooser.get(count++);
}
}
这是最有效和极其简单的,因为我们使用了现有的类和方法。