[Из песочницы] О ценности карт в игре «Пьяница»

В последнее время я много играю со своим 5-летним сыном в карточную игру «Пьяница». И он, и я радуемся, когда побеждаем, и огорчаемся, когда проигрываем.

В какой-то момент я задался вопросом: какова «финансовая» ценность каждой из карт в «Пьянице»? Так как Шестерка бьет Туза (см. вариант правил под катом), то система ценностей в «Пьянице» циклична, и ответ неочевиден. Например, ценнее ли Семерка Шестерки? Семерка бьет Шестерку — значит да! Но с другой стороны, каждая из них бьет только одну другую карту в игре (Семерка — Шестерку, а Шестерка — Туза) — значит они равны по ценности? Но Туз, побитый Шестеркой, сам по себе гораздо ценнее чем Шестерка, побитая Семеркой — значит Шестерка ценнее?!

Я решил подвести математическую модель под анализ ценности карт в «Пьянице». Результаты получились самые неожиданные.
Для начала, вот правила нашего варианта этой игры:

  • В игре участвуют 2 игрока.
  • 36 карт (от шестерок до тузов) раздаются поровну.
  • Каждый игрок снимает верхнюю карту своей колоды и кладет ее лицом вверх — происходит «сражение». Победивший в сражении игрок кладет все карты сражения под низ своей колоды.
  • Победитель в сражении определяется по обычному старшинству карт (сверху вниз): Туз, Король, Дама, Валет, Десятка, Девятка, Восьмерка, Семерка, Шестерка. Есть только одно очень важное исключение: Шестерка побеждает Туза.
  • Если в сражении участвуют одинаковые карты (например, две десятки), то происходит «спор»: поверх «спорящих» карт лицом вниз кладутся еще по карте (они являются пассивными заложниками спора), и потом лицом вверх еще две карты которые вступают в сражение. Победитель забирает себе все карты спора.


Как понятно из правил, победа в этой игре зависит исключительно от везения — победитель определяется раздачей карт, так как от игроков вообще ничего не зависит.

Итак, как мы можем определить «ценность» карты в «Пьянице»? Я решил определить ценность карты через ожидаемое количество карт которые эта карта принесет если игра будет продолжаться бесконечно долго.

Начнем с простой задачи: определения ожидаемого количества карт только для Шестерки и только одного сражения. В колоде 36 карт, значит, если мы ходим Шестеркой, она вступает в сражение с другой (случайно выбранной) картой из оставшихся 35ти. Что может произойти? С вероятностью в 4/35 выпадет Туз, и тогда мы получим и Шестерку, и Туза. С вероятностью в 3/35 выпадет еще одна Шестерка, и произойдет спор —, а так как мы предполагаем абсолютно случайный расклад, то мы с равной вероятностью либо выиграем, либо проиграем его, а значит, что в среднем ожидается, что наша Шестерка останется у нас. Во всех остальных случаях мы теряем шестерку. Итого, ожидаемое кол-во карт для Шестерки после одного сражения: 7/35 Шестерки + 4/35 Туза.

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

Шестерка Семерка Восьмерка Девятка Десятка Валет Дама Король Туз
Шестерка 7/35 0 0 0 0 0 0 0 4/35
Семерка 4/35 7/35 0 0 0 0 0 0 0
Восьмерка 4/35 4/35 11/35 0 0 0 0 0 0
Девятка 4/35 4/35 4/35 15/35 0 0 0 0 0
Десятка 4/35 4/35 4/35 4/35 19/35 0 0 0 0
Валет 4/35 4/35 4/35 4/35 4/35 23/35 0 0 0
Дама 4/35 4/35 4/35 4/35 4/35 4/35 27/35 0 0
Король 4/35 4/35 4/35 4/35 4/35 4/35 4/35 31/35 0
Туз 0 4/35 4/35 4/35 4/35 4/35 4/35 4/35 31/35


Очевидно, что недостаточно учесть одно сражение, чтобы определить ценность карты. Например, у Шестерки есть шанс выиграть Туза, который сыграет в какой-то момент в будущем и, в свою очередь, имеет шанс выиграть другие карты. Как получить подобную матрицу, но с ожидаемыми кол-вами карт через два сражения? Ответ оказывается до изумления простым — надо просто умножить эту матрицу на саму себя! (Основы матричного умножения: чтобы получить элемент (X, Y) результата умножения, надо скалярно умножить ряд Х первой матрицы на колонку Y второй, то есть попарно перемножить соответствующие элементы этих двух векторов и результаты сложить).

Например, вероятность начать с Шестерки и через 2 сражения держать на руках Шестерку — (7/35)^2, так как Туз, потенциально выигранный в первом сражении никак не увеличивать шансов получить Шестерку во втором. Однако, тот же Туз увеличивает шансы получить каждую из остальных карт во втором сражении —, но ожидаемые кол-ва карт для Туза во втором сражении умножаются на вероятность получить Туза в первом сражении (4/35). И т.д.

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

Итак, совсем немного руби кода:

require 'matrix'
# Матрица ожидаемых кол-в для одного сражения
m1 = Matrix[
     [7.0/35, 0, 0, 0, 0, 0, 0, 0, 4.0/35],
     [4.0/35, 7.0/35, 0, 0, 0, 0, 0, 0, 0],
     [4.0/35, 4.0/35, 11.0/35, 0, 0, 0, 0, 0, 0],
     [4.0/35, 4.0/35, 4.0/35, 15.0/35, 0, 0, 0, 0, 0],
     [4.0/35, 4.0/35, 4.0/35, 4.0/35, 19.0/35, 0, 0, 0, 0],
     [4.0/35, 4.0/35, 4.0/35, 4.0/35, 4.0/35, 23.0/35, 0, 0, 0],
     [4.0/35, 4.0/35, 4.0/35, 4.0/35, 4.0/35, 4.0/35, 27.0/35, 0, 0],
     [4.0/35, 4.0/35, 4.0/35, 4.0/35, 4.0/35, 4.0/35, 4.0/35, 31.0/35, 0],
     [0, 4.0/35, 4.0/35, 4.0/35, 4.0/35, 4.0/35, 4.0/35, 4.0/35, 31.0/35]
]
# Матрица ожидаемых кол-в после 1000 сражений (m1 в степени 1000)
m1000 = m1 ** 1000
# (значения округлены) => Matrix[[0.0667, 0.0667, 0.0667, 0.0667, 0.0667, 0.0667, 0.0667, 0.0667, 0.0667], [0.0095, 0.0095, 0.0095, 0.0095, 0.0095, 0.0095, 0.0095, 0.0095, 0.0095], [0.0127, 0.0127, 0.0127, 0.0127, 0.0127, 0.0127, 0.0127, 0.0127, 0.0127], [0.0178, 0.0178, 0.0178, 0.0178, 0.0178, 0.0178, 0.0178, 0.0178, 0.0178], [0.0267, 0.0267, 0.0267, 0.0267, 0.0267, 0.0267, 0.0267, 0.0267, 0.0267], [0.0444, 0.0444, 0.0444, 0.0444, 0.0444, 0.0444, 0.0444, 0.0444, 0.0444], [0.0889, 0.0889, 0.0889, 0.0889, 0.0889, 0.0889, 0.0889, 0.0889, 0.0889], [0.2667, 0.2667, 0.2667, 0.2667, 0.2667, 0.2667, 0.2667, 0.2667, 0.2667], [0.4667, 0.4667, 0.4667, 0.4667, 0.4667, 0.4667, 0.4667, 0.4667, 0.4667]]


Обратите внимание, как через некоторое кол-во сражений все ожидаемые кол-ва карт для одной карты становятся одинаковыми — так как (из-за циркулярной системы ценностей) в конце концов мы можем выиграть все карты, то ожидаемые кол-ва для всех карт сходятся к одному числу. Теперь осталось совсем немного — складываем все числа в каждом ряду чтобы узнать «ценность» каждой из карт (т.е., ожидаемое число карт после 1000 сражений):

m1000.row_vectors.map {|row| row.reduce(&:+).round(3)}
# [0.6, 0.086, 0.114, 0.16, 0.24, 0.4, 0.8, 2.4, 4.2]


Для наглядности:

Шестерка Семерка Восьмерка Девятка Десятка Валет Дама Король Туз
Ценность 0.6 0.086 0.114 0.16 0.24 0.4 0.8 2.4 4.2


Неожиданные выводы:

  • Ценность Шестерки лежит между Валетом и Дамой!
  • Только у Короля и Туза ожидаемое конечное кол-во карт превышает 1 (то есть, ожидается позитивный ROI).

© Habrahabr.ru