unit Unit4;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, Grids, StdCtrls, XPMan;

type
  TSG = class(TForm)
    ForCreate: TTimer;
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormActivate(Sender: TObject);
    procedure Win;
    procedure CreateUnits;
  private
    { Private declarations }
  public
       NotCreate: boolean;
       EnmCnt: byte;


  end;

var
  SG : TSG;
  food,i,j,y,IslNum,a: integer;
  Enemy : array [1..3] of TImage;
  PlayerOK : TImage;

  Isl: array [1..16] of TImage;
  Finish: array [1..2] of TImage;
  hour,minutes,day,storona : Byte;
  coor : array [0..6,0..9,1..2] of Integer;
  IslImgNum : string;
  right,FirstStart, FirstStart2, hod, GameEnd, NG, DW : Boolean;
  AntiCheat: integer; //переменная отвечает за результат
  AllRoundScore: array [0..255] of Byte;
  RoundScore: array [0..2] of variant;
  life: variant;     // зашифрованное рандомом числo
  delife1: Byte;     // Ключ 1, знакоопределяющий
  delife2: Variant;  // Ключ 2 ценлочисленный, рандомный
  RoundScr: Byte;



  implementation

uses Unit1,Unit2,Unit3,Unit5, Menu, settings, GetResultat;

{$R *.dfm}

procedure New_Game;
begin
  delife1:= Random(4);
  delife2:= Random(Random(Random(429731)));
 case delife1 of
  0: life:= (delife2 + 3 + Random);
  1: life:= (delife2 - 3 + Random);
  2: life:= (delife2 * 3) div 1;
  3: life:= (delife2 / 3) div 1;
 end;
end;

procedure Go_To; //процедура для защиты от попыток читерства.
 begin

 end;

 procedure TSG.FormCreate(Sender: TObject);
begin
 NG:= True;
 FirstStart:=false;
 FirstStart2:=false;
 DoubleBuffered := true;
 GameEnd := false;
 DW:= false;
 NotCreate:= false;
 EnmCnt:= 1;
 Show;
end;


procedure TSG.CreateUnits;
var     sle, ste, ft, fl : integer;   //sle-Left|ste-Top|IslNum—кол-во островов|
                ShipCheck: Byte;  //Наслоен ли корабль на остров
             i, j, y, old: Byte;
               i2, j2, y2: Byte;
begin
Randomize; sle:=0; ste:=0;

  if FirstStart2 = True then
   begin
    For i:=1 to IslNum do
        FreeAndNil(Isl[i]);
    For i:=1 to  EnmCnt do
        FreeAndNil(Enemy[i]);
    For i:=1 to 2 do
        FreeAndNil(Finish[i]);
    FreeAndNil(PlayerOK);
   end
  else

   begin
     old:=1;
   if NG = True then
      begin
       New_Game;
       NG:= False;
      end;
   end;

 RoundScore[0]:=0.0028;
 storona:=random(4);                  //Определяем основную сторону спавна.
   case storona of                    //0-вверхy,1-cвлево,2-cправо,3-cнизy.
    0: begin ste :=6; sle := 879;              //вверх
              ft := 6;  fl := 6;        end;

    1: begin ste := 6; sle := 6;            //влево
              ft := 588;  fl := 6;        end;

    3: begin ste := 588; sle := 6;          //вправо
              ft := 588;  fl := 879;           end;

    2: begin ste := 588; sle := 879;      //вниз
              ft := 6;  fl := 879;
       end;
    end;
 for i:=1 to 2 do
   begin
  Finish[i] := TImage.Create(SG);
  Finish[i].Parent := SG;
  Finish[i].Stretch:= True;
  Finish[i].Picture.LoadFromFile('src\Finish.jpg');
   if i=1 then
   begin
     Finish[i].Top :=ste;
     Finish[i].Left :=sle;
     end
   else
   begin
     Finish[i].Top :=ft;
     Finish[i].Left :=fl;
     end;
  Finish[i].Height := 94;
  Finish[i].Width := 94;
    end;

 for i:=1 to EnmCnt do
  begin
  Enemy[i] := TImage.Create(SG);
  Enemy[i].Picture.LoadFromFile('src\enemy.jpg');
  Enemy[i].Parent := SG;
  old:=i;
 Repeat
ShipCheck := 0;
 case storona of
0: begin ste := random(2); sle := random(10); end;     //вверх
1: begin ste := random(7); sle := random(2);  end;    //влево
2: begin ste := random(7); sle := Random(2)+7;  end; //вправо
3: begin ste := Random(2)+5; sle := random(10); end;//вниз
 end;
  Enemy[i].Top := coor[ste,sle,1];
  Enemy[i].Left := coor[ste,sle,2];
  for j:=1 to i do
  begin                                           //Проверяем, не появился ли кораблль в
      if ((Enemy[i].Top)=(Enemy[j].Top)) and     //том же месте, где находится
         ((Enemy[i].Left)=(Enemy[j].Left)) then //   другой корабль.
        ShipCheck:=ShipCheck+1;
  end;
  until(ShipCheck=1);

   Enemy[i].Height := 95;
   Enemy[i].Width := 95;
   end;

  PlayerOK := TImage.Create(SG);
  PlayerOK.Parent := SG;
  PlayerOK.Picture.LoadFromFile('src\pir-ship.jpg');
  case storona of
0: begin ste := 6; sle := Random(9); end;       //вниз
1: begin ste := Random(6); sle := 9; end;       //вправо
2: begin ste := Random(6); sle := random(2); end; //влево
3: begin ste := 0; sle := Random(9); end;      //вверх
   end;
  PlayerOK.Top :=coor[ste,sle,1];
  PlayerOK.Left :=coor[ste,sle,2];
  PlayerOK.Height := 95;
  PlayerOK.Width := 95;
//SG.Refresh;
//SG.Repaint;

 IslNum:= Random(3);   // После тестов исправить надо на IslNum:= random(4);
case IslNum of    // После тестов исправить
 0:IslNum:=16;    // После тестов исправить
 1:IslNum:=13;    // После тестов исправить
 2:IslNum:=10;     // После тестов исправить
end;
   for i:=1 to IslNum do
   begin
  IslImgNum:=(IntToStr(Random(6)+1))+'.jpg';
  Isl[i] := TImage.Create(SG);
  Isl[i].Parent := SG;
  Isl[i].Picture.LoadFromFile('src\'+IslImgNum);
  Isl[i].Height := 94;
  Isl[i].Width := 94;

  begin
    repeat
    right:=false;
     Isl[i].Top :=coor[Random(7),Random(10),1];
     Isl[i].Left :=coor[Random(7),Random(10),2];
     For j:=1 to EnmCnt do
     begin
      For y:=1 to 2 do
      begin
        if ((Isl[i].Top)=(Enemy[j].Top)) and ((Isl[i].Left)=(Enemy[j].Left)) or
           ((Isl[i].Top)=(PlayerOK.Top)) and ((Isl[i].Left)=(PlayerOK.Left))   or
           ((Isl[i].Top)=(Finish[y].Top)) and ((Isl[i].Left)=(Finish[y].Left)) or
           ((Isl[i].Top-99)=(Finish[y].Top)) and ((Isl[i].Left)=(Finish[y].Left)) or
           ((Isl[i].Top+99)=(Finish[y].Top)) and ((Isl[i].Left)=(Finish[y].Left)) or
           ((Isl[i].Top)=(Finish[y].Top)) and ((Isl[i].Left+99)=(Finish[y].Left)) or
           ((Isl[i].Top)=(Finish[y].Top)) and ((Isl[i].Left-99)=(Finish[y].Left)) or
           ((Isl[i].Top-99)=(PlayerOK.Top)) and ((Isl[i].Left)=(PlayerOK.Left)) or
           ((Isl[i].Top+99)=(PlayerOK.Top)) and ((Isl[i].Left)=(PlayerOK.Left)) or
           ((Isl[i].Top)=(PlayerOK.Top)) and ((Isl[i].Left+99)=(PlayerOK.Left)) or
           ((Isl[i].Top)=(PlayerOK.Top)) and ((Isl[i].Left-99)=(PlayerOK.Left))
       then right:=true;

 {case storona of
1,2: begin                    //вправо
       j2:= random(6)+3;
       y2:= random(7);         //влево
     end;

0,3: begin
       j2:= random(6)+3;
       y2:= random(5)+4;
     end; //влево

   end;


       For i:= 1 do 9 do
        if coor[y,i
      // if ((Isl[i].Top)=(Enemy[j].Top)) and ((Isl[i].Left)=(Enemy[j].Left)) or
       }
     end;
     end;
    until(right=false);

    end;
    end;
FirstStart2 := true;
end;

procedure TSG.Win;  //Процедура, вызываемая при достижение финальной точки
 begin
   Ended.Title.Caption :='Вы смогли!!! Вы победили!';

   if EnmCnt = 1 then
     Ended.lblInf.Caption:='Признайтесь, это было не сложно ;)';
   if EnmCnt = 2 then
     Ended.lblInf.Caption:='Такая победа — большое достижение! Поздравляю!';
   if EnmCnt = 3 then
     Ended.lblInf.Caption:='НЕВЕРОЯТНО!!! Лишь еденицы из тысяч способны на это!';

    Ended.Lets.Caption:='Я смогу повторить!';
    Ended.Lets.Font.Size:= 13;

    Ended.ShowModal;
 end;

procedure Defeat; //Процедура вызываемая при проигрыше.
 begin
    If ((Application.MessageBox('Вы проиграли! Желаете начать заново?',
        'Вы проиграли :(', MB_YESNO)) = 7) then SG.Close
                            else SG.CreateUnits();
 //   TopMenu.lblFood.Caption:= IntToStr(  );
 end;



procedure TSG.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ShowMessage('Спасибо за игру! Надеюсь, вам что-нибудь понравилось!');
  GG.Close;
  shadow.Close;
  background.Close;
  TopMenu.Close;
  setting.Close;
  MainMenu.Close;
end;

procedure TSG.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
 var bt,bl: integer;
     l,t,r,d,kat1,kat2 : Variant; //Переменные для ИИ
     i, j, y : Byte;
     Brk : Boolean;
begin
 bt := PlayerOK.Top;
 bl := PlayerOK.Left;

  if Key=37 then // <-
    begin
     PlayerOK.Left := PlayerOK.Left - 97;
    end;

  if Key=38 then // ^
     begin
      PlayerOK.Top := PlayerOK.Top - 97;
     end;

  if Key=39 then // ->
     begin
       PlayerOK.Left := PlayerOK.Left + 97;
     end;

  if Key=40  then //спускаемся вниз
     begin
      PlayerOK.Top := PlayerOK.Top + 97
     end;
if (PlayerOK.Top<0) or        // Если игрок
   (PlayerOK.Left<0) or       //   пытается выйти
   (PlayerOK.Top>679) or      //     за пределы
   (PlayerOK.Left>970) then   //       игрового поля,
begin
 PlayerOK.Left := bl;  //То возвращаем игрока в
 PlayerOK.Top := bt;  //  допустимую зону перемещения
end
  else
   begin
    for i:=1 to IslNum do
    begin                                         //Также проверяем не идем ли
      if (Isl[i].Top=PlayerOK.Top) and           //мы в остров,
         (Isl[i].Left=PlayerOK.Left) then       //если идём,
      begin
       PlayerOK.Left := bl;  //То возвращаем игрока в
       PlayerOK.Top := bt;  //предыдущий слот
      end;
    end;
   end;
  for y:= 1 to 2 do
    begin
     if (PlayerOK.Top = Finish[y].Top) and (PlayerOK.Left = Finish[y].Left) then
          Win;
    end;
{
 Далее рассказываем флоту противнику о том как ему себя вести,
   перед этим определив катеты расстояния, далее находим
   "гипотенузу расстояния", т.е. исходя из катета высоты
   и катеты широты определяем расстояние между объектами
}
if (PlayerOK.Left<>bl) or (PlayerOK.Top<>bt) then          //Но сначала проверяем стрелочка ли нажата
begin
  RoundScore[0]:=RoundScore[0]-0.0001;
  TopMenu.lblFood.Caption := IntToStr(RoundScore[0] * 100000 div 2);
 if RoundScore[0]<0 then
  begin
   if 6 = MessageBox(Handle,'Капитан! На корабле закончилась еда, команда бунтует и отказывается плыть, Теперь мы будем проходить вдвое меньшее расстояние в день! Может быть сдадимся?',
                      'Закончилась еда', 4)
      then
        Defeat
      else food:=1;
  end;
if (food mod 2)=0 then
  begin
    food:= food - 1;
  end
else
  begin
   For i:=1 to EnmCnt do
 begin
  for j:=1 to 2 do
    begin
     kat1 :=  StrToFloat(inttostr(Enemy[i].Top))-PlayerOK.Top;       //Для
     kat2 :=  StrToFloat(inttostr(Enemy[i].Left))-97-PlayerOK.Left; // хода
     l := Sqrt( kat1*kat1 + kat2*kat2 );                           //  влево
  for y:=1 to IslNum do                                // Если противник хочет
  begin                                               //  переместиться туда
  if ((Enemy[i].Top)=Isl[y].Top)  and                //   гда находится остров
     ((Enemy[i].Left-97)=Isl[y].Left) or            //    или за игровое поле
     (Enemy[i].Top<0) or (Enemy[i].Left<0) or
     (Enemy[i].Top>679) or (Enemy[i].Left>970)
      then
      begin
        l:= 214748;    // делаем ход не рентабильным
      end;
  end;

     kat1 :=  StrToFloat(inttostr(Enemy[i].Top))-PlayerOK.Top;       //Для
     kat2 :=  StrToFloat(inttostr(Enemy[i].Left))+97-PlayerOK.Left; // хода
     r := Sqrt( kat1*kat1 + kat2*kat2 );                           //  вправо
  for y:=1 to IslNum do                                // Если противник хочет
  begin                                               //  переместиться туда
  if ((Enemy[i].Top)=Isl[y].Top)  and                //   гда находится остров
     ((Enemy[i].Left+97)=Isl[y].Left) or            //    или за игровое поле
     (Enemy[i].Top<0) or (Enemy[i].Left<0) or
     (Enemy[i].Top>679) or (Enemy[i].Left>970)
      then
       begin
        r:= 214748;    // делаем ход не рентабильным
       end;
  end;

     kat1 :=  StrToFloat(inttostr(Enemy[i].Top))-97-PlayerOK.Top;  //Для
     kat2 :=  StrToFloat(inttostr(Enemy[i].Left))-PlayerOK.Left;  // хода
     t := Sqrt( kat1*kat1 + kat2*kat2 );                         //  вверх
  for y:=1 to IslNum do                                // Если противник хочет
  begin                                               //  переместиться туда
  if ((Enemy[i].Top-97)=Isl[y].Top)  and             //   гда находится остров
     ((Enemy[i].Left)=Isl[y].Left)  or              //    или за игровое поле
     (Enemy[i].Top<0) or (Enemy[i].Left<0) or
     (Enemy[i].Top>679) or (Enemy[i].Left>970)
      then
       begin
        t:= 214748;         // делаем ход не рентабильным
       end;
  end;

     kat1 :=  StrToFloat(inttostr(Enemy[i].Top))+97-PlayerOK.Top;  //Для
     kat2 :=  StrToFloat(inttostr(Enemy[i].Left))-PlayerOK.Left;  // хода
     d := Sqrt( kat1*kat1 + kat2*kat2 );                         //  вниз
  for y:=1 to IslNum do                                // Если противник хочет
  begin                                               //  переместиться туда
  if ((Enemy[i].Top+97)=Isl[y].Top)  and             //   гда находится остров
     ((Enemy[i].Left)=Isl[y].Left)   or             //    или за игровое поле
     (Enemy[i].Top<0) or (Enemy[i].Left<0) or
     (Enemy[i].Top>679) or (Enemy[i].Left>970)
    then
     begin
        d:= 214748;    // делаем ход не рентабильным
     end;
  end;

 // Найдя расстояние, необходимо определить наименьшее
if (l<r) and (l<t) and (l<d) then
  begin
   Enemy[i].Left := Enemy[i].Left-97;
{
Кстати, надо не забыть добавить защиту на координату игрока
}  end
   else begin if (r<t) and (r<d) then
              begin
               Enemy[i].Left := Enemy[i].Left+97;
              end
              else begin if (t<d) then
                         begin
                          Enemy[i].Top := Enemy[i].Top-97;
                         end
                         else begin Enemy[i].Top := Enemy[i].Top+97;
                              end;
              end;
        end;
if (Enemy[i].Top=PlayerOK.Top) and (Enemy[i].Left=PlayerOK.Left) then
    begin
       Defeat;
       GameEnd := true;
       Break;
    end;
end;
  if GameEnd = true then
    begin
       GameEnd := false;
        Break;
    end;
end;
food:= food - 1;
end;
//food:=food+10; // Если положение игрока изменилось, тогда отнимаем пищу!!! ^_^
end;
end;

procedure TSG.FormShow(Sender: TObject);
var a: integer;
    i, j: Byte;
begin
Randomize;
{ Начало основной части }
SG.Width := 980;
SG.Height := 690;
TransparentColorValue := $00123456;
TransparentColor := True;
 For i:= 0 to 6 do
 begin
   For j:=0 to 9 do      // Данная переменная введена во многом для защиты
   begin
  a:=1;                //  приложения. Первое значение массива определяет
  coor[i,j,a]:=6+i*97;   //   номер клетки от верхнего края, второе - от левого
  a:=2;
  coor[i,j,a]:=6+j*97;
   end;                  //    края. Третья переменная говорит о координате клет.
   end;                  //     if a=1, то Top, else Left.
{ Конец основной части }

if NotCreate=False then
  begin
     CreateUnits; //Cоздания объектов
     NotCreate:= True;
  end;


SetActiveWindow(Shadow.Handle);
SetActiveWindow(GG.Handle);
SetActiveWindow(SG.Handle);
end;

procedure TSG.FormActivate(Sender: TObject);
begin
 background.AlphaBlendValue := 255;
    TopMenu.AlphaBlendValue := 255;
     shadow.AlphaBlendValue := 150;
   MainMenu.AlphaBlendValue := 255;
            AlphaBlendValue := 255;
         GG.AlphaBlendValue := 255;
end;

end.
