Об этом проекте

# chess_z chess_z — это программный каркас для китайских шахмат сянци, реализованный на языке C. В настоящее время основное внимание уделяется ядру правил и границе подключения ИИ. ## Основные возможности - **Представление битовыми досками**: доска из 90 клеток представляется двумя битовыми досками `uint64_t`, для каждой стороны и каждого типа фигур имеется отдельная битовая доска. - **Массив-почтовый ящик**: синхронно поддерживается массив-почтовый ящик `board[90]`, что упрощает генерацию правил и отладку. - **Полная поддержка правил**: поддержка начальной позиции, чтение и запись FEN, выполнение ходов, генерация легальных ходов, определение шаха и perft. - **Интерфейс подключения ИИ**: предоставляется `XqEngineAdapter`, позволяющий в дальнейшем подключать внешние функции поиска и оценки для шахматного ИИ. - **Встроенный простой движок**: содержит очень простую оценку материала и мобильности легальных ходов + negamax-поиск, в основном используется для смоук-тестирования каркаса. ## Структура каталогов ```text include/xiangqi/bitboard.h базовые операции с битовыми досками include/xiangqi/types.h базовые типы, фигуры, ходы include/xiangqi/position.h представление позиции, FEN, выполнение ходов include/xiangqi/movegen.h псевдолегальные/легальные ходы, определение шаха, perft include/xiangqi/engine.h интерфейс подключения шахматного ИИ src/ основная реализация examples/cli.c пример интерфейса командной строки stats/generate_positions.c точка входа для генерации случайных легальных позиций stats/search_positions.c точка входа для пакетного поиска позиций stats/random_fen/ данные FEN случайных позиций stats/data/ результаты анализа производительности tests/test_core.c базовые тесты правил ``` ## Сборка Рекомендуется использовать CMake: ```sh cmake -S . -B build cmake --build build ctest --test-dir build ``` Если на компьютере установлен только GCC, можно также напрямую скомпилировать тесты: ```sh gcc -std=c99 -Wall -Wextra -Wpedantic -I include src/position.c src/movegen.c src/engine.c tests/test_core.c -o build/xiangqi_core_tests ./build/xiangqi_core_tests ``` Компиляция интерактивного примера «человек против машины»: ```sh gcc -std=c99 -Wall -Wextra -Wpedantic -I include src/position.c src/movegen.c src/engine.c examples/cli.c -o build/xiangqi_cli ./build/xiangqi_cli ``` По умолчанию пример работает в режиме «вы играете красными, встроенный простой движок играет чёрными». Формат ввода — `начальная клетка + конечная клетка`, вертикали обозначаются буквами `a..i`, горизонтали — цифрами `0..9`, например: ```text b2b9 ``` Доступные команды: ```text moves вывести все текущие легальные ходы fen вывести текущий FEN help вывести справку quit выйти ``` ## Генерация случайных позиций и пакетный поиск После сборки можно сначала сгенерировать набор воспроизводимых случайных легальных позиций, а затем заставить встроенный движок последовательно искать в них ходы: ```sh ./build/xiangqi_generate_positions ./build/xiangqi_search_positions ``` Обе программы по умолчанию используют `stats/random_fen/random_positions.fen`; им также можно указать одинаковый путь к файлу: ```sh ./build/xiangqi_generate_positions build/profile_positions.fen ./build/xiangqi_search_positions build/profile_positions.fen ``` Генератор использует фиксированное случайное зерно, выполняет из начальной позиции случайные ходы в количестве `0..100` и выводит 100 позиций, по одному FEN в строке. Программа поиска один раз последовательно читает файл и ищет один ход для каждой позиции с максимальной глубиной 6 и без ограничения по времени, что удобно в качестве неинтерактивной точки входа для анализа производительности. ## Подключение ИИ Внешний ИИ может напрямую повторно использовать слой правил: ```c XqMoveList legal; xq_generate_legal(&pos, &legal); for (int i = 0; i < legal.count; ++i) { XqPosition next = pos; xq_position_make_move(&next, legal.moves[i]); /* выполнить поиск или оценку в next */ } ``` Также можно подключить собственный поиск через `XqEngineAdapter`: ```c static bool my_search(const XqPosition *pos, unsigned depth, XqMove *best, void *user) { (void)user; /* реализуйте собственный поиск с помощью xq_generate_legal / xq_position_make_move */ return false; } XqEngineAdapter engine = { .evaluate = NULL, .search = my_search, .user = NULL, }; XqMove best; XqSearchLimits limits = xq_search_limits_default(); xq_engine_find_best_move(&engine, &pos, &limits, &best); ``` ## Соглашения о координатах - `file` находится в диапазоне `0..8`, `rank` — в диапазоне `0..9`. - Нижняя горизонталь красных — `rank = 0`, нижняя горизонталь чёрных — `rank = 9`. - `xq_square_make(file, rank)` отображает координаты в `rank * 9 + file`. - FEN записывается в 10 строках от чёрных к красным, заглавные буквы обозначают красные фигуры, строчные — чёрные.