Хобби-проект, настольная игра, пишется на Java. Пока использую голый AWT, с расчётом перевести на Android. Напишу на примере преферанса, хотя я взял игру посложнее и точек принятия решения там на штук тридцать. Аббревиатурой «ТПР» обозначим точку принятия решения.
пока пуля не закрыта
раздать карты
пока все не спасовали
найди следующего игрока
ТПР: заказ в торговле?
определи выигравшего торговлю
если такового нет
[распасовку опущу]
иначе // игра на взятки или мизер
вытяни прикуп
ТПР: заказ и снос?
если игра вистуется
для остальных
ТПР: пас/вист?
если возможны полвиста
ТПР: полвиста?
пока у игроков остались карты
определить, кто первым ходит
в порядке хода
ТПР: чем ходить?
определить, чья взятка
подсчитать очки
Как внедрить этот код в рабочий цикл программы?
ВАРИАНТ 1. Второй цикл обработки сообщений.
Как только захочется поиграть, из обработчика какого-то события запускаем код, указанный выше, и нас интересуют в первую очередь точки принятия решения (callback’и).
// Точка принятия решения (callback)
если (принимает решение ИИ)
прокрутить ИИ
вызвать сцену, которая демонстрирует, как ИИ поступил
вызвать дополнительный цикл обработки сообщений
преобразовать результат работы ИИ в аргументы callback’а
иначе
вызвать нужную сцену
вызвать дополнительный цикл обработки сообщений
преобразовать результат работы сцены в аргументы callback’а
Преимущества: код прост в понимании.
Недостаток: многие оконные фреймворки не дают доступа к циклам обработки сообщений.
ВАРИАНТ 2. Конечный автомат. Цикл правил игры преобразован в конечный автомат.
алг прокрутитьИгру
автомат.пуск
если принимает решение ИИ
прокрутить ИИ (большой веер callback’ов в зависимости от того, в какой ТПР остановились)
записать его решение в автомат
сменить сцену на демонстрирующую решение автомата
иначе
сменить сцену на принятие решения человеком
В каждой из сцен принятия решений есть запись информации в автомат и вызов функции прокрутитьИгру.
Преимущества: никаких требований к системе. Самый простой save/load.
Недостаток: автомат — ад такой ещё. Крайне трудно формализовать, чего требуется от той или иной точки принятия решения.
ВАРИАНТ 3. Сопрограммы. Игровой цикл обычный.
// Точка принятия решения (callback)
если (принимает решение ИИ)
прокрутить ИИ
вызвать сцену, которая демонстрирует, как ИИ поступил
уступить
преобразовать результат работы ИИ в аргументы callback’а
иначе
вызвать нужную сцену
уступить
преобразовать результат работы сцены в аргументы callback’а
Где-то в сценах игры есть команда «уступить».
Преимущества: снова всё просто.
Недостаток: где вы видели в Java сопрограммы?
Пока у меня конечный автомат, но решение совершенно не нравится. Может, вы подскажете какие-то ещё варианты, как лучше реализовать игру, чтобы удобно было навешиваться на оконные фреймворки, писать ИИ и сетевую? Желательно без лишних потоков.