unit _16Unit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Grids, ExtCtrls, StdCtrls;

const parametr=true;
type
  TForm1 = class(TForm)
    casovac: TTimer;
    Label1: TLabel;
    Button1: TButton;
    OpenDialog1: TOpenDialog;
    procedure FormCreate(Sender: TObject);
    procedure klik(Sender: TObject);
    procedure casovacTimer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure ReadIt;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  obr:array [1..16] of timage;
  h,pole:array [1..4,1..4] of byte;
  filename:string;

implementation

{$R *.DFM}
{$R obr.res}

function MoveIt(var x,y:byte):boolean;   //this function moves the patches and returns posibility or imposibility of move
begin
if (x>1)and(pole[x-1,y]=16) then
  begin
  obr[pole[x,y]].left:=obr[pole[x,y]].left-51;
  dec(x);
  obr[pole[x,y]].left:=obr[pole[x,y]].left+51;
  pole[x,y]:=pole[x+1,y];
  pole[x+1,y]:=16;
  moveit:=true;
  end
else
if (y>1)and(pole[x,y-1]=16) then
  begin
  obr[pole[x,y]].top:=obr[pole[x,y]].top-51;
  dec(y);
  obr[pole[x,y]].top:=obr[pole[x,y]].top+51;
  pole[x,y]:=pole[x,y+1];
  pole[x,y+1]:=16;
  moveit:=true;
  end
else
if (x<4)and(pole[x+1,y]=16) then
  begin
  obr[pole[x,y]].left:=obr[pole[x,y]].left+51;
  inc(x);
  obr[pole[x,y]].left:=obr[pole[x,y]].left-51;
  pole[x,y]:=pole[x-1,y];
  pole[x-1,y]:=16;
  moveit:=true;
  end
else
if (y<4)and(pole[x,y+1]=16) then
  begin
  obr[pole[x,y]].top:=obr[pole[x,y]].top+51;
  inc(y);
  obr[pole[x,y]].top:=obr[pole[x,y]].top-51;
  pole[x,y]:=pole[x,y-1];
  pole[x,y-1]:=16;
  moveit:=true;
  end
else moveit:=false;
end;

procedure tform1.ReadIt;
var x,y,z:byte;
    f:textfile;
    s,pom:string;
begin
assignfile(f,filename);
reset(f);
{for y:=1 to 4 do    //this is better posibility of reading from source file, but that isn't so good in Delphi debugger (it throws errors, but without Delphi it runs well
  for x:=1 to 4 do
    try
      read(f,pole[x,y]);
      except on EInOutError do pole[x,y]:=16;
    end;}
for y:=1 to 4 do     //now it is reading from file
  begin
  z:=1;
  readln(f,s);
  for x:=1 to 4 do
    begin
    pom:='';
    while s[z]<>' ' do
      begin
      pom:=pom+s[z];
      inc(z);
      end;
    if pom<>'X' then pole[x,y]:=strtoint(pom)
                else pole[x,y]:=16;
    while s[z]=' ' do inc(z);
    with obr[pole[x,y]] do
      begin
      left:=150+((x-1)*51);
      top:=60+((y-1)*51);
      onclick:=klik;
      parent:=form1;
      end;
    h[x,y]:=abs((pole[x,y]-trunc((pole[x,y]-0.1)/4)*4)-x)+abs(trunc((pole[x,y]-0.1)/4+1-y)); {here I record distance of number from his true position}
    end;
  end;
closefile(f);
end;

procedure TForm1.FormCreate(Sender: TObject);
var x,y:byte;  //it create images of patches (numbers) from resource file and call procedure ReadIt
begin
if parametr=true then casovac.enabled:=true;
for x:=1 to 16 do
  begin
  obr[x]:=timage.create(form1);
  with obr[x] do
    begin
    autosize:=true;
    tag:=x;
    picture.bitmap.handle:=loadbitmap(hinstance,pchar('o'+inttostr(x)));
    end;
  end;
if paramcount>0 then filename:=paramstr(paramcount)
   else filename:='courtney.pos';
ReadIt;
end;

procedure TForm1.klik(Sender: TObject);
var x,y:byte;  //by this procedure you can move the patches
begin
{click on some part of '15'}
x:=trunc(((sender as timage).left-150)/51)+1;
y:=trunc(((sender as timage).top-60)/51)+1;
moveit(x,y);
end;

procedure TForm1.casovacTimer(Sender: TObject); //this procedure find shortest way of some patch
begin
//this procedure should to simulate moving of patches by way, which though procedure cesta
end;

procedure cesta;  //I am sorry, but main procedure is not complete. But thought of this procedure is find way for moving patch, which least move other patches to wrong directiuon from their true position. There should be two graph algorithms in themselves. First shold find the best way of patch and the second should to find best way of X. First graph
                  //algorithm use the second graph algorithm in hisself 
type souradnice=record
  x:byte;
  y:byte;
  end;
var p:array [1..16] of shortint;
    pom,pom2:array [1..4,1..4] of byte;
    x,y:byte;
    start,cil:souradnice;
  function nejx(start,cil:souradnice):shortint; //this function return length of way of empty patch from start to cil position.
                                                //this way is that way, which bring least moving of patches to their more distant positions from their less distant positions.
    var p:array [1..16] of shortint;
        k:array [1..4,1..4] of integer;
        pom:souradnice;
        x,y:byte;
    begin
    for x:=1 to 4 do
      for y:=1 to 4 do
        k[x,y]:=maxint;
    k[start.x,start.y]:=0;
    while (pom.x<>cil.x)or(pom.y<>cil.y) do
      begin
      for y:=1 to 4 do
        for x:=1 to 4 do
          begin

          end;
      end;
    end;
begin
start.x:=2;
start.y:=4;
cil.x:=1;
cil.y:=1;
for y:=1 to 4 do //copying important arrays to new arrays, which I will change at the moment.
  for x:=1 to 4 do
    begin
    pom[x,y]:=pole[x,y];
    pom2[x,y]:=h[x,y];
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);  //this open other file with placement of patches
begin
if opendialog1.execute then
  begin
  filename:=opendialog1.filename;
  ReadIt;
  end;
end;

end.
