Здравствуйте, гость Правила · Помощь

  Все темы | Тема закрыта | Новая тема | Новый опрос  
»  Наконец-то у нас новый генератор раздач! Подписаться | Сообщить другу | Версия для печати
      » 27/05/2001, 19:00,  ALEZI 
Сашун, Дата: 24 Мая 2001 15:18

******
А вот для пользы дела (успокоения параноиков) генератор префный было бы неплохо тут тиснуть. Без там адреса базы и прочих "секретов".
Все его там строк 30. Посмотрели б его "со стороны".


yurets (---.krasu.ru) Дата: 24 Мая 2001 16:12

ну держите :) РНР отличается немного от С, но любой программист при желании разберется

сначала сам датчик случайных чисел (ничего я тут не придумывал, все по науке, алгоритм Мерсенна), генерится случайное число из 32 бит

define("N", 624);
define("M", 397);
define("MATRIX_A", -1727483681); /* constant vector a */
define("UPPER_MASK", -2147483648); /* most significant w-r bits */
define("LOWER_MASK", 2147483647); /* least significant r bits */
$mti = N+1;
$mag01 = array(0, MATRIX_A);

function mt_regen() {
GLOBAL $mt, $mti, $mag01;
for ($kk=0; $kk $y = ($mt[$kk]&UPPER_MASK)|($mt[$kk+1]&LOWER_MASK);
$mt[$kk] = $mt[$kk+M] ^ (($y >> 1)&LOWER_MASK) ^ $mag01[$y & 1];
}
for (; $kk $y = ($mt[$kk]&UPPER_MASK)|($mt[$kk+1]&LOWER_MASK);
$mt[$kk] = $mt[$kk+(M-N)] ^ (($y >> 1)&LOWER_MASK) ^ $mag01[$y & 1];
}
$y = ($mt[N-1]&UPPER_MASK)|($mt[0]&LOWER_MASK);
$mt[N-1] = $mt[M-1] ^ (($y >> 1)&LOWER_MASK) ^ $mag01[$y & 1];
$mti = 0;
return;
}

function genrand() {
GLOBAL $mt, $mti;
if ($mti > N) exit();
if ($mti == N) mt_regen();
$y = $mt[$mti++];
$y ^= ($y >> 11) & 2097151;
$y ^= ($y << 7) & -1658038656;
$y ^= ($y << 15) & -272236544;
$y ^= ($y >> 18) & 16383;
return $y;
}

собственно сдача карт - ничего хитрого, обычное выдергивание карт из колоды. еще раз повторю, все проблемы - в датчике, а не в процедуре deal

function my_mt_rand($min = 0, $max = 51) {
return $min + abs(genrand() % ($max-$min+1));
} -- если быть очень строгим, то в этой процедуре возникает небольшая неравномерность, за счет того что 2**31 (не 32 потому что отбрасывается знак) не делится нацело на 52 ( и 32 тоже), но это несущественно.

function deal($cards)
{
unset($card);
for ($i = 0; $i < $cards; $i++) $card[$i] = $i;
for ($i = $cards; --$i;) {
$pos = my_mt_rand(0, $i);
$t = $card[$pos];
$card[$pos] = $card[$i];
$card[$i] = $t;
}
return $card;
}



yurets (---.krasu.ru) Дата: 24 Мая 2001 16:17

в первой процедуре обрезались строки for... - там в условии стояло "меньше", как тэк пошло :)

function mt_regen() {
GLOBAL $mt, $mti, $mag01;
for ($kk=0; $kk < N-M; $kk++) {
$y = ($mt[$kk]&UPPER_MASK)|($mt[$kk+1]&LOWER_MASK);
$mt[$kk] = $mt[$kk+M] ^ (($y >> 1)&LOWER_MASK) ^ $mag01[$y & 1];
}
for (; $kk < N-1; $kk++) {
$y = ($mt[$kk]&UPPER_MASK)|($mt[$kk+1]&LOWER_MASK);
$mt[$kk] = $mt[$kk+(M-N)] ^ (($y >> 1)&LOWER_MASK) ^ $mag01[$y & 1];
}
$y = ($mt[N-1]&UPPER_MASK)|($mt[0]&LOWER_MASK);
$mt[N-1] = $mt[M-1] ^ (($y >> 1)&LOWER_MASK) ^ $mag01[$y & 1];
$mti = 0;
return;
}


=====================
Ребяты! Переведите ето, плз, на русский язык! Хоть узнаем что-нибудь про "честность" етого генератора"
      » 27/05/2001, 20:56,  yurets 
ну е мое, никак народ не успокоить :)

генератор как генератор, отличие от других - использует крутейший датчик случайных чисел (2/3 кода это он и есть), а так же сохраняет состояние этого генератора в базе, что позволяет обходиться без инициализации генератора при каждом запуске (это тоже беда всех генераторов, мало того что начинают косить, так еще и время от времени расклады повторяются)

раздает проще простого - вытягивая из колоды случайные карты.
для преферанса я проверял для него только тузов в прикупе, 25 на 100 сдач в среднем и сдает. для бриджа тестировался довольно основательно, все как и должно быть.

хотя знаю, Сашун все равно скажет что надо переделать :)
      » 27/05/2001, 21:42,  ALEZI 
Дык именно ДЛЯ НАРОДОУСПОКОЕНИЯ и прошу написать, плз, построчный комментарий!
Дабы убедить народ АЛГОРИТМОМ в ПОЛНОЙ случайности выбора конкретного расклада из ПОЛНОГО их (раскладов) набора.
А тут несколько етот процесс затруднился. Нету алгоритма, но есть зато из него следствие - код вверху.

Которые тут програмисты! Сделайте читателям послабление! Напишите етот комментарий!

А дальше я возьмусь ))

Сашун, в гостях у Алези...
      » 27/05/2001, 23:09,  yurets 
насчет случайности:
первые 2 функции есть реализация генератора Мерсенна, я уже упоминал это. если интересуют подробности - могу дать ссылку. математически доказано, что этот генератор выдает равномернораспределенные значения в диапазоне -2**31..2**31-1, периодичность - 2**19937-1, т.е. существенно больше чем число вариантов раздачи карт в префе, бридже и даже тароке (там кажется 70 карт, есть такая замечательная игра).
то что генератор написан правильно - я сравнивал его работу с образцовыми реализациями (на С), все сходится.

далее, число из диапазона -2**31..2**31-1 переводится в диапазон 0..N-1, где N - число оставшихся на текущий момент карт в колоде. в этом переводе вероятность меньших значений несколько выше (где-то на 0.000001%), чем больших, но этим я пренебрег. можно добиться и идеальной равномерности, но особого смысла в этом я не вижу, отклонение не существенное.

ну и последняя функция сначала раздает все карты подряд (7п8п...КчТч), далее случайным образом выдергивает карты из еще несданной части колоды и помещает их в сданную часть этой колоды, повторяя это столько раз сколько нужно (31 для преферанса и 51 для бриджа). когда в несданной части осталась одна карта - сдача сдана.

надеюсь достаточно подробно, даже для Сашуна? ;)))
а насчет использования для сдачи карт предыдущих расладов - смысла в этом нет абсолютно никакого, разве что экономится время на 1 цикл для сдачи карт по порядку :) хотя хуже от этого тоже не станет...
      » 28/05/2001, 01:27,  Керя 
Юра, а как вы добились того, что он так много разных чисел генерировать умеет ?
      » 28/05/2001, 09:21,  Memo 
Я не знаю PHP, но с C немного знаком :-))

Настораживают строчки:

....
$mti = N+1;
....
function genrand() {
GLOBAL $mt, $mti;
if ($mti > N) exit();
....

Похоже, всегда будет срабатывать exit?!
      » 28/05/2001, 10:05,  yurets 
Кере: повторю персонально :), этого добился не я а Мерсенн. с доказательством его равномерности и периодичности (а оно существует) я разбираться не пробовал, но алгоритм довольно известный, думаю можно доверять этим цифрам.

Memo: ($mti > N) - признак того, что генератор не инициализирован, в этом случае и срабатывает exit().
а инициализация производится в процедуре mt_regen(), в коротой устанавливается $mti=0 и которая вызывается после загрузки состояния генератора из БД. процедуры работы с БД я выкладывать не стал, но уж поверьте что они работают нормально :)
      » 28/05/2001, 12:13,  Керя 
Батенька, я ж у Вас не спрашиваю "кто ?", а спрашиваю "как ?". Мне же интересно все-таки. А если Вам трудно в доказательстве разобраться, то хотя бы ссылочку дайте, я попробую прочесть.
      » 28/05/2001, 14:22,  yurets 
Батенька, вопросы формулировать четче надо

http://www.math.keio.ac.jp/~matumoto/emt.html
      » 28/05/2001, 23:12,  yurets 
Насчет математической доказанности строгой равномерности я похоже ошибся,
строго доказана периодичность генератора.
Как написано здесь, пока не дано определение "хорошей псевдослучайности", и следовательно заявлять о строгой равномерности этого генератора нельзя. Впрочем, как и любого другого генератора. Можно лишь говорить о пригодности генератора для конкретных задач, что определяется прохождением набора соответствующих тестов.

А какие тесты нужны для генератора раскладов я знаю - это тестирование кучи раскладов. Результаты тестирования генератора на 1млн бриджевых сдач можно найти на бриджевой страничке.

PS. Жалуются тут :), что на одном из столов сдали 3 мизера подряд. И что? могло быть и 4, и 5. Другое дело, что такие вещи не должны случаться слишком часто. К тому же сдачи с мизерами были сданы генератором не подряд для этого стола, а поочередно расдавались по всему префзалу (точнее по 2м залам), и из последовательности раздаваемых сдач на один стол случайно выбрались 3 сдачи с мизерами. Проблемы в этом не вижу.
Сашун вон как-то 7 мизеров в одной пуле сыграл - так выходит у него ручной генератор закосил? :))

В общем, особо обеспокоенной общественности рекомендую попробовать собрать статистику по сдачам хотя бы за неделю, а лучше за месяц, а остальным - успокоиться и тратить свои силы на игру, а не на ... :)
Я кстати за потраченное на подобные сообщения время тоже мог бы сделать чего путнего для Гэмблера, так нет же :)
  Все темы | Тема закрыта | Новая тема | Новый опрос  
« Предыдущая тема | Перечень тем | Следующая тема »
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей: