9 увлекательных вещей, которые я узнал, программируя настольные игры

Недавно я решил, что собираюсь взять игру «Запретный остров» и записать её  в виде кода.

Думаю, это звучит странно — просто принять решение, не так ли? На самом деле это одна из частей большой цели, которую я преследую в момент обучения практическому программированию. В рамках этого путешествия я услышал отличную идею поставить перед собой серьезную задачу, которая вас интересует, и работать над ее преодолением. Решив задачу, я решил создать ИИ, который сможет играть «Запретный Остров». (И выиграть!). Здесь вы можете найти популярные игры онлайн.

Очевидно, что если вы собираетесь заставить ИИ играть в игру, вам сначала понадобится цифровая версия игры, чтобы ИИ мог играть. Я знал, что написание правил игры будет немного отвлекать, но я все равно решил попробовать. В итоге это заняло немного больше времени, чем я ожидал. Первоначально я только планировал кодировать правила игры в код, но в конце концов меня соблазнила идея написать программу, которая могла бы играть в эту игру. Превратить мои собственные автоматические мысли во время игры в код, которые могли автоматически выполняться, было довольно сложной задачей. Вот девять главных вещей, которые я узнал в этом путешествии:

Kotlin — отличный язык программирования

Я написал код этого проекта на Котлине. Я использую Kotlin на работе около шести месяцев, практикуюсь с ним в свободное время, и мне это действительно он понравился. Теперь, когда вы делаете что-то, что Kotlin в значительной степени встроил в язык, например, создание класса данных или фильтрацию списка, это дает очевидные преимущества. Я нахожу, что многие другие коды, написанные в бизнес-среде, недостаточно сложны, чтобы по-настоящему ощутить преимущества наличия функционально ориентированного языка.

Однако в этом проекте я увидел, что Kotlin действительно вышел на первый план. Было несколько раз, когда мне удавалось закодировать относительно сложную логику всего в две или три строки.

Правила простых игр на самом деле действительно сложны

Запретный остров — это не то, что я бы назвал сложной игрой. Наверное, на том же уровне, что и «Монополия». Конечно, в первый раз на то, чтобы прочитать и понять правила, потребуется 20 минут, но после этого вы можете научить им 6-летнего ребенка, и он сможет играть в них довольно профессионально.

И все же превращение этих семи страниц правил в код оказалось серьезным делом. Я воспроизвел их с 854 строками довольно краткого функционального кода и 2783 строками тестов. Это довольно солидный объем компьютерных инструкций, особенно если учесть, что инструкции могут описать те же функции менее чем в 200 строках.

Письменные правила игры могут быть неоднозначными

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

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

Люди не рассматривают все возможности

Часть работы по реализации этой игры в виде кода заключалась в реализации функции, которая возвращает все возможные действия для данного состояния. К тому времени, когда я закончил, я был поражен, во-первых, сложностью того, сколько кода требуется этой функции, а во-вторых, ее выводом: нет ничего необычного в том, что функция возвращает более 60 возможных действий, которые можно было бы предпринять. Конечно, когда я играл в игру, я никогда не думал про себя: «Хммм. У меня здесь 60 возможных ходов. Позвольте мне изучить их один за другим».

Наш мозг фантастически умеет сопоставлять шаблоны и исключать множество вариантов.

Причина, по которой я не думаю обо всех возможных вариантах одновременно, заключается в том, что я подсознательно осознаю, что многие из вариантов — безнадежные! Играя в подобную игру, человеческий разум часто имеет в виду несколько текущих целей, и я считаю, что наше подсознание выполняет сопоставление шаблонов вариантов с этими целями. В отличие от компьютера, я ищу хорошие варианты, а не все, что могу. Существует множество плохих вариантов, которые мой мозг исключает еще до того, как я думаю о них, и поэтому только потенциально выгодные варианты всплывают в моем сознании, чтобы я мог провести подробное сравнение.

Получение статистической значимости может быть действительно сложной задачей

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

Однако, продвигаясь дальше, я обнаружил, что иногда мои изменения мало улучшали результаты, а иногда новое важное правило ухудшало результаты. Какое-то время я оставался в недоумении по поводу этих аномалий и просто отказывался от, казалось бы, плохих идей. Однако после того, как это случилось несколько раз, мне стало любопытно. Мне пришло в голову запустить код проверки дисперсии на моем автомате, основанном на правилах. Вы можете догадаться, что я нашел? Когда игрок, основанный на правилах, играл случайными партиями из 1000 игр, разница в результатах между партиями была огромной! Фактически, дисперсия игрока, основанного на правилах, сошлась только после того, как я увеличил размер партии до 32000, Когда я добавил правило и увидел, что результаты ухудшаются, все, что я действительно видел, это статистический шум! Хуже того, чем правила, которые я упустил, было то, что многие правила, в которых я заметил небольшие улучшения, вероятно, также были просто статистическим шумом. Это не означало, что они были неудачниками, но у меня не было достоверных данных, подтверждающих, что это не так. Я думал, что 1000 случайных игр — это много, но оказалось, что для получения статистически значимой выборки из чего-то столь же сложного, как игровой автомат для настольных игр, требуется огромное количество точек данных.

Простые правила не помогают выиграть игру

Я несколько недель работал над своим игровым плеером, основанным на правилах. Я потратил на это большую часть поездок на поезде. Я провел над ним много часов ночью. Как вы думаете, что мне дали все эти усилия? Ну … он может выиграть … некоторые игры. К сожалению, это далеко не то удивительное решение, которое я мог себе представить, если бы вы спросили меня перед тем, как я начал, каких результатов я мог бы получить, потратив столько времени на кодирование решения. Когда мой автомат играет самую простую из простых конфигураций игры, его подход, основанный на правилах, может выиграть всего 20% игр! В самой сложной из жестких конфигураций он выигрывает всего 0,2%. Сравните это с моими собственными результатами: мне кажется, я играл в игру шесть или семь раз на самой простой конфигурации, и мой процент побед составляет 100%.

Я не думаю, что это каким-либо образом показывает, что компьютер не может хорошо выигрывать в этой игре (я бы сказал, что «хорошо» лучше всего определять как «значительно больше, чем в половине случаев»). Однако он показывает, что в подобных играх нелегко выиграть по простым правилам вида «если игра в настоящее время соответствует этому состоянию, выполните это действие». Иногда нам может казаться, что это то, что мы делаем, когда решаем, как играть в игру, но на самом деле это намного больше. Мы знаем, что может произойти в следующие несколько ходов после этого. Мы можем распознать то, что уже произошло в игре, что может повлиять на будущее состояние. Мы можем формулировать среднесрочные цели и работать над их достижением, а также можем отказаться от них, если мы видим приближение катастрофы. Следуя целям, вспоминание истории и построение перспективных прогнозов — это все, что можно добавить к автоматизированному игровому игроку, хотя и с постоянно возрастающей сложностью. Но разве не удивительно, что мы, люди, делаем эти вещи почти не задумываясь?

Игры увлекательны

Вы садитесь играть в настольную игру. Вы тратите 5–20 минут на чтение правил. Это кажется довольно простым. Вы проходите через это, находите несколько проблем и способы их преодоления, узнаете, каковы ключевые механики и как ими манипулировать для своей выгоды. Большинство игр, в которые мы играем, просты и увлекательны. Но это не так. Я имею в виду, они забавные, но не простые. Они кажутся простыми для человеческого разума, но многие игры достаточно сложны, поэтому вычислительные решения для них представляют собой серьезную проблему.

Эта проблема настолько велика, что игры дали свое название целому разделу математики, называемому теорией игр, которая на самом деле выходит далеко за рамки социальных игр и позволяет анализировать широкий спектр ситуаций, связанных с рациональным, стратегическим взаимодействием: это математика принятия решений. Фактически, многие игры и связанные с ними проблемы настолько сложны, что нам трудно понять, насколько они сложны. Что это значит? Одна из наиболее значительных нерешенных проблем в информатике — это определение того, можно ли легко решить проблемы, решения которых легко проверяются (где «легко» означает, что проверка или решение могут быть выполнены за время, которое не растет экспоненциально по мере увеличения размера проблемы). Короче говоря, мы еще недостаточно знаем о математике игр, чтобы однозначно сказать, что некоторые из них либо легко решаются, либо нелегко.

В вашей голове есть компьютер, сделанный из мяса, и он невероятно мощный

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

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *