(*~\Глагол\ПриложенияГОС\Игры\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                          ОТДЕЛ КрНолики+;
(*============================================================================*)
(* НАЗНАЧЕНИЕ: пример игры в "Крестики-нолики".                               *)
(* ПРИМЕЧАНИЯ:                                                                *)
(*   для управления можно использовать только мышку,                          *)
(*   правила игры см. в отделе \Глагол\ПриложенияГОС\Игры\КрНолики\Игра.отд   *)
(*============================================================================*)

ИСПОЛЬЗУЕТ 
  Игра    ИЗ "..\..\Отделы\Игры\КрНолики\",                  (* алгоритм игры *)

  Ввод    ИЗ "..\..\Отделы\Обмен\",
  Окно    ИЗ "..\..\Отделы\Обмен\",

  Поле    ИЗ "..\..\Отделы\Поле\",
  Надел   ИЗ "..\..\Отделы\Поле\",
 Подложка ИЗ "..\..\Отделы\Поле\",
  Записка ИЗ "..\..\Отделы\Поле\",
  Кнопка  ИЗ "..\..\Отделы\Поле\";

ПОСТ                        (* действия *)
  діяЗаново = 1;
  діяВыход  = 2;

ПЕР
  запискаД:Записка.Доступ;  (* сообщение от машины *)

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

      ЕСЛИ  зн = " " ТО рисунок:="  "
      АЕСЛИ зн = "+" ТО рисунок:="><"
      АЕСЛИ зн = "о" ТО рисунок:="()"
      КОН;

      к:=1+x*2;
      с:=1+y*1;

      Окно.ЦепьЗнаков(с,к,с,к+1,рисунок)
    КОН
  КОН
КОН РисоватьПозицию;

(*----------------------------------------------------------------------------*)
ЗАДАЧА НачатьЗаново;                     (* Цель:  подготовиться к новой игре *)
УКАЗ
  Игра.НачатьЗаново;
  Записка.Изменить(запискаД,"");
  РисоватьПозицию
КОН НачатьЗаново;

(*----------------------------------------------------------------------------*)
ЗАДАЧА МышкаВКлетку(x,y:ЦЕЛ);
(*
 * Цель:  сообразить, что делать, если человек загнал мышку в эту клетку
 * До:    <x,y> - координаты клетки
 *)
ПЕР
  n:ЦЕЛ; (* номер клетки в позиции *)
УКАЗ
  ЕСЛИ
       (x < 0) ИЛИ (x > 2) ИЛИ (y < 0) ИЛИ (y > 2)
  ТО
    Записка.Изменить(запискаД,"мимо");
    ВОЗВРАТ
  КОН;
  ЕСЛИ
       Игра.Окончена()
  ТО  
    ВОЗВРАТ
  КОН;
  n:=y*3+x;
  ЕСЛИ
       Игра.позиция[n] # " "
  ТО
    Записка.Изменить(запискаД,"занято");
    ВОЗВРАТ
  КОН;
       Игра.Ход(n);
  ЕСЛИ
       Игра.Окончена()
  ТО  
    Записка.Изменить(запискаД,"Конец!")
  ИНАЧЕ
    Записка.Изменить(запискаД,"");
  КОН;
  РисоватьПозицию 
КОН МышкаВКлетку;

(*----------------------------------------------------------------------------*)
ЗАДАЧА Приём(   поле :Поле.Доступ;
             посылка+:Ввод.нПосылка);
(*
 * получить и обработать управляющие послания
 *)
УКАЗ
  ДЛЯ
       посылка
  ВИДА
  | Ввод.нОтКлавиш:
      ЕСЛИ
           посылка.упрАльт И (посылка.код = 58H) (* Alt+'X' *)
         ИЛИ
          (посылка.код = 1BH)                    (* Esc     *)
      ТО               
        поле.состояние:=діяВыход;
        посылка.код:=0
      КОН
  | Ввод.нОтМышки:
      ЕСЛИ
           (посылка.события = {})
          И
           (посылка.кнопки # {})
      ТО                                               (* нажали кнопку мышки *)
        МышкаВКлетку((посылка.к-1) ДЕЛИТЬ 2,посылка.с-1)
      КОН
  | Кнопка.нПосылка:
      ВЫБРАТЬ
              посылка.кнопкаД.действие
      ИЗ
      | діяЗаново: НачатьЗаново
      | діяВыход:  поле.состояние:=діяВыход
      КОН
  ИНАЧЕ
  КОН
КОН Приём;

(*----------------------------------------------------------------------------*)
ЗАДАЧА СоздатьПоле():Поле.Доступ;
                              (* создаёт рабочее поле экрана с кнопочным меню *)
ПЕР
      полеД:    Поле.Доступ;                      (* рабочее поле экрана *)
  подложкаД:Подложка.Доступ;                      (* подложка поля       *)

  кнопВыход,
  кнопЗаново:Кнопка.Доступ;                       (* экранные кнопки       *)
УКАЗ
                                                              (* создаём поле *)
  полеД:=Поле.Создать(0,0,5,19,ПУСТО,ОТКЛ,Приём);
                                                            (* создаём наделы *)
  подложкаД:=Подложка.Создать(0,0,0,0,"");
   запискаД:= Записка.Создать(1,8,1,10,""); 

  кнопЗаново:=Кнопка.Создать(2,8,"[ ~Заново ]",діяЗаново,ВКЛ); 
  кнопВыход :=Кнопка.Создать(3,8,"[ ~Выход  ]",діяВыход,ВКЛ); 
                    (* добавляем наделы в порядке отрисовки и получения ввода *)
  Поле.ДобавитьНадел(полеД,подложкаД);
  Поле.ДобавитьНадел(полеД,запискаД);
  Поле.ДобавитьНадел(полеД,кнопЗаново);
  Поле.ДобавитьНадел(полеД,кнопВыход);
  ВОЗВРАТ полеД
КОН СоздатьПоле;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Поехали;
ПЕР
  полеД:Поле.Доступ;
УКАЗ
  Окно.Графическое("Крестики-нолики","Lucida Console",24,ПУСТО);
(*
  Окно.Текстовое(ПУСТО);
*)
  полеД:=СоздатьПоле();
  Поле.ОкноНаВсёПоле(полеД);
  Поле.Рисовать(полеД);

  Окно.Показать;
  НачатьЗаново;

  ПОВТОРЯТЬ
    Поле.Проверить(полеД)
  ДО полеД.состояние # Поле.состРабота

КОН Поехали;

(*-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-*)
УКАЗ
  Поехали
КОН КрНолики.
