Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Предпросмотр в XP (в explorer) 
:(
    Опции темы
Illusion Dolphin
  Дата 7.12.2003, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 36
Всего: 63



Не подскажите, как сделать, чтобы в WinXP зарегистрировать новый тип фалов (графический), чтобы в проводнике при выделение файла данного типа в свойствах был виден его предпросмотр, как это организовано со всеми стандартными типами файлов?


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Unregistered
Дата 7.12.2003, 18:25 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Интерфейс IExtractImage для пердварительного просмотра в Проводнике.
Интерфейс IShellPropSheetExt для создания страниц свойств.

Или достань Shell+.
Там есть пробник. Но только на 30 дней.
  Вверх
Illusion Dolphin
Дата 7.12.2003, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 36
Всего: 63



Хочется своими руками дописать всё.... Можно попобробнее остановиться на IExtractImage и IShellPropSheetExt? Не общими фразами, а хоть небольшие краткие примеры?..


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Cheba
Дата 8.12.2003, 01:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pointless one
***


Профиль
Группа: Vingrad developer
Сообщений: 1777
Регистрация: 27.11.2003
Где: /dev/null

Репутация: 1
Всего: 62



Могу накидать про IShellPropSheetExt. С другим не приходилось работать.
PM MAIL ICQ   Вверх
Illusion Dolphin
Дата 8.12.2003, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 36
Всего: 63



Цитата
Могу накидать про IShellPropSheetExt

Очень был бы признателен! Хотя бы на этом примере разобраться...
кинь на мыло, если не составит труда: illusdolphin@!yandex.ru ("!" не нужен - antispam : ))


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Cheba
Дата 12.12.2003, 01:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pointless one
***


Профиль
Группа: Vingrad developer
Сообщений: 1777
Регистрация: 27.11.2003
Где: /dev/null

Репутация: 1
Всего: 62



Добавление вкладок в диалоговое окно свойств файла


Вступление (поскипано, бо не важно)


Как это работает

При формировании диалогового окна свойств файла оболочка Windoze выполняет следующие действия.
1) Ищет в реестре раздел HKEY_CLASSES_ROOT\.ext, где .ext расширение файла.
2) Считывакт оттуда значение, заданное по умолчанию, например, для расширения .txt в нем задана строка textfile.
3) Ищет в секции HKEY_CLASSES_ROOT раздел, совпадающий по имени со значением, полученным в п. 2.
4) В этом разделе проверяет раздел shellext\PropertySheetHandlers
5) Если такой подраздел существует, то из него считываются значения идентификаторов GUIDE для COM-серверов.
6) Оболочка предполагает, что эти серверы реализуют интерфейсы IShellExtInit, IShellPropSheetExt. Она создает экземпляры СОМ-объектов, запрашивая у них эти интерфейсы и при помощи их методов позволяет добавить в дилоговое окно свойств файла страницы.

Чтобы понять, как это происходит, рассмотрим подробнее методы используемых интерфейсов:
Код
 IShellInit = interface(IUnknown)
   [SID_IShellInit]
   function Initialize(pidlFolder: PItemIDList;
     lpdobj: IDataObject;
     hKeyProgID: HKEY): HResult; stdcall;
 end;

Единственный метод этого интерфейса вызывается оболочкой для инициализациирасширений и служит для передачи в него контекста, в которомВ вызвано расширение (текущая папка, выбранный объект). Параметр pidlFolder для диалога всегда содержит nil, а в параметре lpdobj передается ссылка на интерфейс IDataObject, при помощи которого можно получить информацию об объекте, для которого вызвано расширение оболочки.
Код
 IShellPropSheetExt = interface(IUnknown)
   [SID_IShellPropSheetExt]
   function AddPages(lpfnAddPage: TFNAddPropSheetPage;
     lParam: LPARAM): HResult; stdcall;
   function ReplacePage(uPageID: UINT;
     lpfnReplacWith: TFNAddPropSheetPage;
     lParam: LPARAM): HResult; stdcall;
 end;

Второй из используемых интерфейсов характерен только для обработчика диалогового окна свойств и содержит методы, добавлить страницы в диалоговое окно либо заменить уже имеющиеся там новыми. Нам понадобится только первый метод, поскольку второй используется для страниц Панели управления Windoze. В метод AddPages передются два параметра.

  • LpgnAddPage - адрес функции, которую наше раснирение может вызывать для регистрации своих страниц. Страницы должны быть созданы функцией CreatePropertySheetPage.
  • LParam - параметр, который мы должны передать в эту функцию.

Таким образом, для создания своих вкладок необходимо выполнить следующую процедуру.
1. В методе IShellExtInit.Initialize получить и запомнить имя файла, для которого требуется показать показать страницы свойств.
2. В методе IShellPropSheetExt.AddPages - создать и добавитьтребуемы е страницы.

Функция LpfnAddPage имеет следующий тип:
Код
 LPFNADDPROPSHEETPAGE = function(hpdp: HPropSheetPage;
   lParam: Longint): BOOL; stdcall;
 TFNAddPropSheetPage = LPFNADDPROPSHEETPAGE;

параметр lParam нам передают. Параметр HPSP мы должны получить при помощи функции:
Код
 function CreatePropertySheetPage(
   var PSP: TPropertySheetPage): HPropertySheetPage; stdcall;

Эта функция принимает на входе структуру PSP, объявленную как:
Код
 TPropertySheetPage = record
   dwSize: Longint;
   dwFlags: Longint;
   hInstance: THandle;
   case Integer of
     0: (
       pszTemplate: PWideChar);
     1: (
       pResource: Pointer;
       case Integer of
         0: (
           hIcon: THandle);
         1: (
           pszIcon: PWideChar;
           pszTitle: PWideChar;
           pfnDlgProc: Pointer;
           lParam: Longint;
           pfnCallback: TFNPSCallbackW;
           pcRefParent: PInteger;
           pszHeaderTitle: PWideChar;
           pszHeaderSubTitle: PWideChar;));
 end;

От приложения требуется корректно заполнить требуемые поля структуры.

  • dwSize - размер структуры, должен быть установлен в SizeOf(TPropertySheetPage).
  • dwFlags - набор флагов, определяющих поведение создаваемой страницы. Если не требуется какой-то особенной функциональности, можно использовать значение PSP_DEFAULT.
  • HInstance - ссылка на вызывающий модуль.
  • pszTemplate(pResource) - имя ресурса с описанием диалогового окна.Если ипользуется флаг PSP_DLGINDIRECT, то страница может быть создана из ресурса, уже загруженного в память. При этом используется указатель pResource.
  • HIcon(pszIcon) - если задан флаг PSP_USEICON, вкладка будет иметь значок, дескриптор которого задан в параметре HIcon, если используется флаг PSP_USEICONID, значок будет загружен из из ресурса с именем pszIcon.
  • pszTitle - если задан флаг ЗВЗ_ГЫУЕШЕДУ, то вкладка будет иметьзаголовок, заданный этим параметорм, а не ресурсом диалогового окна.
  • pfnDlgProc - адрес функции, обрабатывающей сообщениядля создаваемой страницы.
  • lParam - произвольное значение. После создония страницы Windoze пошлет ей сообщение WM_INITDIALOG с этим значением в lParam.
  • pfnCallback - адрес функции обратного вызова, вызываемой при при создании иуничтожении страницы. Испоьзуется, если задан флаг PSP_USECALLBACK.
  • pcRefParent - адрес переменной со счетчиком ссылок на страницу, используется, ечли задан флаг PSP_USEREFPARENT.

Как можно заметить, описание страницы берется из ресурса, а за ее поведение отвечает функция pfnDlgProc. Это несколько не привычно для программистаDelphi, но имноо таким образом осуществляется создание диалоговых окон в WinAPI. Впрочем, все не так уж сложно, и программист, знакомый с сообщениями Windows и оконной процедурой, легко сможет понять, как создавать свои диалоговые окна.
На этом вводную часть можно считать оконченной и можно приступить к реализаци.


Создание СОМ-сервера

Расширение оболочки - это внутрипроцессный СОМ-сервер, скомпилированный в DLL. Чтобы создать, эго следует выбрать в меню Delphi команду File > New > Other, перейти на страницу ActiveX репозитория объектов и выбрать значок ActiveX Library. Будет создана библиотека. Затем на той же странице нужно выбрать значок COM Object. В появившемся окне следует ввести имя создаваемого класса (например TTextProp) и снять флажок Include Type Library. Будет сгенерирован шаблон СОМ-сервера.
Теперь добавим в секцию uses модуль ShlObj, в котором объявлены требуемые интерфейсы, и добавим их в описание класса. Также добавим поле FileName для хранения имени файла, с которым нам придется работать. После этого объявление класс должно выглядеть следующим образом:
Код
 type
   TTextProp = class(TComObject, IShellExtlnit. IShellPropSheetExt);
   FileName : PChar;     {IShellExtlnit}
   function Initialize(pidlFolder: PItemIDList;
     lpdobj: IDataObject;
     hKeyProgID: HKEY): HResult; reintroduce; stdcall;
   {IShellPropSheetExt}
   function AddPages(lpfnAddPage: TFNAddPropSheetPage;
     lParam: LPARAM): HResult; stdcall;
   function ReplacePage(uPageID: UINT;
     lpfnReplaceWith: TFNAddPropSheetPage;
     lParam: LPARAM): HResult; stdcall;
 end;

 const
   Class_TextProp: TGUID = '{F7195E61-C384-11D2-89E8-80FA4797BEC7}';

Можно приступать к реализации методов. Метод Initialize взят из примера Contmenu.dpr, входящего в комплект поставки Delphi, метод ReplacePage не делает ничего, кроме возвращения кода успешного завершения. Таким образом, наиболее интересен код метода AddPages:
Код
 function TTextProp.AddPages(lpfnAddPage: TFNAddPropSheetPage;
   lParam: LPARAM): HResult; stdcall;
 var
    PSP : TPropSheetPage;
   hPage : HPROPSHEETPAGE;
 begin
   // Добавляем свою страницу свойств
   Result := E_FAIL;
   FillChar(PSP.SizeOf(PSP), 0);
   with PSP do
     begin
       dwSize := SizeOf(PSP);
       dwFlags := PSP_DEFAULT or PSP_USEICONID;
       hlnstance := Syslnit.hlnstance;
       pszlcon := 'MAINICON';
       pszTemplate := 'SheetDialog'; // Имя шаблона в ресурсе
       pfnDlgProc  := @DialogProc;
       lParam := Integer(Self);
       // Ссылка на себя для DialogProc
     end;
   hPage  := CreatePropertySheetPage(PSP);
   if Assigned(hPage) then
     begin
       // OK,  создали страницу успешно.
       // добавляем ее в PageControl
       lpfnAddPage(hPage,  lParam);
       // Увеличиваем счетчик ссылок
       _AddRef;
       Result  := NOERROR;
     end;
 end;

Как видим, сам по себе метод несложен, но в его коде есть один тонкий момент. Дело в том, что оболочка Windows после вызова этого метода «отпускает» СОМ-сервер, вызывая его метод IUnknown._Release, что приводит к его немедленному разрушению и выгрузке DLL из памяти. Однако это явно не входит в наши планы, а поэтому мы должны проделать описанную ниже процедуру.

1. Принудительно увеличить счетчик ссылок вызовом метода _AddRef.
2. По завершении работы с диалоговым окном вызвать метод _Release для освобождения памяти.
3. Запомнить где-то ссылку на себя и сохранять ее до конца работы (чтобы вызвать метод _Release впоследствии).
Ссылка запоминается в поле lParam структуры TPropSheetPage. В дальнейшем это поле будет передано в диалоговую процедуру, и мы сможем сохранить ссылку.

ВНИМАНИЕ
Это редчайший случай прямого вмешательства в механизм автоматического управления подсчетом интерфейсных ссылок. Без веских на то оснований вызывать методы AddRef и Release не надо.


Создание описания диалогового окна и диалоговой функции

Как мы уже ранее упоминали, описание диалогового окна должно храниться в файле ресурсов программы. Для этого необходимо создать ресурс типа DIALOGEX (файл sheet.rc) и подключить его к проекту. Кроме того, нам понадобится модуль с описаниями констант следующего содержания:
Код
 unit  Constant;
 interface
 const
   ID_MEMO = 1;
   ID_LOAD = 2;
 implementation
 end.

В самом файле ресурсов надо добавить следующее описание диалогового окна:
Код
 #include "constant.pas"
 SheetOialog DIALOGEX 0, 0, 0, 0
 FONT 8, "MS Shell Dlg"
 STYLE DS_SETFONT | DS_FIXEDSYS
 CAPTION "Delphi Extension"
 begin
   EDITTEXT ID_MEMO, 10, 10, 150, 120, ES_MULTILINE | ES_READONLY
   PUSHBUTTON "&Sample", ID_LOAD, 100, 140, 60, 12
 END

Как видите, описание диалогового окна достаточно просто и очевидно. Диалоговое окно будет содержать мемо-поле и кнопку. Более подробно о языке описания ресурсов можно узнать из документации Windows SDK. Однако это лишь описание расположения элементов управления на форме. От нас требуется написать код, обеспечивающий функциональность диалогового окна. Этот код расположен в функции DialogProc, которая вызывается каждый раз, когда нашему окну приходит сообщение. К счастью, нет необходимости обрабатывать все сообщения Windows (для этого существует функция DefWindowProc), необходимо лишь описать специфическую функциональность, нужную нам.
Код
 const
   WM_CREATED = WM_APP + 1;

 function DialogProc(hWnd: THandle; Msg: UINT;
   wParam: WPARAM; lParam: LPARAM): BOOL; stdcall;
 var
   Buffer: array[0..1024] of Char;
   Count: Integer;
   hChild: THandle;
   TP: TTextProp;
   R: TRect;
 begin
   case Msg of
 ...

Сообщение WM_INITDIALOG приходит при создании страницы. В поле lParam хранится значение, которое передается в TPropSheetPag.lParam. Для сохранения ссылки на объект TTextProp воспользуемся возможностью поставить в соответствие любому окну произвольное число. Его можно записать вызовом функции SetWindowLong с параметром DWL_USER, а получить - вызовом функции GetWindowLong. Кроме этого мы отправляем сами себе сообщение WM_CREATED с помощью функции PostMessage. Это гарантирует, что оно придет после полного завершения инициализации окна.
Код
 WM_INITDIALOG:
   begin
     TP := TTextProp(PPropSheetPage(lParam).lParam);
     SetWindowLong(hWnd, DWL_USER, Integer(TP));
     PostMessage(hWnd, WM_CREATED,  0,  0);
   end;

Окно полностью проинициализировано, корректируем координаты элементов управления, чтобы они располагались корректно вне зависимости от разрешения и установленного шрифта:
Код
 WM_CREATED:
   begin
     GetWindowRect(hWnd, R);
     hChild := GetDlgItem(hWnd, ID_MEMO);
     MoveWindow(hChild, 20, 20, R.Right - R.Left - 40,
       R.Bottom - R.Top - 70, FALSE);
     hChild := GetDlgItem(hWnd, ID_LOAD);
     MoveWindow(hChild, R.Right - R.Left - 20 - 100,
       R.Bottom - R.Top - 40,  100,  30,  FALSE);
   end;

Сообщение WM_COMMAND приходит каждый раз, когда пользователь выбирает в окне какой-то элемент управления. Мы обрабатываем только одну команду - по щелчку на кнопке загружаем в многострочное поле первый килобайт файла:
Код
 WM_COMMAND:
   begin
     if (LoWord(wParam) = ID_LOAD) and
        (HiWord(wParam) = BN_CLICKED) then
       begin // Щелкнули на кнопке Sample
         TP := TTextProp(GetWindowLong(hWnd, DWL_USER));
         with TFileStream.Create(TP.FileName, fmOpenRead) do
           try
             FillChar(Buffer, SizeOf(Buffer), 0);
             Count := Size;
             if Count >= SizeOf(Buffer) then
               Count := SizeOf(Buffer) - 1;
             ReadBuffer(Buffer, Count);
             hChild := GetDlgItem(hWnd, ID_MEMO);
             SendMessage(hChild, WM_SETTEXT, 0, Integer(@Buffer));
           finally
             Free;
           end;
       end;
   end;

Сообщение WM_DESTROY приходит при уничтожении окна. Освобождаем ранее выделенную память и позволяем выгрузиться нашему СОМ-серверу:
Код
 WM_DESTROY:
   begin
     TP := TTextProp(GetWindowLong(hWnd, DWL_USER));
     CoTaskMemFree(TP.FileName);
     TP._Release;
   end;

Все остальные сообщения передаются в процедуру обработки, предоставленную Windows API:
Код
   else
     Result := BOOL(DefWindowProc(hWnd, Msg,  wParam,  lParam));
     Exit;
   end;
   Result := True;
 end;

Как видите, создание диалогового окна средствами API - не такая уж сложная задача.


Регистрация расширения оболочки

Наше приложение, которое является СОМ-сервером, должно прописать в реестре дополнительную информацию о том, к какому расширению файла оно относится. Удобно делать это одновременно с регистрацией СОМ-сервера. Как известно, регистрация осуществляется вызовами функций DllRegisterServer и DllUnregisterServer, которые Delphi предоставляет автоматически. Однако мы можем вмешаться в этот процесс и дополнить их функциональность. Для этого откроем файл проекта и модифицируем его. Вначале определим константы, чтобы полученный код было легко модифицировать:
Код
 const
   EXT = '.txt';
   DESCRIPTIVE = 'txtfile';
   FRIENDLYJWIE = 'Текстовый документ';
   KEY_NAME = DESCRIPTIVE + '\shellex\PropertySheetHandlers';

В функции DllRegisterServer после успешной регистрации сервера функцией из модуля ComServ проверим наличие в реестре требуемых ключей и при необходимости добавим их:
Код
 function DllRegisterServer: HResult; stdcall;
 var
   RegKey: HKEY;
 begin
   Result := ComServ.DllRegisterServer;
   if Result = S_OK then
     begin
       CreateRegKey(EXT, '', DESCRIPTIVE, HKEY_CLASSES_ROOT);
       if RegOpenKey(HKEY_CLASSES_ROOT, DESCRIPTIVE,
          RegKey) <> ERROR_SUCCESS then
         begin
           RegCloseKey(RegKey);
           CreateRegKey(DESCRIPTIVE, '', '', HKEY_CLASSES_ROOT);
         end;
       CreateRegKey(Format (KEY_NAME + '\%s', [GUIDToString(Class_TextProp)]), '', '',            HKEY_CLASSES_ROOT);
     end;
 end;

В функции DllUnregisterServer удалим ненужный ключ с регистрацией расширения оболочки:
Код
 function DllUnregisterServer: HResult; stdcall;
 begin
   DeleteRegKey(KEY_NAME, HKEY_CLASSES_ROOT);
   Result := ComServ.DllUnRegisterServer;
 end;

Осталось зарегистрировать расширение в Windows. На компьютере разработчика для этого можно воспользоваться командой Run > Register ActiveX Server, на компьютере клиента - утилитой RegSvr32 из состава Windows или TRegSvr из комплекта поставки Delphi. После регистрации программы выберите в Проводнике Windows файл с расширением *.txt и посмотрите его свойства.
Полные исходные тексты расширения оболочки приведены на прилагаемом компакт-диске.


Заключение (поскипан, бо напрямую к обсуждаемому вопроу не отностся)



2 Vit
Простите за оффтоп, но очень жаль, что вы так и не установили подсветку синтаксися. huh2.gif dontgetit.gif
PM MAIL ICQ   Вверх
Illusion Dolphin
Дата 12.12.2003, 17:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 36
Всего: 63



Большое спасибо!!! Попробую сделать...


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
yDa5HuK
Дата 7.6.2007, 10:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 21
Регистрация: 24.11.2006

Репутация: нет
Всего: нет



Код

/*****************************************************************
    Шахматы
*****************************************************************/
/*программа состоит из нескольких файлов*/

:- [globals].        % DOMAINS, PREDICATES
:- [zug_gen].    % генератор позиций
:- [stack].        % стек
:- [pos_val].    % вычисление позиций

frontchar(I,C,R):-
    nonvar(I),
    name(I,S),
    S = [Char|Rest],
    name(R,Rest),
    name(C,[Char]),!.
frontchar(I,C,R):-
    nonvar(C),nonvar(R),
    name(Rest,R),
    name([Char],C),
    S = [Char|Rest],
    name(I,S),!.

str_char(S,C):-
    name(S,[C]).

char_int(C,C).

generate(Move,Farbe,Old,New,Hit):-
    all_moves(Farbe,Old,Move),
    make_move(Farbe,Old,Move,New,Hit).

/*****************************************************************
    Альфа-бета - алгоритм
*****************************************************************/
/*
depth - глубина 
stellung - позиция
*/

/*новая глубина поиска*/
newdepth(_Depth,hit,NewDepth) :-
    top(X),
    X<4,
    NewDepth=1,!.
newdepth(Depth,_,NewDepth) :-
    NewDepth is Depth-1,!.    

/*уточнение границ*/
get_best(Stellung,Color,Depth,Alpha,Beta) :-
    invert(Color,Op),
    generate(Move,Color,Stellung,Neu_Stellung,Hit),
    newdepth(Depth,Hit,New_Depth),
    new_alpha_beta(Color,Alpha,New_Alpha,Beta,New_Beta),
    evaluate(Neu_Stellung,Op,Value,_,New_Depth,New_Alpha,New_Beta),
    compare_move(Move,Value,Color),
    cutting(Value,Color,Alpha,Beta),
    !,fail.

/*новые границы*/    
new_alpha_beta(white,Alpha,New_Alpha,Beta,Beta) :-
    get_0(_,Value),
    Value>Alpha,
    New_Alpha=Value,!.
new_alpha_beta(black,Alpha,Alpha,Beta,New_Beta) :-
    get_0(_,Value),
    Value<Beta,
    New_Beta=Value,!.
new_alpha_beta(_,Alpha,Alpha,Beta,Beta).
    
compare_move(_,Value,white) :-
    get_0(_,Old),
    Old>=Value,!.
compare_move(_,Value,black) :-
    get_0(_,Old),
    Old =< Value,!.
compare_move(Move,Value,_) :-
    replace(Move,Value).

cutting(Value,white,_,Beta) :-
    Beta<Value.
cutting(Value,black,Alpha,_) :-
    Alpha>Value.

/*выбор позиции*/
evaluate(stellung(halbstellung(_,_,_,_,_,[],_),_,_),_,Value,move(0,0),_,_,_) :-
    winning(black,Value),!.
evaluate(stellung(_,halbstellung(_,_,_,_,_,[],_),_),_,Value,move(0,0),_,_,_) :-
    winning(white,Value),!.
evaluate(stellung(W,B,_),Color,Value,move(0,0),0,_,_) :-
    count_halbst(W,white,X),
    count_halbst(B,black,Y),
    compensate(Color,Z),
    Value is X-Y+Z,!.
evaluate(Stellung,Color,Value,Move,Depth,Alpha,Beta) :-
    worst_value(Color,Worst),
    push(move(0,0),Worst),
    not(get_best(Stellung,Color,Depth,Alpha,Beta)),
    pull(Move,Value),!.
    
/****************************************************************
    Управление игрой
****************************************************************/

/*считываем ход шахматиста проверяем корректность ввода*/
enter(Stellung,Color,Move) :-
    human(Color),
    repeat,
    read_move(Move),
     (    check_legal(Move,Color,Stellung),!;
        write('Illegal Move'),fail
     ).

/*поиск наилучшего хода-ответа по альфа-бета алгоритму*/
enter(Stellung,Color,Move) :-    
    depth(Depth),!,
    worst_value(white,Alpha),
    worst_value(black,Beta),
    evaluate(Stellung,Color,_Value,Move,Depth,Alpha,Beta),
    write_move(Move),!.

/*игра начинается*/    
play(GrundStellung,Anzug) :-
    asserta(brett(GrundStellung,Anzug)),
    repeat,
    retract(brett(Stellung,Color)),
    enter(Stellung,Color,Move),
    make_move(Color,Stellung,Move,New,_),
    invert(Color,Op),
    asserta(brett(New,Op)),
    fail.
play(_,_).

    
/****************************************************************
    Глобальные предикаты
****************************************************************/

change(Old,Color,From,To,New):-
    half(Old,Halb,Color),
    exist(From,Halb,Typ),
    extract(Halb,Typ,Liste),
    remove(From,Liste,Templist),
    combine(Halb,Typ,[To|Templist],Newhalb),
    add_half(Old,Newhalb,Color,New).

kill(Old,Color,Feld,New):- 
    half(Old,Halb,Color),
    exist(Feld,Halb,Typ),
    extract(Halb,Typ,Liste),
    remove(Feld,Liste,Newlist),
    combine(Halb,Typ,Newlist,Newhalb),
    add_half(Old,Newhalb,Color,New).
    
extract(halbstellung(X,_,_,_,_,_,_),pawn,X).
extract(halbstellung(_,X,_,_,_,_,_),rook,X).
extract(halbstellung(_,_,X,_,_,_,_),knight,X).
extract(halbstellung(_,_,_,X,_,_,_),bishop,X).
extract(halbstellung(_,_,_,_,X,_,_),queen,X).
extract(halbstellung(_,_,_,_,_,X,_),king,X).

combine(halbstellung(_,B,C,D,E,F,G),pawn,N,halbstellung(N,B,C,D,E,F,G)).
combine(halbstellung(A,_,C,D,E,F,G),rook,N,halbstellung(A,N,C,D,E,F,G)).
combine(halbstellung(A,B,_,D,E,F,G),knight,N,halbstellung(A,B,N,D,E,F,G)).
combine(halbstellung(A,B,C,_,E,F,G),bishop,N,halbstellung(A,B,C,N,E,F,G)).
combine(halbstellung(A,B,C,D,_,F,G),queen,N,halbstellung(A,B,C,D,N,F,G)).
combine(halbstellung(A,B,C,D,E,_,G),king,N,halbstellung(A,B,C,D,E,N,G)).
    
/****************************************************************
    Вычислительны е подпрограммки
****************************************************************/

check_00(Old,white,15,17,New) :-
    Old=stellung(halbstellung(_,_,_,_,_,[15],_),_,_),
    change(Old,white,18,16,New),!.
check_00(Old,white,15,13,New) :-
    Old=stellung(halbstellung(_,_,_,_,_,[15],_),_,_),
    change(Old,white,11,14,New),!.
check_00(Old,black,85,87,New) :-
    Old=stellung(_,halbstellung(_,_,_,_,_,[85],_),_),
    change(Old,black,88,86,New),!.
check_00(Old,black,85,83,New) :-
    Old=stellung(_,halbstellung(_,_,_,_,_,[85],_),_),
    change(Old,black,81,84,New),!.
check_00(Old,_,_,_,Old).

make_move(Farbe,Old,move(From,To),New,hit):-
    invert(Farbe,Oppo),
    kill(Old,Oppo,To,Temp),
    change(Temp,Farbe,From,To,New),!.
make_move(Farbe,Old,move(From,To),New,nohit):-
    check_00(Old,Farbe,From,To,Temp),
    change(Temp,Farbe,From,To,New),!.

/****************************************************************
    Интерфейс
****************************************************************/
/*очередной ход*/
read_move(move(From,To)):-
    repeat,
    nl,write('Man move: '),
    read(Input),
    (
    Input = 'exit', halt;
    name(Input,[A,B,C,D]),
    str_pos([A,B],From),
    str_pos([C,D],To),!;
    write('Wrong format ( enter like <a1b2.> '),
    fail
     ).

/*координаты*/
str_pos([L,C],Pos):-
    nonvar(Pos),
    pos_no(Row,Col,Pos),
    L is Col + 96,
    C is Row + 48,!.
str_pos([L,C],Pos):-
    Col is L - 96,
    Row is C - 48,
    pos_no(Row,Col,Pos),!.

pos_no(Row,Col,N):-
    nonvar(N),!,
    Row is N // 10,
    Col is N mod 10.
pos_no(R,C,N):-
    N  is  R*10 + C.

/*возможен ли ход*/
check_legal(Move,Color,Stellung):-
    generate(PosMove,Color,Stellung,_,_),
    Move = PosMove,!.

/*выводим на экран ход компьютера*/
write_move(move(From,To)):-
    str_pos([A,B],From),
    str_pos([C,D],To),
         name(Move,[A,B,C,D]),
    write('Computer move:   '),write(Move),!.

/*объясняем пользователю правила игры*/    
/*пользователь всегда играет белыми*/
who_vs_who:-
    write('1st player - man (white)'),nl,
    write('2nd player - computer (black)'),nl,nl,
    write('Enter moves like <d2d4.>'),nl,
    write('Enter <exit.> to quit'),nl,nl,
    write('Start'),nl,
    asserta(human(white)),!.

                
/****************************************************************
    Запуск 
****************************************************************/
/*brett - доска
grund - причина
stellung - позиция
bauer - пешка (фигура)*/

/*начальное расположение фигур на доске*/
grundstellung(stellung(H1,H2,0)):-
    Bauerw = [21,22,23,24,25,26,27,28],
    H1 = halbstellung(Bauerw,[11,18],[12,17],[13,16],[14],[15],notmoved),
    Bauerb = [71,72,73,74,75,76,77,78],
    H2 = halbstellung(Bauerb,[81,88],[82,87],[83,86],[84],[85],notmoved).

/*запуск*/
run:-
    retractall(stack(_,_,_)),
    retractall(top(_)),
    retractall(human(_)),
    retractall(depth(_)),
    retractall(brett(_,_)),

    grundstellung(Stellung),
    asserta(depth(2)),
    init_stack,
    who_vs_who,
    play(Stellung,white),
    closechess.    
            

это код для игры в шахматы, компилятор выдает ошибку:
4 use the format CODE=dddd, HEAP=dddd or ERRORLEVEL=d.
Версия PROLOG 3.3 
Заранее всех благодарю.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

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

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0558 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.