Случайная выборка с учетом веса

Один из распространенных приемов в игровой логике – использование элемента случайности. Он используется, например, при машинной генерации уровней, лабиринтов, или когда на локации появляются случайные враги или бонусы. При этом зачастую требуется выбрать случайный объект из какого-либо списка с учетом того, что некоторые из них имеют большую вероятность выбора, чем другие – то есть, имеют больший “вес”.

Я написал особую реализацию алгоритма такой выборки – она работает не с обычными массивами, а с перечислениями (enum). В шаблон функции передаются два перечисления – самих элементов и их весов. Этот пример иллюстрирует также богатые возможности метапрограммирования, CTFE и интроспекции в D.

import std.stdio;
import std.traits;
import std.random;
import std.algorithm;

T weightedRandomEnum(T, W)()
    if (isNumeric!W &&
        is(T == enum) && is(W == enum) && 
        EnumMembers!T.length == EnumMembers!W.length)
{
    enum members = [EnumMembers!T];
    enum weights = [EnumMembers!W];
    enum weightsSum = reduce!("a + b")([EnumMembers!W]);
    
    auto randomNumber = uniform(0, weightsSum);
    
    foreach(i, weight; weights)
    {
        if (randomNumber < weight)
            return members[i];
        else
            randomNumber -= weight;
    }
    
    assert(0, "Should never get here");
}

enum Color
{
    Red, Yellow, Green, Blue
}

enum Weights
{
    Red = 100, 
    Yellow = 20, 
    Green = 20, 
    Blue = 5
}

void main()
{
    foreach(i; 0..10)
        writeln(weightedRandomEnum!(Color, Weights));
}

Обновление dlib

Состоялось серьезное обновление набора библиотек dlib. В числе нововведений:

  • Появилась начальная поддержка быстрого преобразования Фурье (FFT) в dlib.image. Возможна фильтрация и свертка изображений (со стороной 2^n) в частотной области;
  • Обновлен пакет dlib.math, добавлена реализация комплексных и дуальных чисел, а также внесены исправления и дополнения в dlib.math.matrix3x3 и dlib.math.matrix4x4;
  • Обновлен пакет dlib.geometry, добавлен класс ориентированных боксов (OBB), трехмерных треугольников и полигональных мешей. Реализована проверка на пересечение между сферой и треугольником, а также сферой и OBB. Добавлен модуль dlib.geometry.bezier с реализацией кривых Безье.

Иллюстрация FFT-свертки: быстрое синтетическое боке (оптическое размытие):

Изменения доступны в ревизии r21 и выше. В ближайшем будущем ожидается первый релиз проекта.

http://code.google.com/p/dlib/

Дао программиста

Некоторые из принципов, которых я придерживаюсь в своей работе, можно выразить в виде вот таких афоризмов:

1. Лучшая программа – это та, которая не была написана.

2. Простота – мать надежности.

3. Сложное должно быть простым.

4. Обычный программист думает: “Как сделать так, чтобы оно работало?”
   Хакер думает: “Как сделать так, чтобы оно не сломалось?”
  
5. Оптимизация – это зло.

6. Если программа падает, в ней есть ошибка.
   Если программа не падает, в ней все равно есть ошибка.
   Просто она еще себя не проявила.
  
7. Защита от дурака важнее защиты от недоброжелателя.

8. Хороший код не нуждается в комментариях.

9. Красивое решение – правильное решение.

10. Улучшить порой сложнее, чем переписать заново.

Пример физики на движке Chipmunk

Пример рисования мышью многоугольников, которые сразу же начинают “жить” в физическом мире. В качестве физического движка используется ChipmunkD – прямой порт Chipmunk на D. Демка может быть использована в качестве основы для physics-based 2D-игры. Единственное ограничение – поддерживаются только выпуклые многоугольники, неконвексная геометрия просто отсеивается и не тесселируется до простых форм.

В архиве – исходники и сборки для Win32 и Linux x86:
polyshaper-all-platforms.zip (1.16 МБ)

Внимание! Пример писался достаточно давно – исходный код, скорее всего, не скомпилируется современными версиями DMD без дополнительных “танцев с бубном”.

Обновление dlib

Была значительно обновлена коллекция библиотек dlib: добавлены новые модули в пакет geometry (реализация AABB и сфер, а также пересечений между ними), исправлен баг с нахождением обратной матрицы 4×4, добавлен модуль dlib.math.matrix3x3, а также несколько полезных функций для векторов, матриц и кватернионов. Изменения доступны в ревизии r12 и выше.

http://code.google.com/p/dlib/