Школоло / Говнокод #12107 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
  81. 81
  82. 82
  83. 83
  84. 84
  85. 85
  86. 86
  87. 87
  88. 88
Procedure TForm1.CreateObjects(Column, Row: Integer); // Процедура создания кнопок (ячеек).
Var
  i, j, iLeft, iTop, iRow : Integer; // Переменные, отвечающие за расположение ячеек на форме. (Кроме iRow, она содержит номер ячейки по горизонтали.)
  SpeedButton : array of TSpeedButton; // Собственно, сам массив с ячейками.
  cColumn : Char; // Номер ячейки по вертикали.
  iMine : ShortInt; // Дополнительная переменная кол-ва бомб на поле.
BEGIN
{Присваиваем начальные значения переменным. :7:}
  iLeft := 0; // Начальная позиция по горизонтали.
  iTop := 5; // Начальная позиция по вертикали.
  iRow := 1; // Номер ячейки по горизонтали.
  iMine := MineCount; // Кол-во мин на поле.
  cColumn := 'A'; // Номер ячейки по вертикали.
  SetLength(SpeedButton, Row+1); // Массив с ячейками.
{------------------------------------------ :7:}

{Создаём новые списки. :8:}
  FObjectList := TObjectList.Create; // Список с объектами.
  Form2.FMineList := TStringList.Create(); // Список с номерами мин на поле.
{--------------------- :8:}

{Главный цикл создания игрового поля :9:}
  For i := 1 to Column do // Запускаем цикл создания по вертикали.
   Begin
    For j:=1 to Row do // Теперь тоже самое по горизонтали.
     bEgin
       SpeedButton[j] := TSpeedButton.Create(Self); // Создаём очередную ячейку на поле.
       SpeedButton[j].Parent := GamePanel; // Этим параметром указываем, что ячейка принадлежит первой форме.
       SpeedButton[j].Top := iTop; // Задаём расположение ячейки по вертикали.
       SpeedButton[j].Name := cColumn + IntToStr(iRow); // Задаём имя ячейки.
       SpeedButton[j].Flat := True; // Используем св-во кнопок не отображаться на рисунке.
       SpeedButton[j].Font.Color := clBlue; // Делаем цвет текста синим.
       SpeedButton[j].Font.Style := [fsBold]; // Делаем шрифт жирным.
       SpeedButton[j].OnClick := SpeedButton1.OnClick; // Указываем, какая процедура будет вызываться при клике на ячейку.
       SpeedButton[j].OnMouseDown := SpeedButton1.OnMouseDown; // Указываем, какая процедура будет вызываться при нажатии на ячейку.
       SpeedButton[j].Left := iLeft+8; // Задаём расположение ячейки по горизонтали, смещая её на 8 пикселей вправо.
       {Устанавливаем бомбу в ячейку. :10:}
         If (iMine <> 0) and (SpeedButton[j].Name <> 'A1') then // Если кол-во бомб не превышено, то...
          beGin
           Randomize; // Генерируем список ПСЧ.
           SpeedButton[j].Tag := Random(2); // Случайным образом задаём, будет ли бомба находится в ячейке.
           If SpeedButton[j].Tag = 1 then
            begin
             Form2.FMineList.Add(SpeedButton[j].Name); // Добавляем новую запись в массив бомб.
             Dec(iMine); // Уменьшаем счетчик мин на единицу.
            end;
          enD;
       {----------------------------- :10:}
         FObjectList.Add(SpeedButton[j]);// Добавляем новую запись в массив ячеек.
         iLeft := iLeft + 24; //Увеличиваем расстояние между ячейками.
         If iRow = Row then iRow := 1 // Если номер следующей ячейки по горизонтали неправильный, то меняем его на 1.
          Else Inc(iRow); // Иначе увеличиваем номер.
     eNd;
    cColumn := Char(Ord(cColumn) + 1); // Увеличиваем номер ячейки по вертикали.
    iTop := iTop + 24; // Увеличиваем положение ячейки по вертикали.
    iLeft := 0; // Обнуляем позицию ячейки по горизонтали.
   End;
{----------------------------------- :9:}

  ImageList1.GetBitmap(0, (FindComponent('A1') as TSpeedButton).Glyph); // Загружаем спрайт в первую ячейку.
  Form2.FMineList.SaveToFile('OUTPUT.TXT'); // Сохраняем расположение мин в файл.
  MineCountLabel.Caption := IntToStr(Form2.FMineList.Count); // Показываем колво мин на поле.
END;

Function TForm1.CheckMove(X,Y : ShortString): Boolean; // Функция проверки валидности ячейки. Она должна находится рядом с текущей.
Var
 iXod, iAlf : Integer; // Вспомогательные переменные.
BEGIN
 result := false; // Презумпция вины :)
 iXod := Abs(StrToInt(Y) - StrToInt(dPos.yInt)); // Получаем расстояние до текущей ячейки по горизонтали.
 iAlf := Abs(Ord(dPos.xChr) - Ord(X[1])); // Получаем расстояние до текущей ячейки по вертикали.
 If ((iXod <= 1) and (iAlf <= 1)) and ((iXod <> 0) or (iAlf <> 0)) then result := true; // И если оно не больше одного, то разрешаем ход.
END;

Procedure TForm1.SpeedButton1Click(Sender: TObject); // Главная процедура нажатия на кнопку(ячейку).
Var
  i : Integer; // Счётчик цикла.
  cObject : TSpeedButton; // Сам объект.
  Str, j : String; // Вспомогательная переменная имени ячейки.
  Count : Integer; // Вспомогательная переменная. (стр. 160)
BEGIN
{Подготавливаем переменные :1:}
  cObject := TSpeedButton(Sender); // Получаем ячейку, на которую кликнули.
  Str := cObject.Name; // Присваиваем вспомогательной переменной имя задействованной ячейки.
  dClick.xAlf := Str[1]; // Присваиваем переменной первый символ задействованной ячейки по вертикали.
  dClick.yFlt := Copy(Str, 2, Length(Str)); // Получаем номер ячейки по горизонтали.
{------------------------- :1:}
...

По просьбам желающих. Код некогда созданной мною игрушки Сапёр. Отдельный прикол, это как потом все эти кнопки удаляются.

Запостил: Govnocoder#0xFF Govnocoder#0xFF, (Updated )

Комментарии (149) RSS

  • А, через Name передавать. Тоже нормально. В WinSight лулзы можно словить.
    Ответить
  • > // Процедура создания кнопок (ячеек).
    Блин, я думал что они вручную аккуратно разложены на форме... Цикл создания кнопок уменьшает градус говнокодности данного говокода 🙁

    > Randomize
    А вот Randomize перед каждым random'ом это то еще говнецо... Особенно если ГПСЧ инициализируется временем с точностью до мс...
    Ответить
    • Именно, мне тогда так и не удалось сделать нормальный ГПСЧ для минного поля. Приходилось играть почти на одинаковых полях. А цикл там потому, что игрок может сам настраивать количество клеток на поле.
      Ответить
  • Почти все переменные нормально названы за мелким исключением TForm1.
    bEgin~eNd //м-м даже так.

    Вообще очень настроженно отношусь к коду в котором каждая строка раскомментирована. Но тут ничего смертельного. Так, мелочи.
    Совсем не такое говно как рекламировали.
    Ответить
    • Я еще xAlf и yFlt не понял как переводятся. x и y то понятно, а вот что такое alf и flt?
      Ответить
      • > alf
        Alf сокращено от Alfavit. То есть координата клетки по вертикали. Flt координата по горизонтали. Это дополнительные значения координат.
        Ответить
        • > Alf сокращено от Alfavit.
          Резонно.

          > Flt координата по горизонтали.
          А можно английское слово, от которого это порождено?
          Ответить
          • Оно ни от чего не порождено. Я как щас помню откуда взялось "flt". Это как alf, только числовой. Тогда мне почему-то в голову взбрела первая ассоциация с числами - float. Ну я взял первую букву из этого слова и вставил её заместо первой из "alf". Вот так-то!
            Ответить
      • Там еще бульщит
        >X,Y : ShortString
        Зачем координаты строками?
        >iLeft := iLeft + 24
        >SpeedButton[j].Left := iLeft+8;
        Я такое в своё время тоже писал. Сейчас бы наверное вынес 8 в константу и танцевал от неё.
        Помню в VB была херь TwipsPerPixel или как-то так. В дельфях тоже должно быть такое, 8 - это ж не пиксели? Вот от неё бы и мерял.
        Ответить
        • > Зачем координаты строками?
          Сейчас уже не вспомню почему выбрал строки вместо чисел. Наверное, тогда мне показалось что так "компактней". Думаете есть смысл переписать под числа?
          С меджик намберами тоже всё понятно.
          Ответить
          • >Думаете есть смысл переписать под числа?
            Я бы не стал. Работает - не трогай.
            Тупая работа вроде этой не принесет пользы.
            Ответить
            • 8 и 24 это размер обычной SpeedButton. ТЗ в чём измеряется положение, а по-моему в пикселях.
              Ответить
      • Странно кстати. В обычном сапере можно ходить куда угодно, а здесь только в соседнюю к открытым клеточку?
        Ответить
          • Аа. А если мины выстроятся в цепочку и не дадут ему пройти?

            P.S. И интересно бы узнать что означают alf и flt?
            Ответить
            • У него есть инвентарь, там куча ништяков, от детектора мин, до бутылки водки, которую можно пить.
              Ответить
              • > У него есть инвентарь, там куча ништяков, от детектора мин, до бутылки водки, которую можно пить.
                А можно грабитьминировать корованы?
                Ответить
                • Корованы я не запилил, но крафтинг и прокачка есть. Даже звуковое сопровождение присутствует!
                  Ответить
                  • Так лучше выложи сиё шпиливо на ргхост - интересно заценить.
                    А то в коде говна я не вижу.
                    Ответить
                  • Хм, а что и из чего он крафтит, если на поле лежат только мины?

                    P.S. Присоединяюсь к предыдущему оратору с просьбой выложить куда-нибудь прогу.
                    Ответить
  • > Сохраняем расположение мин в файл
    Сапёр с сейвами это читерство!
    Ответить
    • Если сейв делается только при закрытии приложения и подрыве - то нет.
      Ответить
  • По мне так любой код на делфи выглядит как говно.
    Ответить
  • Dec(iMine); // Уменьшаем счетчик мин на единицу.

    Лучше вообще без комментариев, чем с такими.
    Ответить
    • От нечего делать я тогда каждую строчку прокомментировал. Даже:
      result := false; // Презумпция вины :)
      Ответить
    • Переправа переправа, берег левый берег правый. Почему-то напомнило.
      Ответить
  • Я правильно понял, что мины будут кучковаться с одного края?
    Ответить
      • Да, ещё есть вероятность того, что нужное число мин не расставится.
        Ответить
      • Кидаешь в первый 10 клеток, потом
        for i := 1 to 10 do
        swap(i, random(i+1,100));
        Ответить
        • Этот алгоритм не масштабируется до 0ля клеток. У Fai масштабируется.
          Ответить
          • Да и с ростом числа клеток на поле тоже. Так алгоритмы не записывают. Записывать в общем виде алгоритмы надо.
            Ответить
        • С большой вероятностью в первых 10ти клетках не будет бомб, особенно с ростом поля.
          Ответить
          • Мы с равной вероятностью получим любое из C(n,k) расположений мин.
            Учи матан, гумно.
            Ответить
        • Правка:
          for i := 1 to 10 do
          swap(i, random(i,100));
          то есть клетку можно поменять с самой собой.
          Иначе не сойдётся даже количество различных выхлопов ГСЧ за n итераций, будет (n-1)*(n-2)*...*(n-k)=C(n-1,k-1). А надо C(n,k)

          Нет, это не C(n,k). Короче, если все мины разные, то число их расположений будет n*(n-1)*...(n-k+1)=n!/(n-k)! . И алгоритм мой тоже имеет столько же выходов в зависимости от результатов ГСЧ.
          Чтобы доказать равномерность, надо доказать, что для каждого расположения мин существует выход алгоритма, дающий это расположение
          Ответить
          • Так как количество расположений равно количеству выходов алгоритма, то из существования выхода для каждого расположения следует то, что этот выход единственный. Тогда равномерность очевидна.
            Ответить
            • Доказывать существование выхода, дающего данное расположение, юудем по индукции. База: мин ноль, доказывать нечего.
              Переход:
              берём любое расположение k мин на поле из n клеток. Берём выход алгоритма k-1 мины для поля из n-1 клеток, который даёт нужное распложение для мин с номерами 2,3,4...k, такой выход существует по индукционному предположению.
              Смотрим, какая клетка после данной перестановки переставилась туда, куда мы хотим поставить мину 1.
              Тогда берём, ставим мину 1 на место этой клетки, делаем перестановку для (k-1) на (n-1), получаем нужную перестановку
              чтд
              Ответить
              • Вообщем тебе понравился этот алгоритм, тк легко доказывается по индукции?
                Ответить
                • Съеби в биореактор, быдлокодишка, убей себя об стенку, как Томми.
                  Ответить
                  • Откуда такой батхерт? Подруга не даёт чтоли? Рассказывай если хочешь, может мы тебе посоветуем.
                    Ответить
                      • Какой ещё матан? Это то что ты рассказываешь? Это простейшие вещи. Основы. Если для тебя это матан - иди на метан.
                        Ответить
          • Только при реализации твоего алгоритма заметил:
            > random(i,100)
            С каких пор рандом принимает несколько аргументов? Или ты свою ф-ю писал? У меня не компилится короче.
            Ответить
              • Ну блин, это псевдокод же.
                Если бы я написал Random(cell_count-i+1)+i, то что, было бы понятнее?
                Ответить
                • Поправь меня, если где неправ.
                  1. Кидаем в первые N клеток бомбы (единицы):
                  For i := 1 to MinesCount do
                    MineArray[i] := 1;

                  2. Проходимся по всему массиву и каждый элемент меняем местами с другим случайным элементом:
                  For i := 1 to High(MineArray)-1 do Swap(i, RandomRange(1,LengthOfArray));
                  Ответить
                  • > 2. RandomRange(1,LengthOfArray))
                    Как можно быть таким невнимательным
                    Ответить
                      • Да.
                        Кстати, это всё для случая нумерации от 1, ну ты понял. Так паскальнее ^^

                        > High(MineArray)
                        > LengthOfArray

                        Ты определись
                        Ответить
                        • > Ты определись
                          Использую переменную, вызывать лишний раз функцию ни к чему.
                          > случая нумерации от 1
                          А если юзать i := 0, какие подводные камни?
                          Ответить
                          • > Использую переменную, вызывать лишний раз функцию ни к чему.

                            У тебя фигня в алгоритме же. В двух местах, в которых должна быть одна и та же сущность, я вижу разные вещи.


                            Что за High(), она же только для динмассива возвращает число используемых элементов. А в динмассиве с нуля начинается.

                            > А если юзать i := 0, какие подводные камни

                            Нумерацию сдвинуть трудно?
                            Так, сколько тебе лет, каков твой стаж?
                            Ответить
                            • Я исправил. У меня везде LengthOfArray вместо High.
                              > она же только для динмассива
                              MineArray у меня динамический массив.
                              В общем, спасибо. Всё работает как надо.
                              > Так, сколько тебе лет, каков твой стаж?
                              Нискажу.
                              Ответить
                              • > MineArray у меня динамический массив.

                                И при этом ты так спокойно пошёл писать алгоритм, явно предназначенный для нумерации от 1?!
                                Ответить
                                  • Херню несёшь.
                                    Ладно, подскажу, как вообще правильно надо действовать для любых индексов начала и конца:
                                    for i := Low(a) to Pred(High(a)) do
                                      Swap(i, i+random(High(a)+1-i));
                                    Ответить
                                  • Короче, вот код. Или ты меня щас посылаешь на йух, или объясняешь что не так:
                                    Var
                                     MineArray : array of Byte;
                                    ...
                                    Procedure TMainForm.generateRandomArea(MinesCount: Integer = 20);
                                    Var
                                      i,j,LengthOfArray : Integer;
                                    
                                    Procedure SwapEx(a,b:integer);
                                    Begin
                                     MineArray[a] := MineArray[a] - MineArray[b];
                                     MineArray[b] := MineArray[a] + MineArray[b];
                                     MineArray[a] := MineArray[b] - MineArray[a];
                                    End;
                                    
                                    BEGIN
                                     LengthOfArray := High(MineArray);
                                     For j := 0 to MinesCount-1 do  MineArray[j] := 1;
                                    
                                      For i := 0 to LengthOfArray-1 do SwapEx(i, Random(LengthOfArray-i+1)+i)
                                    END;
                                    Ответить
                                    • 1. SwapEx перепиши нормально, без этой хуйни, мы не на устной олимпиаде по информатике.
                                      2. Почему LengthOfArray хранит не длину, а верхний индекс? Назови нормально. LastIndex типа там.
                                      Логика цикла перестановок правильная.

                                      И ещё, я раньше тоже индексировал массивы от 0 до Length-1, а потом Ада меня отучила от этого.
                                      Ответить
                                      • > SwapEx перепиши нормально
                                        Я тут заметил кое-что. Если использовать 1й вариант SwapEx (как в моём коде выше), то кол-во мин будет каждый раз варьироваться от 17 до 20. А если переписать:
                                        Procedure SwapEx(a,b:integer);
                                        Var p: integer;
                                        begin
                                          p :=  MineArray[a];
                                          MineArray[a] :=  MineArray[b];
                                          MineArray[b] := p;
                                        End;

                                        то всё норм. Почему так?
                                        Ответить
                                        • Потому что ты пиздец, про подвобные камни кулхацкерного метода обмена значений учат на 1м курсе.

                                          Вот есть у тебя код
                                          a:=a-b;
                                          b:=a+b;
                                          a:=b-a;
                                          а теперь представь, что a и b являются ссылками на один и тот же адрес. После первой же строки они обе обнуляются.
                                          Про индексы аналогично.
                                          Про xor вместо +- аналогично.
                                          Ответить
                                          • не ссерьтесь, девочки
                                            вы оба занимаетесь преждевременной оптимизацией
                                            да еще и на паскале
                                            Ответить
                                              • ты померил профилировщиком? тормозит? нет? тогда ты занимаешься преждевременной оптимизацией
                                                Ответить
                                                • Кроме профилировщика есть ещё такая штука, как оценка алгоритмической сложности.
                                                  Ответить
                                                    • Это я тонко намекаю на то, что чтобы отличить говно от неговна, не обязательно иметь под рукой специальные программы.
                                                      Ответить
                                        • Вот молодежь пошла... нет, чтобы подебажить процедуру на разных примерах, самому разобраться, что же в ней не так... порадоваться тому, что сам справился с проблемой. Нет, надо запостить нубовопрос на форум и ждать пока мамочка Тарас расскажет что же тут не так.

                                          > Потому что ты пиздец
                                          Два чаю этому сэру.
                                          Ответить
      • 1. Заполняешь всё поле минами
        2. Если мин больше чем нужно - удаляешь случайную.
        3. Если ровно столько сколько нужно - выходишь из цикла.
        4. В противном случае переходишь на шаг 2.

        Плюс алгоритма в простоте и том, что для входных данных только одно условие - число мин должно быть неотрицательным числом.
        Ответить
        • > 2. Если мин больше чем нужно - удаляешь случайную.
          А как правильно брать случайные числа? Тут выше говорили что Randomize преде Random`ом говно.
          Ответить
          • Randomize нужно вызывать один раз при старте проги. Дальше тупо Random'ы по необходимости.
            Ответить
            • Randomize инициализирует ГСЧ текущим временем. Random выдаёт случайное число и переводит ГСЧ в новое состояние
              Ответить
          • > Randomize преде Random`ом говно.

            Random сам по себе говно, ищи вихрь мерсена, а то как же играть в сапёра, без равномерного распределения мин?
            Ответить
            • Подозреваю что рандом нечто подобное и использует. Вот правда не люблю рандомы с глобальным состоянием.
              А вот твистер из крестов с локальным состоянием в объекте или рандом в Хаскеле - норм
              Ответить
              • > Подозреваю что рандом нечто подобное и использует.
                Не стоит подозревать. Там какой-нибудь тупейший конгруэнтный генератор в духе:
                seed := seed * 1005001 + 12345;
                result := seed mod max;
                Если есть желание - загляни в исходники делфевого RTL, благо они открыты.
                Ответить
                • А подумать?
                  То, что ты сказал, выдаст период длины max
                  Ответить
                  • Константы взяты от балды. Лень открывать википедию и брать правильные.
                    Ответить
                    • Я не про константы. А про способ получения результата по сиду.
                      Ответить
                      • Да я и первую то строку криво написал. Там должен еще стоять модуль не кратный двум. Иначе оно и до max не дотянет.

                        И к тому же я забыл, как правильно преобразовывают генератор чисел от 0 до N в генератор от 0 до M ;(

                        Помню, что что-то типа буферной переменной, из которой делением извлекаются случайные числа нужного размера, а когда битов остается мало - в нее набиваются новые, взятые из генератора.
                        Ответить
                        • > И к тому же я забыл, как правильно преобразовывают генератор чисел от 0 до N в генератор от 0 до M ;(

                          Не поверишь
                          Seed*M/N

                          В Паскале именно так и делается, так как там N=2^32, то делается mul, потому возвращается содержимое edx.
                          В сишке возвращаются старшие 16 бит сида, поэтому rand()%n не зацикливается слишком быстро.
                          Ответить
                          • > Seed*M/N
                            Ну да, согласен, для конгруэнтного говногенератора такой способ более чем адекватен.

                            Но распределение получается чуть-чуть перекошенным. Если N не делится на M, то некоторые числа выпадают немного чаще остальных.

                            Портить хорошие генераторы типа вихря мерсена таким преобразованием нехорошо, поэтому я и пытался вспомнить как это делается с равномерным распределением (см. статью ниже).
                            Ответить
                            • Да, random(3), например, будет выдавать одно число примерно на одну миллиардную чаще (или реже), чем другие.
                              Ответить
                              • А random(100500), например, будет выдавать примерно 700 чисел на две стотысячных реже чем другие...
                                Ответить
                              • А в random(1005494) почти половина чисел (если быть точным - 502422 штуки) будут выпадать на 0.00023 чаще чем другие.
                                Ответить
                        • Hi GVNKD,

                          The method does work, but... с какого для тасования колоды карт перестало хватать линейного конгруэнтного PNRG mod RANGE_MAX + RANGE_MIN?
                          Ответить
                          • > с какого для тасования колоды карт перестало хватать линейного конгруэнтного PNRG mod RANGE_MAX + RANGE_MIN
                            С того дня как всякие онлайн казино должны проходить сертификацию на труъ рандомность. Вот и приходится покупать аппаратные источники труъ рандома, и использовать такие методы...
                            Ответить
                            • > онлайн казино
                              ждем некогда созданную мною игрушку Сапёр онлайн, с мультиплеем и на бабки
                              Ответить
                            • > покупать аппаратные источники
                              Вроде как можно собрать самому даже. Нужен только АЦП, шумящий диод и контроллер. Для серьёзных применений не годится, конечно.
                              Кроме того, можно насолить впрок. Получил сорок гигабайт чистой энтропии и выбирай себе. Главное - не попадаться с этим правоохренителям на глаза.
                              Ответить
                              • > Вроде как можно собрать самому даже.
                                Ну если надо было бы проходить сертификацию - я бы все-таки купил готовый.

                                P.S. Хотел одно время спаять такой генератор на стабилитроне - ни один стабилитрон шуметь не захотел ;(
                                Ответить
                          • К слову о тарасовании колоды карт и линейном конгруэнтном ГПСЧ: http://ru.pokerstrategy.com/forum/thread.php?threadid=155416.

                            Здесь как раз описан частный случай алгоритма, который приводил выше Тарас (ка пример правильного алгоритма). А так же описаны последствия хренового тасования: Авторы рассказывают, что написали программу, которая рассчитывала полный расклад, увидев первые пять карт, за одну секунду. А для покера это само собой эпик фейл.
                            Ответить
                            • В начале он описал очевидные нубские ошибки.
                              Если их исправить, то рассказ в конце станет невероятным, т.к. нет реальной возможности узнать сколько было в LSB таймера на момент старта и сколько раундов RNG выполнилось до начала анализа.
                              Ответить
                              • > сколько раундов RNG выполнилось до начала анализа.
                                На самом деле даже если пофиксить те баги, и оставить стандартный конгруэнтный PRNG, то проблема останется.

                                Перед началом алгоритма сид может находится в одном из 2^32 состояний, а
                                4млрд вариантов это не такое уж большое число. Это намного меньше, чем 52!.

                                Да, в точности угадать расклад уже не удастся. Если мы играем колодой из 52 карт, то 5 карт попадут нам на руки одним из 311875200 способов. Поделим 2^32 на это число, и получим в районе 14 раскладов. Для ускорения вычислений можно составить таблицу, пусть она и будет весить гигабайты, зато поиск будет мгновенным.

                                Итого - посмотрев на полученные карты, и не зная начального состояния генератора, мы получаем примерно 14 вариантов расклада. А это очень неплохой чит для такой игры как покер.
                                Ответить
        • Мой рабочий и эффективный алгоритм даже не плюсанули, а эту квадратичную парашу плюсанули.
          Ответить
          • Ай, не плачь, не плачь, не плачь,
            Я куплю тебе калач.
            Если будешь плакать -
            Куплю худой лапоть!
            Ответить
          • Мой тоже рабочий, при этом простой и даёт хорошее распределение. KISS, помнишь?
            Ответить
            • Твой нихуя не простой.
              У тебя быдлоалгоритм, он тормозит, он долго пишется.
              Мой алгоритм быстро работает, быстро пишется, даёт идеальное распределение, но чтобы это понять, нужен матан.
              Это как сортировка перебором и квиксорт.
              Ответить
              • Я не знаю, какой долбоёб проминусовал, но тут КИСС применять - это пиздец.
                Это всё равно что удалять плохие элементы из массива по одному (со сдвигом хвоста), потому что это просто и понятно. А на просьбу сделать нормально (через проход с двумя итераторами) говорить, что это сложно и нарушает КИСС.
                Я так понимаю, у быдлокодеров появился новый флаг?
                Раньше они писали говно, потому что "Дейкстра сказал не оптимизировать", теперь они пишут говно, потому что "в Википедии написано не усложнять".
                Какую идиому не придумай, а быдлокодер её всё равно в качестве отмазки применит.
                Ответить
                • > какой долбоёб проминусовал
                  Нейтрализовал.

                  > У тебя быдлоалгоритм, он тормозит, он долго пишется.
                  Может быть. Я предложил свою версию, почему ты в меня какашками кидаешься не знаю.

                  > Мой алгоритм быстро работает, быстро пишется
                  Да, я посмотрел твой алгоритм, действительно задумка хорошая. И он даже проще.

                  P.S. А людей незнакомых с ходу быдлокодерами называть перестань..

                  P.P.S. По-поводу "квадратичности" твой алгоритм отрабатывает n операций, где n - необходимое количество мин, а мой - (m-n), где n - количество мин, а m - площадь поля.

                  Таким образом, если нужно разместить 90 мин на поле в 100 клеток, мой алгоритм будет быстрее.

                  А если необходимо раместить 1 мину на поле в 1000 клеток - тут твой лидер.
                  Ответить
                  • > P.P.S. По-поводу "квадратичности" твой алгоритм отрабатывает n операций, где n - необходимое количество мин,

                    Расскажи, как ты делаешь операцию "убрать случайную мину".

                    > P.S. А людей незнакомых с ходу быдлокодерами называть перестань..

                    Я тебя быдлокодером не называл, я сказал только, что у тебя быдлоалгоритм, и что быдлокодеры любую идиому применят в качестве оправдания своему быдлокоду.
                    Ответить
                    • > Расскажи, как ты делаешь операцию "убрать случайную мину".
                      Ну например так:
                      1. Заводим дополнительный массив, в который в начале алгоритма помещаем координаты всех мин;
                      2. Генерируем случайное число, используем его как индекс в массиве, получаем координаты мины которую надо удалить;
                      3. Берем последний элемент массива и переставляем его на место только что поюзанного;
                      4. ???
                      5. Удаление мин за О(1) при O(n) памяти, PROFIT
                      Ответить
                      • Ну это да, но мне интереснее, как Fai собрался реализовывать.
                        Ответить
                      • > 1. Заводим дополнительный массив, в который в начале алгоритма помещаем координаты всех мин;
                        Т.е. сначала массив будет полностью забит единицами (бомбами), или как? И такой массив у меня уже есть, ничего заводить не надо.
                        Ответить
                        • Да, и в итоге приходим к моему же алгоритму, но с другого конца.
                          Ответить
                          • Твой алгоритм это кстати генерация перестановки последовательности (1,1,...,1,0,0,...,0), в которой k единиц и n-k нулей, из которого выкинута бесполезная перетасовка хвоста нулей.
                            Ответить
                        • Забей на это квадратичное говно, Тарас привел хороший алгоритм:
                          http://govnokod.ru/12107#comment160674

                          > Куда конкретно кидать?
                          Хм. Очень странный вопрос. Как-нибудь нумеруете все клетки поля по порядку. В первые K клеток помещаете мины...

                          P.S. А если все-таки хочется поюзать алгоритм Fai - его лучше немного перевернуть:

                          1. Инициализируем само поле нулями, а дополнительный массив координатами всех клеток:
                          field = {{0, 0}, {0, 0}}
                          free = {(1,1), (1,2), (2,1), (2,2)}
                          freecnt = 4

                          2. Для каждой мины
                          2.1. Генерируем случайное число rnd в диапазоне 1 . .freecnt (например 3)
                          2.2. free[rnd] покажет координаты клетки, в данном случае (2,1), помещаем в нее мину:
                          field = {{0, 0}, {1, 0}}
                          2.3. Переставляем free[freecnt] на место free[rnd], уменьшаем freecnt на единицу

                          P.P.S. Код приводить не буду из образовательных целей.
                          Ответить
          • >а эту квадратичную парашу плюсанули
            Зависть плохое чувство.
            И алгоритм Fai не квадратичный (но n в О(n) побольше).
            Ответить
            • > 2. Если мин больше чем нужно - удаляешь случайную.

              Расскажи мне про эту часть подробнее.

              > 3. Если ровно столько сколько нужно - выходишь из цикла.
              > цикла
              Ответить
        • > выходишь из цикла
          > Плюс алгоритма
          Плюс в том, что оригинальный баг починен и мины теперь кучкуются с другого края 🙂
          Ответить

Добавить комментарий

Переведи на "PHP", guest!

    А не использовать ли нам bbcode?


    8