Есть ли какой-нибудь шаблон в методе Random()?
Я начал делать проект, где есть козы! Да, козы.
В настоящее время существует только одна функция, когда я нажимаю на козу, она создает другую козу в позиции Random.
Я понял, что есть структура позиций:
![I've made red lines on patterns]()
Вот код:
public class GameActivity extends Activity {
private int[] arrGoats = new int[5];
private RelativeLayout battlefield;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
battlefield = (RelativeLayout) findViewById(R.id.rel_battlefield);
arrGoats[0] = R.drawable.amarelo;
arrGoats[1] = R.drawable.azul;
arrGoats[2] = R.drawable.branco;
arrGoats[3] = R.drawable.verde;
arrGoats[4] = R.drawable.vermelho;
criarCabra(60, 100);
}
private void criarCabra(float x, float y) {
int cabraImg = arrGoats[new Random().nextInt(4)];
ImageView cabra = new ImageView(this);
cabra.setImageResource(cabraImg);
cabra.setX(x);
cabra.setY(y);
LayoutParams params = (LayoutParams) new LayoutParams(MarginLayoutParams.WRAP_CONTENT,
MarginLayoutParams.WRAP_CONTENT);
params.width = 150;
params.height = 120;
cabra.setLayoutParams(params);
cabra.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
criarCabra(new Random().nextInt(2000), new Random().nextInt(1000));
}
});
battlefield.addView(cabra);
}
}
Я хотел бы знать, почему этот шаблон создается, хотя я использую Random().NextInt()
для определения позиций коз.
Я сошел с ума?
Ответы
Ответ 1
Сначала вы создаете новый объект Random
каждый раз. В Android начальное значение выводится из текущего времени и хеш-кода идентификатора:
public Random() {
// Note: Using identityHashCode() to be hermetic wrt subclasses.
setSeed(System.currentTimeMillis() + System.identityHashCode(this));
}
Для двух объектов, созданных последовательно, хэш-коды идентичности близки друг к другу. На моем Android KitKat Dalvik VM я получаю коды хеш-идентификаторов, которые отличаются только 32.
currentTimeMillis()
также не имеет большого значения для семян.
Само случайное является линейным конгруэнтным генератором вида
random[i+1] = a * random[i] + b (mod c)
где random[0]
- это семя, а a
, b
и c
- параметры.
Основываясь на этом ответе, подобные семена действительно дают аналогичные результаты в линейных конгруэнтных генераторах:
Причина, по которой вы видите аналогичный исходный вывод nextDouble с аналогичными семенами, заключается в том, что, поскольку вычисление следующего целого числа включает только умножение и добавление, величина следующего целого не сильно зависит от различий в младших битах.
Следовательно, ваши два сгенерированных последовательно Random
с семенами по умолчанию будут создавать значения, которые, по-видимому, коррелированы и заставят ваших коз позиционировать на линии.
Чтобы исправить это, используйте тот же объект Random
и/или более случайный псевдослучайный генератор, чем линейный конгруэнтный.
Ответ 2
Вы создаете новые экземпляры Random
при каждом вызове criarCabra
и каждом вызове onClick
. Создайте один статический экземпляр Random
, затем повторно используйте его.
Если вы действительно не знаете, что делаете, и у вас есть все основания для этого, лучше всего создать только один экземпляр Random
для каждой программы, а затем опросить его, когда вам понадобятся дополнительные значения.