В этой статье я бы хотел поговорить о ещё одном предмете, который преподаётся в 1 семестре 4 курса. Называется он системы искусственного интеллекта=)
Суть курса передать очень трудно, потому что особо ничего не было понятно с самого начала и до конца)
А рассказать хочется о семестровой работе, в которой было необходимо написать игру с искусственным интеллектом на прологе. К слову, писали мы её около 2-3 недель в конце декабря-начале января, уже после зачёта.
Мы выбрали игру "Поддавки" и основным мотивом было то, что у нас был неплохой пример=)
Задачу осложняло то, что этот пример был дважды сдан однокурсниками и дважды преподаватель их спалил)
Пример был взят отсюда - визуальная часть на Delphi, интеллект на прологе.
Переписывание я начал с визуальной части. Так как мы довольно много пишем на С++ с Qt, и есть опыт, я решил, что это будет самым быстрым и практичным вариантом. Однако самому писать не хотелось, поэтому интерфейс был выпилен отсюда.
Сразу встал вопрос о связи визуальной части и интеллекта. Гугл выдал несколько вариантов, но самым практичным оказался этот.
В первой части я попытаюсь переписать его в нормальном стиле и укажу некоторые проблемы, которые возникли у меня.
Часть 1. Связь SWI-Prolog и Qt.
Для разработки использовался Qt Creator и SWI-Prolog.
Итак, первое что нам необходимо сделать - скачать SWI-Prolog с их официального сайта.
Отмечу, что у меня на 64х битной Windows версия пролога для 64 не заработала, так что нужно качать версию для 32!
После скачки её необходимо установить(желательно в стандартную папку).
Чтобы начать использование SWI в Qt, необходимо скопировать некоторые файлы из папки, в которую мы его установили, в папку с нашим проектом. В нашем проекте папка называется swi-prolog. Копируем папки lib и include полностью и из папки bin 2 файла - swipl.dll и pthreadVC.dll.
Внимание! эти 2 .dll файла необходимо помещать в папку, где находится запускаемый файл! Без них проект работать не будет и будет выдавать "During startup program exited with code 0xc0000135".
Далее необходимо сделать инклуд библиотеки и include-файлов в файл qt-проекта .pro:
LIBS += ./swi-prolog/bin/swipl.dll
INCLUDEPATH += ./swi-prolog/include
Теперь перейдём к коду.
1.Прописать переменные среды. В них нужно указать путь к установленному SWI-Prolog и сделать это можно так:
2. Заинклудить .dll файл swi-prolog'а.
3. Подключим файл с интеллектом. Здесь стоит сказать, что любые сообщения, которые мы посылаем через PlCall(подробнее можно прочитать на оф.сайте swi-prolog'а), необходимо заключать в блоки try{}catch(){}.
Всё! Теперь мы можем обращаться с запросами к файлу интеллекта.
Рассмотрим подробнее наш пример.
PlCall - это макрос, он отправляет запрос - это первый аргумент(retractall), а второй - это принимаемые им аргументы. Данный запрос удалит все данные о computer_checker из базы. Обратная операции удаления - операция записи, называется assert.
Здесь стоит отметить, что если мы хотим узнать что-нибудь из базы, например, проверить справедливость утверждения, нам нужно проверять возвращаемое PlCall-ом значение.
Пример: мы хотим, чтобы значение в массиве было WHITE, если на этих координатах находится пешка игрока (player_checker). Это будет выглядеть так:
На этом я пожалуй закончу. О второй части - организации и реализации интеллекта мы поговорим чуть позже с Евгением Ли, который был ответственным за эту часть.
Ссылка на репозиторий:
http://code.google.com/p/poddavki/
Суть курса передать очень трудно, потому что особо ничего не было понятно с самого начала и до конца)
А рассказать хочется о семестровой работе, в которой было необходимо написать игру с искусственным интеллектом на прологе. К слову, писали мы её около 2-3 недель в конце декабря-начале января, уже после зачёта.
Мы выбрали игру "Поддавки" и основным мотивом было то, что у нас был неплохой пример=)
Задачу осложняло то, что этот пример был дважды сдан однокурсниками и дважды преподаватель их спалил)
Пример был взят отсюда - визуальная часть на Delphi, интеллект на прологе.
Переписывание я начал с визуальной части. Так как мы довольно много пишем на С++ с Qt, и есть опыт, я решил, что это будет самым быстрым и практичным вариантом. Однако самому писать не хотелось, поэтому интерфейс был выпилен отсюда.
Сразу встал вопрос о связи визуальной части и интеллекта. Гугл выдал несколько вариантов, но самым практичным оказался этот.
В первой части я попытаюсь переписать его в нормальном стиле и укажу некоторые проблемы, которые возникли у меня.
Часть 1. Связь SWI-Prolog и Qt.
Для разработки использовался Qt Creator и SWI-Prolog.
Итак, первое что нам необходимо сделать - скачать SWI-Prolog с их официального сайта.
Отмечу, что у меня на 64х битной Windows версия пролога для 64 не заработала, так что нужно качать версию для 32!
После скачки её необходимо установить(желательно в стандартную папку).
Чтобы начать использование SWI в Qt, необходимо скопировать некоторые файлы из папки, в которую мы его установили, в папку с нашим проектом. В нашем проекте папка называется swi-prolog. Копируем папки lib и include полностью и из папки bin 2 файла - swipl.dll и pthreadVC.dll.
Внимание! эти 2 .dll файла необходимо помещать в папку, где находится запускаемый файл! Без них проект работать не будет и будет выдавать "During startup program exited with code 0xc0000135".
LIBS += ./swi-prolog/bin/swipl.dll
INCLUDEPATH += ./swi-prolog/include
Теперь перейдём к коду.
1.Прописать переменные среды. В них нужно указать путь к установленному SWI-Prolog и сделать это можно так:
- char env[] = "SWI_HOME_DIR=C:\\Program Files\\pl";
- putenv(env);
2. Заинклудить .dll файл swi-prolog'а.
- //инклуд файла
- static char * av [] = {"libpl.dll", NULL} ;
- if (PL_initialise(1 , av) == 0)
- {
- PL_halt(1);
- qDebug() << "lib initialize error -(";
- }
- else
- qDebug() << "lib initialize ok!";
3. Подключим файл с интеллектом. Здесь стоит сказать, что любые сообщения, которые мы посылаем через PlCall(подробнее можно прочитать на оф.сайте swi-prolog'а), необходимо заключать в блоки try{}catch(){}.
- //открытие файла пролога
- try
- {
- if(PlCall("call", PlTermv(PlCompound("consult('Anti-checkers.pl')"))))
- qDebug() << "database opening ok!";
- else
- qDebug() << "database opening fail!";
- }
- catch (PlException & ex)
- {
- QMessageBox::warning(this, "Prolog Exception", QString("Prolog has thrown an exception:") + QString((char *)ex));
- }
Всё! Теперь мы можем обращаться с запросами к файлу интеллекта.
Рассмотрим подробнее наш пример.
PlCall - это макрос, он отправляет запрос - это первый аргумент(retractall), а второй - это принимаемые им аргументы. Данный запрос удалит все данные о computer_checker из базы. Обратная операции удаления - операция записи, называется assert.
- //обнуляем значения
- PlCall("retractall", PlTermv(PlCompound("computer_checker(_,_)")));
Здесь стоит отметить, что если мы хотим узнать что-нибудь из базы, например, проверить справедливость утверждения, нам нужно проверять возвращаемое PlCall-ом значение.
Пример: мы хотим, чтобы значение в массиве было WHITE, если на этих координатах находится пешка игрока (player_checker). Это будет выглядеть так:
- PlTermv args = PlTermv(PlCompound(str_i), PlCompound(str_j));
- if(PlCall("player_checker", args))
- checkers[i][j] = WHITE;
На этом я пожалуй закончу. О второй части - организации и реализации интеллекта мы поговорим чуть позже с Евгением Ли, который был ответственным за эту часть.
Ссылка на репозиторий:
http://code.google.com/p/poddavki/
очень интересный обзор.
ОтветитьУдалитья ломаю голову над подобной проблемой, я хочу подключить swi-prolog к microsoft visual studio, но совсем не знаю как это сделать. есть ли какие-нибудь соображения на данный счет?
ps я правильно понимаю что если я сделаю это то я смогу использовать возможности пролога программируя в MVS ??
Смотря к какому проекту нужно подключить. Вот здесь есть варианты подключения к
Удалитьc#, c++, и другим.
http://www.swi-prolog.org/contrib/
Если подключите - то да, безусловно, всё будет работать.
Интересно бы продолжение темы..
ОтветитьУдалить