Дополнил описание галадки Шеннона

This commit is contained in:
2020-03-22 19:00:49 +03:00
parent 60c202325e
commit d4c1dc743b
9 changed files with 130 additions and 409 deletions

View File

@ -8,17 +8,130 @@ scripts:
- /static/predictor.js
---
Правила игры простые. Робот пытается предсказать, что выберет человек: чет или нечет.
Если предсказание удалось, робот получает очко, а счет уменьшается на единицу.
Если же предугадать выбор не удалось, то очко достается человеку, а счет увеличивается.
Игрок победит, если доберется до 50 очков. Но когда счет опустится до -50, победа будет
за железякой.
В студенческое время я наткнулся на интересную статью об [игре "Чет-нечет"](game)
на домашней страничке пользователя [ltwood](ltwood).
Чтобы выбирать вариант с клавиатуры, кликните внутри серой рамки,
а потом пользуйтесь клавишами "1" - нечет или "2" - чет.
Правила очень простые. Игрок загадывает один вариант из двух: "чет" или "нечет",
а оппонент пытается угадать выбор игрока. Если угадать не удалось, то очко получает
загадавший, а если угадать получилось - то угадывающий. Кто первым наберет 20 очков,
тот и молодец!
- [Код гадалки](https://github.com/anwinged/homepage/blob/master/source/_assets/predictor/demo.vue)
Кажется, что в этой игре все случайно. Случайно загадывается число, потом случайно
второй игрок пытается угадать что же было загадано. Я очень сильно удивился, когда
попробовал поиграть в эту игру с программой и за десять попыток так ни разу и не выиграл.
Парадокс в том, что мы умаем_ что загадываем числа случайно. На самом деле все не так,
и последовательность загаданных чисел не случайна.
Исходного кода оригинальной гадалки в открытом доступе нет, есть только [описание алгоритма](algo),
по которому я сделал свою реализацию на TypeScrypt.
## Демоверсия
Попробуйте набрать 50 очков и выиграть. Чтобы выбирать вариант с клавиатуры,
кликните внутри серой рамки, а потом пользуйтесь клавишами "1" - нечет или "2" - чет.
---
<div id="app"></div>
---
## Как Это работает
Математически алгоритм на [странице](algo) сайта ltwood.
Я рассмотрю простой пример, чтобы показать принцип.
В основе алгоритма находится популяция "демонов" - автоматов, которые на основании ходов
игрока и предсказанных значениях выдают новое предсказание. Демонами управляет
супервайзер. Задача супервайзера в том, чтобы опросить всех демонов, выбрать ответ
от одного их них, а после получения ответа игрока пометить тех, кто выдал правильный ответ.
Алгоритм состоит из двух шагов:
- предсказать следующих ход игрока;
- учесть реальный ход игрока, добавив веса тому демону, который предугадал ход.
Рассмотрим работу на примере одного демона.
Пусть у нас есть демон, который смотрит на последний хода игрока
и на свое последнее предсказание.
Строим два вектора:
- `[<1 ход демона>, <1 ход игрока>, 0]`
- `[<1 ход демона>, <1 ход игрока>, 1]`
В самом начале, когда у демона нет никакой информации о ходах игрока, эти векторы
будут выглядеть как `[0]` и `[1]`. Но с накоплением данных, они всегда будут каждый
по 5 элементов.
После чего смотрим, который из таких наборов в прошлом приносил победу чаще,
и соответственно выбираем или вариант с 0, или с 1.
После получения действительного хода игрока, мы увеличиваем вес того набора,
который оказался верным. И далее снова предсказываем ход.
Теперь с числами.
#### Ход 1
У демона нет информации, наборы `[0]` и `[1]` равнозначны, выбираем `[0]`,
а значит предсказываем ход игрока 0.
Игрок загадывал 1. Обновляем веса:
```
[0] = 0
[1] = 1
```
#### Ход 2
Строим векторы на основе последних ходов:
```
0: [0, 1, 0]
1: [0, 1, 1]
```
Для этих векторов тоже еще нет весов, так что снова выбираем первый, предсказываем 0.
Игрок снова выбрал 1. Обновляем веса (помним, что еще были прошлые вектора из одного элемента):
```
[0] = 0
[1] = 1
[0, 1, 0] = 0
[0, 1, 1] = 1
```
#### Ход 3
Картина такая же, как на втором ходу, но отличие в том, что у нас есть веса с прошлого хода:
```
0: [0, 1, 0] - 0
1: [0, 1, 1] - 1
```
Выбираем вариант 1, игрок снова выбирает 1. Предсказание удалось!
## Расширение алгоритма
Это был самый элементарный вариант. Понятно, что на таком далеко не уедешь,
и никого не обыграешь. Чтобы хорошо предугадывать ходы игроков, используется
несколько демонов с разной величиной просматриваемой истории. Следит за ними
"супервайзер", который ведет для каждого демона рейтинг. На основе этого рейтинга
выбираются ответы тех демонов, которые были наиболее успешны в своих предсказаниях.
## Ссылки
- [Код гадалки](repo)
- [Описание алгоритма](algo)
- [Описание игры у ltwood](game)
[ltwood]: https://sites.google.com/site/ltwood/
[game]: https://sites.google.com/site/ltwood/projects/heshby
[algo]: https://sites.google.com/site/ltwood/projects/heshby/algorithm
[repo]: https://github.com/anwinged/predictor