Исходник программы, показывающей пример реализации древней китайской игры Го (в Китае она называется Wei-chi).
Го - одна из простых, но в тоже время и сложных настольных игр. Два противника по очереди кладут черные и белые камни на квадратную доску. Если вы окружите группу камней противника своим цветом, камни удаляются, и вам засчитывается очко за каждый захваченный камень.
Фанаты описывают ее как «величайшую настольную игру всех времен» и «более трудную для освоения, чем шахматы». Если вы не знакомы с игрой, просто поищите в Интернете «Правила игры в Го» или «Учебник по игре в Го».
Доступны три размера доски: 9x9, 13x13 и официальный 19x19.
Реализован режим отладки, который имеет функции, полезные для отработки навыков:
- Несколько камней определенного цвета могут быть помещены за один «ход».
- Каждый камень отображает группу или блок, к которому он принадлежит (блоки представляют собой связанные группы камней одного цвета).
- Уже размещенные камни можно удалить, щелкнув правой кнопкой мыши.
Для оценки я просто засчитываю берущему захваченные камни. Насколько я понимаю, один игрок может заполнить мертвые зоны, но для другого это будет самоубийственно (а значит, запрещено). Я думаю, что «мертвые» места засчитываются для игрока, который мог бы там играть, но я не уверен в этом, и стоит ли их классифицировать.
Заметки по исходнику
Идентифицировать группы камней и определить, когда группа окружена камнями противоположного цвета, было сложнее закодировать, чем ожидалось. Игра заключается в размещении камней на пересечении линий сетки. Группа - это набор из одного или нескольких камней одного цвета, соединенных горизонтальными и вертикальными линиями сетки. Группу захватывают, окружая ее камнями противоположного цвета. «Окружение» означает, что каждая горизонтальная и вертикальная линия сетки, идущая от краев группы, заполнена камнем противоположного цвета.
После нескольких неудачных запусков моим решением было реализовать процедуры, которые очищают все блоки и идентифицируют их с нуля после установки каждого камня. Findblocks инициирует процесс, а функция FindBlocksFrom рекурсивно завершает поиск каждого блока. Функция BlockCount вызывается для подсчета блоков в каждой группе, а также возвращает количество открытых ребер. Все можно было бы сделать более эффективно, но всего несколько сотен камней и всего несколько сотен ходов, поэтому время для начала с нуля для каждого сыгранного камня не имеет значения.
В программе реализованы тесты, чтобы предотвратить некоторые запрещенные размещения камней, например, «самоубийственные» ходы, которые завершают окружение группы цвета игрока.