Тема: [WIP] mooChess
Показать сообщение отдельно
Старый 09.07.2011, 13:49   #2
shybovycha
ПроЭктировщик
 
Аватар для shybovycha
 
Регистрация: 27.05.2007
Сообщений: 110
Написано 40 полезных сообщений
(для 33 пользователей)
Ответ: [WIP] mooChess

Добрый день, товарищи!

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

Обо всем - по порядку.


Отказ от редактора
Редактор изначально предполагал определенные усилия и большие затраты времени на создание банального валидатора ходов. После некоторых умозаключений вслух было принято решение реализовать простые проверки на валидность того либо иного хода на стороне сервера средствами языка (а не БД, как изначально предполагалось). Пока особых изменений в валидации замечено не было (альфа-версия, таки!) - валидатор по-прежнему возвращает "верно" для любого хода.


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

То бишь, теперь для запуска игры необходимо в консоли написать

$
./[path_to_game_client]/chess.elf white

*начнет поиск оппонента, играющего черными фигурами
либо же

$ ./[path_to_game_client]/chess.elf black

*начнет поиск оппонента, играющего белыми фигурами


Повторю заметку: аргумент указывает, какими фигурами хотите играть вы.


Изменение сути игры

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


Изменение протокола общения клиента и сервера

И вот оно, то маленькое и незаметное изменение, которое полностью изменило игру!

Дабы не вникать в детали и не разбрасываться теориями, умозаключениями и терминами просто опишу протокол.

Теперь общение клиента и сервера происходит так:
  • клиент начинает работу с известной желаемой стороной (цвет фигур, которыми пользователь желает управлять). Если сторону определить не удалось - клиент завершает работу
  • серверу отправляется запрос вида "хочу играть за %side%", *(%side% = {черных, белых})
  • сервер принимает запрос и выбирает из БД случайным образом первую попавшуюся игру, у которой сторона, противоположная запрошенной уже используется, а запрошенная - нет (если игрок хочет играть "за белых" - "черная сторона" будет проверена на "не пустоту", а "белая сторона" - "на пустоту"). Коль найдется одна такая запись (ибо больше нам и не нужно) - "запрошенной стороне" будет присвоено значение ID (уникальный для каждого клиента код; генерируется на стороне сервера при получении запроса "хочу играть за..." и отдается клиенту в конце этого же запроса как результат). Если же ни одной записи не найдено (либо все игроки уже в игре, либо в игре нету желающих быть оппонентом нашему пользователю и все хотят играть теми же фигурами, что и он) - в БД будет создана новая игровая запись с заполненной "запрошеной стороной" и пустой противоположной
  • если на предыдущем шаге был найден оппонент для пользователя, запрос будет иметь форму "!%uid%", если нет - "?%uid%". В первом случае клиент нашего пользователя перейдет в бесконечный цикл опроса сервера (см. прим. 1) вида "так у меня уже есть оппонент или еще нет?". Во втором (равно как и в случае ответа "да, у тебя появился оппонент!" от сервера при первом раскладе) - будет открыто окно с видом доски и фигурами желаемого цвета внизу
  • при каждом новом ходе серверу отправляется запрос "я - %uid% и хочу пойти отсюдова да сюда". Сервер выполняет определенные действия (см. прим. 2) и возвращает результат "да, можешь идти" или "нет, тебе туда нельзя"
  • клиент может находиться в двух состояниях (см. прим. 3) - первом, когда ходит пользователь этого же клиента и втором, при котором право хода имеет его оппонент. Будучи во втором состоянии клиент постоянно опрашивает сервер на наличие новых ходов. При наличии новых ходов (точнее, одного хода - хода противника), клиенты переходят в противоположные состояния и перерисовывают позиции фигур на доске
Примечания

Прим. 1: цикл опроса в буквальном смысле выглядит так:

while (1)
{
  int res = isGameStarted(client_id);

  if (res < 0)
  {
    // ошибка
    return 1;
  } else
  if (res > 0)
  {
    // игра начата
    break;
  }
}
В ближайшем будущем просто критически необходимо поставить таймаут опроса равным хотя бы нескольким секундам. Иначе же это чревато перегрузками как клиента, так и сервера.

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

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


Коллоквиум

Итак, сказано - много, понятного - мало. Давайте попробуем разобрать коротенький пример работы для прояснения ситуации.

Скажем, есть у нас три игры "в процессе" (люди уже играют во всю - их мы трогать не будем; они у нас будут декорациями на сцене) и два клиента, которые хотят играть белыми фигурами. Запускаем клиент и хотим играть черными ($ ./chess.elf black). Клиент отправляет запрос "хочу играть черными", сервер получает его, находит первого же клиента, который хочет играть белыми фигурами, приписывает ему нас. Наш клиент получает ответ "значит ты у нас будешь *** и у тебя есть противник. рубись.". Начинается игровой цикл (который пока, увы, не реализован в достаточной мере) - ... - ожидание нового хода - расстановка фигур - запрос на новый ход - ... и т. д.


Конец очередного спринта (aka Backlog)

Итак, очередной спринт закончен. Сделано не так много, как хотелось бы, но теперь игра начинает почучуть обретать форму. Все вышеописанное и составляет, собсно, бэклог данного спринта. Взять исходники сервера и клиента (повторюсь: редактора более нету!) можно по ссылке. Для компиляции клиента, как и ранее необходим SFML 1.6 (в частности, sfml-network, sfml-window, sfml-graphics). Для запуска сервера - PHP. Дабы пост не казался унылым до невозможности привожу скрин, на котором два клиента запущены и нашли друг друга. Ах, да: в архиве также содержится SQL-скрипт для создания необходимых таблиц БД (использован MySQL, скрипт пока не стандартизирован).

Спасибо за внимание!
Миниатюры
Нажмите на изображение для увеличения
Название: screen1.jpg
Просмотров: 1090
Размер:	214.9 Кб
ID:	14336  

Последний раз редактировалось shybovycha, 09.07.2011 в 13:52. Причина: обновление скриншота и воспоминание о SQL
(Offline)
 
Ответить с цитированием
Эти 4 пользователя(ей) сказали Спасибо shybovycha за это полезное сообщение:
baton4ik (07.08.2011), Mhyhr (09.07.2011), Randomize (12.07.2011), SBJoker (09.07.2011)