MahjongSoft.ru


Home | Софт | Статьи и аналитика | Онлайн Маджонг Калькулятор
Алгоритм расчёта руки | Алгоритмы рассадки

Алгоритм расчёта руки в спортивном маджонге.

Под расчётом руки понимаем определение фанов в руке.

Представление руки:

  1. Объявленные комбинации. То, что игрок объявил во время игры. Определяются следующими значениями:
  2. Закрытые кости в руке. Кости, которые на момент выигрыша оставались закрытыми.
  3. Ранг выигрышной кости.
  4. Откуда пришла выигрышная кость (варианты: со стены или с дискарда).
  5. Дополнительные признаки особых ситуаций в игре:
  6. Ветра места и раунда (имеют значение только в случае, если рука содержит хотя бы один панг или конг ветров).

Вышеприведённых значений достаточно для однозначного определения всех фанов в руке (в т.ч. если возможны несколько вариантов раскладки руки по комбинациям и фанам).

Собственно этапы алгоритма:

  1. Процедура "парсинга" руки, т.е. синтаксического разбора закрытых тайлов в руке и представление всей руки в виде набора комбинаций.
  2. Рука в MCR может быть представлена как в виде "регулярной" руки, т.е. состоящей из 4 сетов (чоу, панг, конг) и одной пары, так и в виде специальных рук. К специальным рукам относятся:

    Сама процедура построена по принципу рекурсии, т.е. если на входе процедуры выясняется, что все закрытые кости в руке уже распределены по комбинациям, то объявляем получившиеся комбинации одним из вариантов устройства руки. Если присутствуют закрытые кости, то берём первую закрытую кость и пытаемся пристроить её в чоу, панг или пару (естественно, что конгов в закрытой части руки быть не может). Если получается, то рекурсивно продолжаем разбор получившейся руки, если не получается - откатываемся назад. В случае, если количество закрытых костей равно 14 (т.е. вся рука закрыта, кроме возможно выигрышной кости), то дополнительно проверяем на специальную руку, а если количество закрытых костей больше или равно 9 проверяем на наличие в руке переплетённого ряда (который описывается, как некие специальные типы комбинаций).

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

    Нетривиальные моменты процедуры парсинга:

  3. Определение количества ожиданий.
  4. Для этого используется вышеприведённая процедура парсинга. Просто изымаем выигрышную кость и, добавляя в цикле все возможные ранги костей в качестве выигрышной проверяем, получилась ли валидная рука, т.е. рука, состоящая из комбинаций, в т.ч. специальных. Замечание. Количество ожиданий считается без учёта выхода костей, т.е. перебираем именно ВСЕ ранги, даже если все кости данного ранга уже вышли в дискард или находятся в руке (пятые кости). На выходе процедуры получаем количество ожиданий.

  5. Определение фанов.
  6. Процедура строится с учётом "совместимости" фанов. Для определения совместимости использовалась таблица значений логического типа (т.е. совместим - не совместим). Размерность таблицы - половина от 80*80 (т.е. мы не проверяем совместимость фанов самих с собой и таблица симметрична относительно диагонали, т.ч. можем использовать только половину значений). Для каждого фана написана специальная функция, которая для заданной руки (уже представленной в виде набора комбинаций) выдаёт на выходе значение, присутствует ли данный фан в руке (в общем случае - количество таких фанов). Сам алгоритм определения фанов в руке построен так:

    На выходе процедуры получаем массив количества фанов в руке, из которого путём суммирования легко вычислить количество очков в руке (а также количество очков не включая цветы/сезоны, что нужно для определения выигрыша)

    Некоторые замечания по алгоритму: