(*~\Глагол\Отделы\Игры\Шашки\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                         ОТДЕЛ Игра;
(*============================================================================*)
(* Программа игры в русские шашки (8х8) на языке Глагол (www.glagol.nad.ru).  *)
(*                                                                            *)
(* НАЗНАЧЕНИЕ: алгоритм игры в шашки                                          *)
(* ПРИМЕЧАНИЯ: если программа долго думает или слишком умно ходит,            *)
(*             то надо уменьшить <уровень> (и наоборот).                      *)
(*----------------------------------------------------------------------------*)
(* Позиция: 90 91 ... 98 99, игровое поле доски между 11 и 88 клетками.       *)
(*          80 81 ... 88 89  Доступ к позиции:                                *)
(*          ...............  1) по номеру         клетки  n  (от 0 до 99),    *)
(*          10 11 ... 18 19  2) по местоположению клетки x,y (от 0 до 9),     *)
(*           0  1 ...  8  9  3) по номеру чёрной  клетки  ч  (от 0 до 32).    *)
(*============================================================================*)

ИСПОЛЬЗУЕТ
(*
  Окно    ИЗ "....\Отделы\Обмен\";
*)
  Окно    ИЗ "..\..\..\Отделы\Обмен\";

ПОСТ
                                         (* признаки клетки *)
  вне-     = 0;  (* вне игрового поля *)
  нижние-  = 1;  (* занято нижними    *)
  верхние- = 2;  (* занято верхними   *)
  дамка-   = 3;  (* занято дамкой     *)
                                         (* веса *)
  весШашки    = 100;
  весДамки    = весШашки*2;
  весОгромный = весДамки*10;
                                         (* смещение на одну клетку для n *)
  вправо=1; 
  влево=-1;  
  вверх=10; 
  вниз=-10; 
                                         (* наибольшее число взятий за ход *)
  бьемЗаХод  = 10;
                                    (* наибольшее число рассматриваемых ходов *)
  всегоХодов = 300; 

ВИД
                           (* описатель хода *)
  нХод- = НАБОР
    откудаN-:ЦЕЛ;                 (* начальная клетка   *)
    кудаN-  :ЦЕЛ;                 (* конечная клетка    *)
    битых-  :ЦЕЛ;                 (* всего битых клеток *)
    битыеN- :РЯД бьемЗаХод ИЗ ЦЕЛ;(* n для битых клеток *)
    дамкой- :КЛЮЧ                 (* если пришла дамкой *)
  КОН;
                           (* данные для отката хода *)
  нОткат = НАБОР
    вес:ЦЕЛ;                      (* вес позиции до этого хода      *)  
    клетка:МНОЖ;                  (* признаки клетки откуда ходили  *)
    битые:РЯД бьемЗаХод ИЗ МНОЖ   (* хранилище битых клеток         *)
  КОН;

  ВидЗадачиГОС = ЗАДАЧА;   (* нигде не используется *)

ПЕР
     ходы+:РЯД всегоХодов ИЗ нХод; (* память для рассм. ходов        *)
  позиция-:РЯД 100 ИЗ МНОЖ;        (* текущие признаки всех клеток   *)

    вес :ЦЕЛ;                      (* текущий вес позиции            *)
  конец-:КЛЮЧ;                     (* ВКЛ, если конец игры           *)

  ходМашины-:нХод;                 (* вычисленный ход машины         *)

  уровень+:ЦЕЛ;                    (* полуходов грубого поиска       *)

  NвX-,NвY-,NвЧ:РЯД 100 ИЗ ЦЕЛ;    (* ускорение перевода n в x,y и ч *)
  XYвN-:РЯД 10,10 ИЗ ЦЕЛ;          (* перевод x,y в n                *)
  ЧвN:РЯД 32 ИЗ ЦЕЛ;               (* ускорение перевода ч в n       *)
                           (* переменные для нахождения возможных ходов *)
  свои,чужие:ЦЕЛ;                  (* 'верхние' или 'нижние'         *)
  вперед:ЦЕЛ;                      (* смещение на одну клетку для n  *)
  Yдамок:ЦЕЛ;                      (* Y превращения шашки в дамку    *)
                           (* постоянные на всем протяжении работы приложения *)
    соседи:РЯД 4 ИЗ ЦЕЛ;           (* смещение n для соседних клеток *) 
  весШашек:РЯД 32 ИЗ ЦЕЛ;          (* веса ч клеток для нижних шашек *)
  весДамок:РЯД 32 ИЗ ЦЕЛ;          (* веса ч клеток для нижних дамок *)

  пустойХод+:нХод;              

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА СторонаХода-(сторона:ЦЕЛ);
(*
 * Цель:  обозначить своих и чужих для нахождения возможных ходов
 * До:    <сторона> - 'верхние' или 'нижние'
 * После: <свои>    - = <сторона>
 *        <чужие>   - противоположная к <свои> сторона
 *        <вперед>  - вверх или вниз
 *        <Yдамок>  - Y превращения шашки в дамки (1 или 8)
 *)
УКАЗ
       свои:=сторона;
  ЕСЛИ
       свои = нижние
  ТО
    чужие:=верхние;
    вперед:=вверх;
    Yдамок:=8
  ИНАЧЕ
    чужие:=нижние;
    вперед:=вниз;
    Yдамок:=1
  КОН;
КОН СторонаХода;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА НайтиТихиеИзN-(откудаN,ходов+:ЦЕЛ);
(*
 * Цель:  найти все возможные тихие ходы (не взятия) из данной клетки
 * До:    <откудаN> - начальная клетка
 *        <ходов>   - число уже найденных ходов
 * После: <ходы>  - заполненные описатели ходов
 *        <ходов> - всего найденных ходов
 *)
ПЕР
  кудаN,сдвиг,i:ЦЕЛ;

 (*-------------------------------- подЗадача --------------------------------*)
  ЗАДАЧА ЗаписатьХод(откудаN,
                     кудаN:ЦЕЛ; ход+:нХод);
  УКАЗ
    ход.откудаN:=откудаN;
    ход.кудаN:=кудаN;
    ход.дамкой:=(дамка В позиция[откудаN]) ИЛИ (NвY[кудаN] = Yдамок);
    ход.битых:=0;
  КОН ЗаписатьХод;

УКАЗ
  ЕСЛИ
       дамка В позиция[откудаN]
  ТО
    ОТ i:=0 ДО РАЗМЕР(соседи)-1 ВЫП
      сдвиг:=соседи[i];
      кудаN:=откудаN+сдвиг;
      ПОКА
           позиция[кудаN] = {}
      ВЫП
        ЗаписатьХод(откудаN,кудаN,ходы[ходов]);
        УВЕЛИЧИТЬ(ходов);
        УВЕЛИЧИТЬ(кудаN,сдвиг)
      КОН
    КОН
  ИНАЧЕ
    кудаN:=откудаN+вперед+вправо;
    ЕСЛИ
         позиция[кудаN] = {}
    ТО
      ЗаписатьХод(откудаN,кудаN,ходы[ходов]);
      УВЕЛИЧИТЬ(ходов)
    КОН;
    кудаN:=откудаN+вперед+влево;
    ЕСЛИ
         позиция[кудаN] = {}
    ТО
      ЗаписатьХод(откудаN,кудаN,ходы[ходов]);
      УВЕЛИЧИТЬ(ходов)
    КОН
  КОН
КОН НайтиТихиеИзN;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА НайтиУдарныеИзN-(откудаN,ходов+:ЦЕЛ);
(*
 * Цель:  найти все возможные ударные ходы из данной клетки
 * До:    <откудаN> - начальная клетка
 *        <ходов>   - число уже найденных ходов
 * После: <ходы>  - заполненные описатели ходов
 *        <ходов> - всего найденных ходов
 *)
ПОСТ
  (* состояния бьющей фигуры *)
  простоШашка = -3;
  простоДамка = -2;
  дамкаБьет   = -1; (* уже нашла бой   *)
  дамкаИщет   =  0; (* только ищет бой *)
ПЕР
  битых:ЦЕЛ; (* в текущей цепочке боя *)
  битыеN:РЯД бьемЗаХод ИЗ ЦЕЛ;
  откуда:МНОЖ;
  состояние:ЦЕЛ;

  ЗАДАЧА ЗаписатьХод(откудаN,кудаN:ЦЕЛ; дамкой:КЛЮЧ; ход+:нХод);
  ПЕР
    i:ЦЕЛ;
  УКАЗ
    ход.откудаN:=откудаN;
    ход.кудаN:=кудаN;
    ход.дамкой:=дамкой;
    ход.битых:=битых;

    ОТ i:=0 ДО битых-1 ВЫП
      ход.битыеN[i]:=битыеN[i]
    КОН
  КОН ЗаписатьХод;

  ЗАДАЧА Бьём(состояние+,откудаN,направление,отN,ходов+:ЦЕЛ);
  (*
   * Цель:  попытаться кого-либо убить из данной клетки
   * До:    <откудаN>     - где сидим
   *        <состояние>   - текущее состояние бьющей фигуры
   *        <направление> - с которого уже били
   *        <отN>         - начальная клетка боя
   *        <ходов>       - число уже найденных ходов
   * После: если не можем бить, то <откудаN> это конец предыдущего боя и
   *        его добавляем в <ходы>
   *)
  ПЕР
    кудаN,битаяN,сдвиг,i:ЦЕЛ;
    битая:МНОЖ; (* для хранения битой фигуры *)
    бьет:КЛЮЧ;  (* ВКЛ, если можно бить из <откудаN> *)
    будетСостояние:ЦЕЛ;
  УКАЗ
    бьет:=ОТКЛ;
    ОТ i:=0 ДО РАЗМЕР(соседи)-1 ВЫП
      ЕСЛИ
           (i+направление) # 3
      ТО                            (* назад не бьем *)
        сдвиг:=соседи[i];
        битаяN:=откудаN+сдвиг;
        ЕСЛИ
             (состояние >= простоДамка)
            И
             (i # направление)
        ТО               (* для дамки скользим в стороны, а в перед как шашка *)
          ПОКА
               позиция[битаяN] = {}
          ВЫП
            УВЕЛИЧИТЬ(битаяN,сдвиг)
          КОН
        КОН;
        кудаN:=битаяN+сдвиг;
        ЕСЛИ
             (чужие В позиция[битаяN]) И (позиция[кудаN] = {})
        ТО
          бьет:=ВКЛ;
          битыеN[битых]:=битаяN;
          УВЕЛИЧИТЬ(битых);
          ЕСЛИ
               состояние >= дамкаИщет
          ТО                                 (* для дамки которая еще не била *)
            ходов:=состояние;  (* удаляем предыдущие пустые ходы *)
            состояние:=дамкаБьет
          КОН;
                               (* временно заменяем битую фигуру своей шашкой *)
          битая:=позиция[битаяN];
          позиция[битаяN]:={свои};
                                        (* идем дальше *)
          ЕСЛИ
               состояние >= простоДамка
          ТО
                   будетСостояние:=ходов;   (* запоминаем начало пустых ходов *)
            ПОКА
                 позиция[кудаN] = {}
            ВЫП
              Бьём(будетСостояние,кудаN,i,отN,ходов);
              УВЕЛИЧИТЬ(кудаN,сдвиг)
            КОН
          ИНАЧЕ
            ЕСЛИ
                 NвY[кудаN] = Yдамок
            ТО
                 будетСостояние:=простоДамка
            ИНАЧЕ
                 будетСостояние:=простоШашка
            КОН;
            Бьём(будетСостояние,кудаN,i,отN,ходов)
          КОН;
                                  (* восстанавливаем битую фигуру *)
          позиция[битаяN]:=битая;
                                  (* и больше не будем ее добавлять в <ходы> *)
          УМЕНЬШИТЬ(битых)
        КОН
      КОН
    КОН;
    ЕСЛИ
         (НЕ бьет) И (битых > 0) И (состояние # дамкаБьет)
    ТО
      ЗаписатьХод(отN,откудаN,состояние >= простоДамка,ходы[ходов]);
      УВЕЛИЧИТЬ(ходов)
    КОН
  КОН Бьём;
     
УКАЗ
  битых:=0;
                                           (* временно убираем бьющую фигуру *)
  откуда:=позиция[откудаN];
  позиция[откудаN]:={};
                                           (* ищем ходы *)
  ЕСЛИ
       дамка В откуда
  ТО
       состояние:=простоДамка
  ИНАЧЕ
       состояние:=простоШашка
  КОН;
  Бьём(состояние,откудаN,-1,откудаN,ходов);
                                           (* восстанавливаем бьющую фигуру *)
  позиция[откудаN]:=откуда
КОН НайтиУдарныеИзN;

(*----------------------------------------------------------------------------*)
ЗАДАЧА НайтиТихие(ходов+:ЦЕЛ);
(*
 * Цель:  найти все возможные тихие ходы (не взятия)
 * До:    <ходов> - число уже найденных ходов
 * После: <ходы>  - заполненные описатели ходов
 *        <ходов> - всего найденных ходов
 *)
ПЕР
  ч:ЦЕЛ;
УКАЗ
  ЕСЛИ свои = нижние ТО 
                            (* передние идут первыми *)
    ОТ ч:=31 ДО 0 ПО -1 ВЫП
      ЕСЛИ
           свои В позиция[ЧвN[ч]]
      ТО
        Игра.НайтиТихиеИзN(ЧвN[ч],ходов)
      КОН
    КОН
  ИНАЧЕ
    ОТ ч:=0 ДО 31 ВЫП
      ЕСЛИ
           свои В позиция[ЧвN[ч]]
      ТО
        Игра.НайтиТихиеИзN(ЧвN[ч],ходов)
      КОН
    КОН
  КОН
КОН НайтиТихие;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА НайтиУдарные-(ходов+:ЦЕЛ);
(*
 * Цель:  найти все возможные ударные ходы
 * До:    <ходов> - число уже найденных ходов
 * После: <ходы>  - заполненные описатели ходов
 *        <ходов> - всего найденных ходов
 *)
ПЕР
  ч:ЦЕЛ;
УКАЗ
  ОТ ч:=0 ДО 31 ВЫП
    ЕСЛИ
         свои В позиция[ЧвN[ч]]
    ТО
      Игра.НайтиУдарныеИзN(ЧвN[ч],ходов)
    КОН
  КОН
КОН НайтиУдарные;

(*----------------------------------------------------------------------------*)
ЗАДАЧА Убрать_клетку(n:ЦЕЛ):МНОЖ;
(*
 * Цель:  убрать клетку <n> и пересчитать вес позиции для нижних
 * До:    <n> - номер клетки
 * Ответ: признаки убираемой клетки
 *)
ПЕР
  клетка:МНОЖ;
УКАЗ
  клетка:=позиция[n];
  позиция[n]:={};
                         (* убавление веса позиции *)
  ЕСЛИ нижние В клетка ТО
    ЕСЛИ дамка В клетка ТО
      УМЕНЬШИТЬ(вес,весДамки);
      УМЕНЬШИТЬ(вес,весДамок[NвЧ[n]])
    ИНАЧЕ
      УМЕНЬШИТЬ(вес,весШашки);
      УМЕНЬШИТЬ(вес,весШашек[NвЧ[n]])
    КОН
  ИНАЧЕ
    ЕСЛИ дамка В клетка ТО
      УВЕЛИЧИТЬ(вес,весДамки);
      УВЕЛИЧИТЬ(вес,весДамок[31-NвЧ[n]])
    ИНАЧЕ
      УВЕЛИЧИТЬ(вес,весШашки);
      УВЕЛИЧИТЬ(вес,весШашек[31-NвЧ[n]])
    КОН
  КОН;
  ВОЗВРАТ клетка
КОН Убрать_клетку;

(*----------------------------------------------------------------------------*)
ЗАДАЧА Поставить_на_клетку(n:ЦЕЛ; клетка:МНОЖ);
(*
 * Цель:  поставить на <n> данную <клетка> и пересчитать вес позиции для нижних
 * До:    <n>      - номер клетки
 *        <клетка> - признаки клетки
 *)
УКАЗ
  позиция[n]:=клетка;
                         (* приращение веса позиции *)
  ЕСЛИ 
        нижние В клетка
  ТО
    ЕСЛИ
         дамка В клетка
    ТО
      УВЕЛИЧИТЬ(вес,весДамки);
      УВЕЛИЧИТЬ(вес,весДамок[NвЧ[n]])
    ИНАЧЕ
      УВЕЛИЧИТЬ(вес,весШашки);
      УВЕЛИЧИТЬ(вес,весШашек[NвЧ[n]])
    КОН
  ИНАЧЕ
    ЕСЛИ
         дамка В клетка
    ТО
      УМЕНЬШИТЬ(вес,весДамки);
      УМЕНЬШИТЬ(вес,весДамок[31-NвЧ[n]])
    ИНАЧЕ
      УМЕНЬШИТЬ(вес,весШашки);
      УМЕНЬШИТЬ(вес,весШашек[31-NвЧ[n]])
    КОН
  КОН
КОН Поставить_на_клетку;

(*----------------------------------------------------------------------------*)
ЗАДАЧА Отработка_хода(ход+:нХод; откат+:нОткат);                   (* Заход() *)
(*
 * Цель:  отработка хода
 * До:    <ход>   - данный ход
 * После: <откат> - данные для отката хода <ход>
 *)
ПЕР
  i:ЦЕЛ;
УКАЗ
  откат.вес:=вес;
  откат.клетка:=Убрать_клетку(ход.откудаN);

  ОТ i:=0 ДО ход.битых-1 ВЫП
    откат.битые[i]:=Убрать_клетку(ход.битыеN[i])
  КОН;
  ЕСЛИ
       ход.дамкой
  ТО
    Поставить_на_клетку(ход.кудаN,откат.клетка+{дамка})
  ИНАЧЕ
    Поставить_на_клетку(ход.кудаN,откат.клетка)
  КОН
КОН Отработка_хода;

(*----------------------------------------------------------------------------*)
ЗАДАЧА Откат_хода(ход+:нХод; откат+:нОткат);
(*
 * Цель:  восстановление состояния предшествующего данному ходу
 * До:    <ход>   - предыдущий отработанный ход вперед
 *        <откат> - данные для отката хода <ход>
 *)
ПЕР
  i:ЦЕЛ;
УКАЗ
  вес:=откат.вес;
  позиция[ход.кудаN]:={};

  ОТ i:=0 ДО ход.битых-1 ВЫП
    позиция[ход.битыеN[i]]:=откат.битые[i]
  КОН;
  позиция[ход.откудаN]:=откат.клетка
КОН Откат_хода;

(*----------------------------------------------------------------------------*)
ЗАДАЧА Поиск_хода(свои,alpha,beta,уровень,глубина,ходов0:ЦЕЛ):ЦЕЛ;
(*
 * Цель:  NegaScout поиск хода
 * До:    <свои>    - 'верхние' или 'нижние'
 *        <alpha>   - наибольший достигнутый вес для <свои>
 *        <beta>    - наибольший достигнутый вес для <чужие>
 *        <уровень> - от <уровень> до 0
 *        <глубина> - от 0 до ...
 *        <ходов0>  - уже занято ходов в <ходы>
 * Ответ: наибольший достигнутый вес для <свои>
 *)
ПЕР
  чужие:ЦЕЛ;           (* 'верхние' или 'нижние'       *)
  ходов:ЦЕЛ;           (* ходов из текущей позиции     *)
  откат:нОткат;        (* данные для отката хода       *)
  нхода:ЦЕЛ;           (* номер хода                   *)
  оценка:ЦЕЛ;          (* оценка следующего хода чужих *)
  следУровень:ЦЕЛ;     (* следующий уровень поиска     *)
УКАЗ
  ЕСЛИ свои = нижние ТО        (* давайте определимся *)
    чужие:=верхние
  ИНАЧЕ
    чужие:=нижние
  КОН;
  ЕСЛИ уровень = 0 ТО          (* хватит углубляться *)
    ЕСЛИ
         свои = нижние
    ТО
      ВОЗВРАТ  вес
    ИНАЧЕ
      ВОЗВРАТ -вес
    КОН
  КОН;
                               (* находим все возможные ходы *)
  Игра.СторонаХода(свои);
  ходов:=ходов0;
  НайтиУдарные(ходов);

  ЕСЛИ
         ходов = ходов0
  ТО
    НайтиТихие(ходов);
    ЕСЛИ
         ходов = ходов0
    ТО
      ВОЗВРАТ -весОгромный+глубина
    КОН
  КОН;
                               (* оживим приложение *)
  Окно.Отработать;
                               (* для всех найденых ходов *)
        нхода:=ходов0;
  ПОКА
       (нхода < ходов)
      И
       (alpha < beta)
  ВЫП
    Отработка_хода(ходы[нхода],откат);
    ЕСЛИ
         ходы[нхода].битых > 0
    ТО                         (* взятие не понижает следующий уровень *)
      следУровень:=уровень
    ИНАЧЕ
      следУровень:=уровень-1
    КОН;
                               (* нулевое окно *)
    оценка:=-Поиск_хода(чужие,
                       -(alpha+1),-alpha,следУровень,глубина+1,ходов);
    ЕСЛИ
         (оценка > alpha)
        И
         (оценка < beta)
    ТО                         (* полное окно *)
      оценка:=-Поиск_хода(чужие,
                         -beta,-alpha,следУровень,глубина+1,ходов)
    КОН;
    Откат_хода(ходы[нхода],откат);
    ЕСЛИ
         оценка > alpha
    ТО
                  alpha:=оценка;
      ЕСЛИ
           глубина = 0
      ТО                          (* это хороший ход *)
        ходМашины:=ходы[нхода]
      КОН
    КОН;
    УВЕЛИЧИТЬ(нхода)
  КОН;
  ВОЗВРАТ alpha
КОН Поиск_хода;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ХодНижних-(ход+:нХод);
ПЕР
  откат:нОткат;
УКАЗ
  Отработка_хода(ход,откат)
КОН ХодНижних;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ХодВерхних-;
ПЕР
  оценка:ЦЕЛ;
  откат:нОткат;
УКАЗ
  оценка:=Поиск_хода(верхние,
                    -весОгромный,весОгромный,уровень,0,0);
  ЕСЛИ
       оценка # -весОгромный
  ТО
    Отработка_хода(ходМашины,откат)
  ИНАЧЕ
    конец:=ВКЛ                     (* конец игре *)
  КОН;
                                   (* может машина выиграла ? *)
  ЕСЛИ
       оценка = весОгромный-1
  ТО
    конец:=ВКЛ                     (* конец игре *)
  КОН;
  Игра.СторонаХода(нижние)
КОН ХодВерхних;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА НачатьЗаново-;                   (* Цель:  подготовиться к началу игры *)
ПЕР
  x,y:ЦЕЛ;
  признаки:МНОЖ;
УКАЗ
  вес:=0;
  конец:=ОТКЛ;
  ходМашины:=пустойХод;
  ОТ y:=0 ДО 9 ВЫП
    ОТ x:=0 ДО 9 ВЫП
      ЕСЛИ (y >= 1) И (y <= 8) И (x >= 1) И (x <= 8) ТО (* на доске *)
        признаки:={};
        ЕСЛИ ЧЕТ(x+y) ТО (* черная клетка *)
          ЕСЛИ  (y >= 1) И (y <= 3) ТО
            признаки:={нижние}
          АЕСЛИ (y >= 6) И (y <= 8) ТО
            признаки:={верхние}
          КОН
        КОН
      ИНАЧЕ
        признаки:={вне}
      КОН;
      позиция[XYвN[x,y]]:=признаки
    КОН
  КОН
КОН НачатьЗаново;

(*----------------------------------------------------------------------------*)
ЗАДАЧА Подготовить;
(*
 * Цель:  подготовка отдела в начале работы приложения
 * После: <соседи>                       - смещение n для соседних клеток
 *        <пустойХод>                    - заглушка
 *        <NвX>,<NвY>,<XYвN>,<ЧвN>,<NвЧ> - переводные ряды
 *        <весШашек>,<весДамок>          - клеточные веса для нижних фигур
 *)
ПЕР
  x,y,n,ч:ЦЕЛ;
УКАЗ
  пустойХод.откудаN:=11;
  пустойХод.кудаN:=11;
  пустойХод.битых:=0;
                          (* переводные ряды для n,x,y и ч *)
  ч:=0;
  ОТ y:=0 ДО 9 ВЫП
    ОТ x:=0 ДО 9 ВЫП
      n:=x+y*10;
      NвX[n]:=x;
      NвY[n]:=y;
      NвЧ[n]:=-1;
      XYвN[x,y]:=n;

      ЕСЛИ (y >= 1)
          И
           (y <= 8)
          И
           (x >= 1)
          И
           (x <= 8)
          И
           ЧЕТ(x+y)
      ТО                  (* черная клетка на доске *)
        ЧвN[ч]:=n;  
        NвЧ[n]:=ч;
        УВЕЛИЧИТЬ(ч)
      КОН
    КОН
  КОН;
                          (* смещение n для соседних клеток *)
  соседи[0]:=вправо+вверх;  (* 1 0 *)
  соседи[1]:=влево+вверх;   (*  *  *)
  соседи[2]:=вправо+вниз;   (* 3 2 *)
  соседи[3]:=влево+вниз;
                          (* нумерация черных клеток: 
      28  29  30  31
    24  25  26  27
      20  21  22  23
    16  17  18  19
      12  13  14  15
     8   9  10  11
       4   5   6   7
     0   1   2   3  *)
                          (* веса черных клеток для нижних шашек *)
  весШашек[28]:=20; весШашек[29]:=18; весШашек[30]:=16; весШашек[31]:=18;
  весШашек[24]:=16; весШашек[25]:=17; весШашек[26]:=15; весШашек[27]:=14;
  весШашек[20]:=15; весШашек[21]:=16; весШашек[22]:=12; весШашек[23]:=12;
  весШашек[16]:=14; весШашек[17]:=13; весШашек[18]:=11; весШашек[19]:=10;
  весШашек[12]:=13; весШашек[13]:=11; весШашек[14]:=10; весШашек[15]:= 9;
  весШашек[ 8]:= 5; весШашек[ 9]:= 6; весШашек[10]:= 7; весШашек[11]:= 8;
  весШашек[ 4]:= 1; весШашек[ 5]:= 2; весШашек[ 6]:= 3; весШашек[ 7]:= 4;
  весШашек[ 0]:=17; весШашек[ 1]:=18; весШашек[ 2]:=19; весШашек[ 3]:=16;
  (* веса черных клеток для нижних дамок *)
  весДамок[28]:=16; весДамок[29]:= 9; весДамок[30]:= 9; весДамок[31]:=17;
  весДамок[24]:=15; весДамок[25]:=17; весДамок[26]:=10; весДамок[27]:=18;
  весДамок[20]:=14; весДамок[21]:=19; весДамок[22]:=19; весДамок[23]:=11;
  весДамок[16]:=11; весДамок[17]:=19; весДамок[18]:=20; весДамок[19]:=12;
  весДамок[12]:=12; весДамок[13]:=20; весДамок[14]:=19; весДамок[15]:=11;
  весДамок[ 8]:=11; весДамок[ 9]:=19; весДамок[10]:=19; весДамок[11]:=17;
  весДамок[ 4]:=18; весДамок[ 5]:=10; весДамок[ 6]:=14; весДамок[ 7]:=16;
  весДамок[ 0]:=17; весДамок[ 1]:= 9; весДамок[ 2]:= 9; весДамок[ 3]:=15;
КОН Подготовить;

УКАЗ
  Подготовить
КОН Игра.
