unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormPaint(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

const
  cols = 10;
  rows = 10;
  size = 40;

var
  Form1: TForm1;
  walls: array [0..cols, 0..rows] of boolean;
  vizited: array [0..cols, 0..rows] of boolean;
  px, py: integer;

implementation

{$R *.lfm}

function Go(x, y, dx, dy: integer): boolean;
begin
  Result := false;
  if (x>=0) and (y>=0) and (x<rows) and (y<cols) and (not walls[x, y]) and (not vizited[x, y]) then begin
    vizited[x, y] := true;

    px := x; py := y;
    Form1.Refresh;
    Application.ProcessMessages;
    Sleep(100);

    if (x=dx) and (y=dy) then begin
      Result := true;
    end else begin
      if Go(x-1, y, dx, dy) then Result := true else
      if Go(x, y-1, dx, dy) then Result := true else
      if Go(x+1, y, dx, dy) then Result := true else
      if Go(x, y+1, dx, dy) then Result := true;
    end;

    if not Result then begin
      px := x; py := y;
      Form1.Refresh;
      Application.ProcessMessages;
      Sleep(100);
    end;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  x, y: integer;
begin
  Randomize;
  for x := 0 to cols-1 do begin
    for y := 0 to rows-1 do begin
      if Random > 0.5 then begin
        walls[x, y] := true;
      end else begin
        walls[x, y] := false;
        px := x;
        py := y;
      end;
    end;
  end;
end;

procedure TForm1.FormPaint(Sender: TObject);
var
  x, y: integer;
begin
  for x := 0 to cols-1 do begin
    for y := 0 to rows-1 do begin
      if walls[x, y] then begin
        Canvas.Brush.Color := clBlack;
      end else begin
        Canvas.Brush.Color := clWhite;
      end;
      Canvas.FillRect(Rect(x*size, y*size, (x+1)*size, (y+1)*size));
    end;
  end;

  Canvas.Brush.Color := clRed;
  Canvas.Ellipse(px*size, py*size, (px+1)*size, (py+1)*size);
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  dx, dy, vx, vy: integer;
begin
  dx := x div size;
  dy := y div size;
  if (dx>=0) and (dy>=0) and (dx<rows) and (dy<cols) then begin
    if Button = mbLeft then begin
      walls[dx, dy] := not walls[dx, dy];
      Refresh;
    end;
    if Button = mbRight then begin
      for vx := 0 to cols-1 do begin
        for vy := 0 to rows-1 do begin
          vizited[vx, vy] := false;
        end;
      end;
      if not Go(px, py, dx, dy) then ShowMessage('Path not found');
      Refresh;
    end;
  end;
end;

end.

