@D0ct0r_Murder

Алгоритм расстановки позиций чисел в игре «пятнашки» — выводит -1. В чём ошибка?

в startGameButton_Click выводится все -1. Я до сих пор не заметил в чём ошибка.
Как определить,придумал ли рандом одинаковое число,по-другому не знаю,как,кроме перебора. Почему он выходит из цикла. Он должен перебрать его,пока рандом не выдаст число,отличное от тех чисел,что уже были.

private void startGameButton_Click(object sender, EventArgs e)
        {
            int[] t_numbers;
            MessageBox.Show("Game started...");
            GetRandomLocate(out t_numbers);

            string str = "";

            foreach (var t in t_numbers)
                str += t.ToString() + " ";

            MessageBox.Show(str);
        }
private void GetRandomLocate(out int[] t_numbers)
        {
            Random random = new Random();
            bool flag = true;

            t_numbers = new int[Logic.size];

            for (int i = 0; i < Logic.size; i++)
                t_numbers[i] = -1;

            for(int i = 0;i<Logic.size;i++)
            {
                while(flag)
                {
                    int rnd = random.Next(0, Logic.size + 1);
                    int ind = 0;

                    foreach (var t in t_numbers)
                        if (t == rnd)
                            ind = 1;

                    if (ind == 0)
                    {
                        t_numbers[i] = rnd;
                        flag = !flag;
                    }

                    else
                        flag = true;
                }
            }
        }
  • Вопрос задан
  • 364 просмотра
Пригласить эксперта
Ответы на вопрос 3
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
1. Сгенерите массив от 1 до 15.
2. Перемешайте его
3. Берите любое из массива и удаляйте (режим очереди или стека - не важно).
Ответ написан
@kttotto
пофиг на чем писать
Самый нормальный способ перемешать, это в готовом массиве в цикле брать порядковый элемент и менять его местами с рандомным. Зачем Вам головняк с двойным циклом?
var rnd = new Random();
var arr = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ];
for(var i; i < arr.Length; i++)
{
	var newPosition = rnd.Next(arr.Length);
	var temp = arr[newPosition];
	arr[newPosition] = arr[i];
	arr[i] = temp;
}


PS: А для того, чтобы понять что в массиве есть такое число или нет, можно применить linq
t_numbers.Any(x => x == number)
И никогда не делайте эту штуку внутри метода
Random random = new Random();
Это угрожает созданием одинаковых последовательностей. Объект Random должен быть полем класса, причем статическим.
Ответ написан
Комментировать
@youkerni
Unity3D developer
Способ которым ты контролируешь уникальность цифр на кнопке далеко не оптимальный. Представь сколько итераций потребуется для того, что бы срандомить число 24 если у тебя уже есть числа от 0 до 23 (для поля 5x5); Шанс 1/25, а значит в среднем будет уходить 25 итераций. Это не много, но не оптимально.

Что я предлагаю: создать List, засунуть туда n чисел (от 0 до n). И дальше использовать следующий код:

t_numbers = new int[Logic.size];
List<int> numbers = new List<int>();
int randomIndex = -1;

 for (int i = 0; i < Logic.size; i++)
                numbers.Add(i);
int i = 0;
do
{
  randomIndex = random.Next(0, numbers.Count);
   t_numbers[i++] = numbers[randomIndex];
   numbers.RemoveAt(randomIndex);
} while(numbers.Count > 0);


Не уверен что написал все верно, т.к. пишу код прямо тут. Но суть ты должен был уловить.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы