Как использовать одно и то же случайное начальное число между устройствами Windows?

Я пытаюсь перетасовать карты в колоде, используя одно и то же случайное семя, поэтому колоды будут случайными, но синхронизированными на обоих клиентах. Я использую следующий алгоритм перемешивания:

    internal void ShuffleDeck(int randomSeed)
    {
        _random = new Random(randomSeed);
        Cards.Card[] toShuffle = CardsInDeck.ToArray();
        Shuffle<Cards.Card>(toShuffle);
        CardsInDeck = toShuffle.ToList<Cards.Card>();
    }

    /// <summary>
    /// Shuffle the array.
    /// </summary>
    /// <typeparam name="T">Array element type.</typeparam>
    /// <param name="array">Array to shuffle.</param>
    private static void Shuffle<T>(T[] array)
    {
        int n = array.Length;
        for (int i = 0; i < n; i++)
        {
            // NextDouble returns a random number between 0 and 1.
            // ... It is equivalent to Math.random() in Java.
            int r = i + (int)(_random.NextDouble() * (n - i));
            T t = array[r];
            array[r] = array[i];
            array[i] = t;
        }
    }

Когда я запускаю два экземпляра карточной игры на одном компьютере, карты перемешиваются и синхронизируются на обоих клиентах, как и ожидалось, но когда я запускаю один экземпляр на своем компьютере, а другой — в эмуляторе HoloLens, карты используют одно и то же начальное число, но карты не синхронизируются. Есть ли способ перетасовать карты и синхронизировать их между несколькими клиентами?

Под синхронизацией я подразумеваю, что они перемешиваются точно так же. IE, когда я запускаю оба клиента в первый раз с четырьмя картами (a,b,c,d), порядок колоды (b,c,a,d) на обоих клиентах. Когда я запускаю клиентов во второй раз, порядок колод (c, d, a, b) на обоих клиентах.


person Seth Kitchen    schedule 17.08.2016    source источник
comment
Если бы вы использовали Twister Mersenne, вы могли бы просто поделиться текущим начальным числом, и оба генерировали бы одну и ту же последовательность значений. Кстати, это несовершенный тасовщик.   -  person Ňɏssa Pøngjǣrdenlarp    schedule 17.08.2016
comment
@Plutonix, что такое несовершенный тасовщик? Есть ли Mersenne Twister, встроенный в С#?   -  person Seth Kitchen    schedule 17.08.2016
comment
Он ошибочен - он должен перемещать каждый элемент один раз и только один раз, не учитывая его при перемещении последующих элементов.   -  person Ňɏssa Pøngjǣrdenlarp    schedule 17.08.2016
comment
См. blog.codinghorror.com/the-danger-of-naivete. причина, по которой ваш тасование не является правильным. И за правильно реализованный шафл.   -  person Jim Mischel    schedule 18.08.2016
comment
@JimMischel Спасибо за эту статью. Я по наивности просто погуглил алгоритм перемешивания C# и получил dotnetperls.com/fisher-yates-shuffle. и скопировал его. Казалось, что это сработало, но ваша статья объясняет, почему это не так. Спасибо   -  person Seth Kitchen    schedule 18.08.2016


Ответы (2)


Для этого вам необходимо убедиться, что обе машины используют одно и то же начальное число и один и тот же генератор случайных чисел. Нет никакой гарантии, что разные версии класса Random будут использовать один и тот же алгоритм.

Поэтому вам нужно разработать свой собственный класс генератора случайных чисел и использовать его вместо System.Random.

person Jim Mischel    schedule 17.08.2016
comment
Разит. Почему System.Random должен быть другим? Спасибо, что в значительной степени отвечает на мой вопрос, но я понятия не имею, как создать случайный класс... - person Seth Kitchen; 17.08.2016
comment
@SethKitchen: Причина изменений может заключаться в том, что они нашли ошибку или придумали более быстрый алгоритм. Что касается создания собственного, вы можете сделать это, получить исходный код существующего System.Random из referencesource.microsoft.com/#mscorlib/system/, скопируйте код в свой проект, измените имя на MyRandom, а затем везде, где вы используете System.Random в своем коде, ссылайтесь MyRandom. Или вы можете провести небольшое исследование и разработать собственный генератор псевдослучайных чисел. Это не так сложно. - person Jim Mischel; 17.08.2016
comment
@Jim Mischel: О втором предложении вашего комментария: взгляните на лицензионное соглашение для справочного источника, найденного на referencesource.microsoft.com. - person Peter O.; 20.06.2017
comment
@ПитерО. Принято к сведению. - person Jim Mischel; 20.06.2017
comment
Просто в дополнение к моему комментарию. Я хотел добавить, что я не юрист, но не смог отредактировать этот комментарий. - person Peter O.; 20.06.2017

Я просто хочу добавить свой собственный ответ здесь.

Простой тасование 52 карт может занять всего 29 байт или (что более практично) 52 байта, что большинство приложений может считать «немного». На мой взгляд, было бы лучше сохранить перетасованную колоду, в данном случае, а не чем семя, если только ваше приложение не показывает вашим пользователям код для повторного создания перетасованной колоды вашими игроками. Таким образом, вам не придется привязывать свое приложение к определенному ГСЧ (например, System.Random).

person Peter O.    schedule 07.09.2018