Pull to refresh

Comments 31

UFO just landed and posted this here
Очень просто проиграть, когда ИИ ставит вместо моего крестика свой нолик (да-да, он так может) :(
ИИ мстит за ходы m0nhawk'a, а если серьезно, в ходе тестов у меня не случалось такой ситуации, но я постараюсь понять в чем дело.
Проявляется, когда большая часть поля заполнена. Особенно на «агрессивной» стратегии.
UFO just landed and posted this here
Да, есть такой момент, выигрывайте честно, это куда интересней(да-да, и так можно).
Ух, так у все управление сессиями базируется на том, что клиент будет слать запросы в рамках одного соединения?

Достаточно чуть дольше думать над ходом, браузер закрывает соединение и начинаются глюки потому что на сервере началась новая игра, а клиент об этом не знает…
Да, открытое соединение служит как идентификато, если есть поддержка keep-alive браузер будет слать все get ajax запросы через 1 соединение.

Насчет таймаутов, в заголовках это — Keep-Alive: timeout=25, max=100, если в течение 25 секунд не будет никаких дествий, бразурер должен закрыть соединение, но в браузерах свои дефолтные настройки, и этот заголовок они просто игнорирует, в FF к примеру таймуат — 115 секунд, а это 2 минуты, я думаю хватит подумать.

вот, кстити табличка(тесты не мои):

Opera 11.11 – 120 seconds
Chrome 13 – at least 300 seconds (server closed after 300 second timeout)
IE 9 – 60 seconds
Firefox 4 – 115 seconds

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

А вот откуда сервер узнает состояние старого поля, если в коде нет его передачи? Оно было в процессе, который уже умер.

И получается, что игрок и сервер с этого момента имеют разное представление о том, в каком состоянии находится поле.
При такой реализации, если браузер закрывает соединение, пользователь никак не узнает, что продолжить это игру ему не удастся, это связано с тем, что на стороне пользователя, нет события закрытия соединения.
Проще вместо всей этой фигни с take_socket и прочим просто завести N процессов, каждый из которых будет accept'ить один и тот же сокет и при успехе просто спавнить еще один такой же, а основную работу продолжать в себе самом. Таким образом мы гарантируем, что слушающий сокет не будет простаивать пока процесс инициализирует клиента.
Если я правильно понял, Ваша модель только увеличит производительность приема клиентов, из-за того, что мы выносим accept'ы в разные процессы, а главная причина почему я использовал фигню с take_socket, это для того, чтобы избежать гонок между spawn() и controlling_process().
да, вы правильно поняли, это позволит подключаться одновременно большему числу клиентов. Я понял, что take_socket используется, чтобы избежать RC, просто предложил вариант проще. Кстати, а почему вы предпочли сырую реализацию реализации через OTP?
Предпочел реализацию без OTP, наверное главной причиной является недостаточное знание фреймворка.
Я запомню вашу модель сетевого взаимодействия, это будет действительно проще и логичней.
Здорово сделано.
Не помешало бы правда добавить различительные цвета крестикам и ноликам (красный-синий), а то серый путается постоянно.
Ну это было как демонстрация, кто захочет добавит.
получилась гомоку с уменьшенной доской. до рэндзю не хватает ещё ста пятнадцати клеток и турнирных правил. очень нравится эта игра
на 3.6 уже не хватает доски (мне) выстроить вилку :)
попробую реализовать полную версию, давно хотел потрогать эрланг; спасибо за предельный стиль изложения
Поправить в некоторых местах, и поле можно увеличить до желаемых размеров.
возможно где-то есть логическая ошибка, алгоритм 3.6 сделал неверный ход, вилки не было…
или «­бот играет достаточно хорошо в пределах [0.5, 1]­», но более 1 уже недостаточно хорошо? сел за код, разбираюсь…
на 3.6 он должен пресекать(защитная стратегия) все ваши ходы, насчет ошибки, возможно бот сыграл недостаточно эффективно для той игровой ситуации, но бот только оценивает выгоду куда поставить, в той ситуции значит алгоритм посчитал, что выгодно поставить именно там.
Все-же зря фреймворками пренебрегаете. Ваш код имеет очень мало общего с реальными Erlang-программами.

Для приема подключений используйте, например, Cowboy. Ну и OTP все-же постарайтесь осилить. Там ничего сложного нет, главное найти хороший мануал…

И не называйте модули «main», «internal» и прочими общими именами — пространство имен для модулей в Erlang общее. Добавляйте префикс например.
Зачем такие сложности с сессиями? WebSockets пробовали использовать? Все будет быстрее и лучше.
Не считаю что есть какие-то сложности с сессиями, Websockets — не рассматривал, изначально решил, что реализация будет через keep-alive.
Cowboy + websockets тут идеальны будут.
Писать на Erlang без OTP — довольно бессмысленно.
Обычно при появлении в коде в чистом виде оператора отсылки сообщения ("!") и/или функции «spawn» (особенно без link) говорит, что что-то тут не так…
На считаю, что писать без фреймворка — бессмысленно, возможно не эффективно, да.

Не забываем, это просто демонстрационная программа, которая стала для меня хорошим поводом опробовать Erlang.
OTP — это не фреймворк, это скорее стандартная библиотека плюс архитектурные рекомендации, которые учитывают знания и опыт разработчиков. Поэтому писать можно и без, только зачем изобретать велосипед и собирать грабли, когда можно это всё обойти?
А если интересно более глубоко опробовать Erlang, то этот же проект, только на OTP и Cowboy с вэбсокетами будут отличным продолжением. ;-)
всё обойти
На этапе обучения — чтобы лучше понимать саму OTP. Только делать это надо осознано, а не с целью, сделать свое с 0 и лучше. Рано или поздно, возникают ситуации, которые уже нельзя обойти. Это редкость, но досадная. Лучше сразу понимать как и что устроено.
Продолжение: +1.
Может генерировать на сервере рандомный GameId и отправлять его клиенту в куку?
Тогда при внезапном рестарте сессии его можно опознать и вернуть в игру.
Лучше даже не куку а с server.my/newgame/ редиректить на server.my/join// это ползволит 1) прозрачно балансировать нагрузку 2) сразу очевидно как сделать многопользовательскую версию и делиться ссылкй с другом.
Это следующий этап.
Потом можно сделать номера всем играм, выставить в список игр и любой желающий сможет зайти посмотреть на игру других людей.
А когда человек присоединяется к игре, он заходит на site.my/game/new оттуда с кукой уходит на site.my/game/[game_id]. В этом случае кука подтверждает его право участвовать в игре, а не просто смотреть.
Сидел разбирался с кодом. Фиксил баги. И всё это время меня не отпускало двоякое чувство, что автор с одной стороны очень силён в недрах эрланга и http. С другой стороны увлечён демосценой. А с третьей стороны — дилетант в программировании. 8-\ Какая-то гремучая смесь прям получилась
Sign up to leave a comment.

Articles