一个经典Delphi算法(老鼠走迷宫问题)

 unit Unit1;

interface

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

type   TForm1 = class(TForm)     Edit1: TEdit;     btn_3: TButton;     Edit2: TEdit;     Edit3: TEdit;     Edit4: TEdit;     Edit5: TEdit;     Label1: TLabel;     Label2: TLabel;     Label3: TLabel;     Label4: TLabel;     btn_1: TButton;     pnl1: TPanel;     pnl2: TPanel;     pnl3: TPanel;     procedure btn_3Click(Sender: TObject);     procedure btn_1Click(Sender: TObject);     procedure FormCreate(Sender: TObject);   private     x,y,k,x1,y1,x2,y2     : integer;     A   : array [1..4, 1..4] of Integer;     B   : array [1..4, 1..4] of Integer;     C   : array [1..4, 1..4] of Integer;     E   : array [1..16]       of TEdit;     F   : array [1..4, 1..4] of Boolean;     function Walk(nx,ny,ni,nj:Integer; xNy:Boolean; WalkStr:string):string;     function FangX(nx,ny,ni:integer):integer;     { Private declarations }   public     { Public declarations }   end;

var   Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.FangX(nx,ny,ni:integer):integer; begin   if      ni = 1 then    // 右     if (A[nx,ny+1]=0) or (A[nx,ny+1]=A[x2,y2]) then       Result:= 0     else       Result:= 1   else if ni = 2 then   // 下     if (A[nx+1,ny]=0) or (A[nx+1,ny]=A[x2,y2])  then       Result:= 0     else       Result:= 1   else if ni = 3 then   // 左     if (A[nx,ny-1]=0) or (A[nx,ny-1]=A[x2,y2])  then       Result:= 0     else       Result:= 1   else if ni = 4 then   // 上     if (A[nx-1,ny]=0) or (A[nx-1,ny]=A[x2,y2])  then       Result:= 0     else       Result:= 1   else   Result:= 0; end;

//传入------- 1, 1, 1, 3,           true         'Begin->11' function TForm1.Walk(nx,ny,ni,nj: Integer; xNy:Boolean; WalkStr:string):string; //var i: integer; begin   //判断是否到了出口   if ((WalkStr='11')and(C[x1,y1]=5))or(F[1,1]=False) then begin WalkStr:=''; Showmessage('不通!'); exit; end else   if (WalkStr<>(IntToStr(x2)+IntToStr(y2))) then begin     if (FangX(nx,ny,1)=0) and(C[nx,ny+1]<>5) and(C[nx,ny+1]=0) and(ny<y) then begin       B[nx,ny]:=nj; C[nx,ny]:=1; F[nx,ny]:=True; Result:=WalkStr+'->'+Walk(nx,ny+1,B[nx,ny],C[nx,ny],F[nx,ny],(IntToStr(nx)+IntToStr(ny+1)));     end else     if (FangX(nx,ny,2)=0) and(C[nx+1,ny]<>5) and(C[nx+1,ny]=0) and(nx<x) then begin       B[nx,ny]:=nj; C[nx,ny]:=2; F[nx,ny]:=True; Result:=WalkStr+'->'+Walk(nx+1,ny,B[nx,ny],C[nx,ny],F[nx,ny],(IntToStr(nx+1)+IntToStr(ny)));     end else     if (FangX(nx,ny,3)=0) and(C[nx,ny-1]<>5) and(C[nx,ny-1]=0) and(ny>1) then begin       B[nx,ny]:=nj; C[nx,ny]:=3; F[nx,ny]:=True; Result:=WalkStr+'->'+Walk(nx,ny-1,B[nx,ny],C[nx,ny],F[nx,ny],(IntToStr(nx)+IntToStr(ny-1)));     end else     if (FangX(nx,ny,4)=0) and(C[nx-1,ny]<>5) and(C[nx-1,ny]=0) and(nx>1) then begin       B[nx,ny]:=nj; C[nx,ny]:=4; F[nx,ny]:=True; Result:=WalkStr+'->'+Walk(nx-1,ny,B[nx,ny],C[nx,ny],F[nx,ny],(IntToStr(nx-1)+IntToStr(ny)));     end else        begin C[nx,ny]:=5; B[nx,ny]:=5; F[nx,ny]:=False;        Case nj of         3: begin Result:=WalkStr+'->'+Walk(nx,ny+1,nj,B[nx,ny+1],F[nx,ny+1],(IntToStr(nx)+IntToStr(ny+1))); end;         4: begin Result:=WalkStr+'->'+Walk(nx+1,ny,nj,B[nx+1,ny],F[nx+1,ny],(IntToStr(nx+1)+IntToStr(ny))); end;         1: begin Result:=WalkStr+'->'+Walk(nx,ny-1,nj,B[nx,ny-1],F[nx,ny-1],(IntToStr(nx)+IntToStr(ny-1))); end;         2: begin Result:=WalkStr+'->'+Walk(nx-1,ny,nj,B[nx-1,ny],F[nx-1,ny],(IntToStr(nx-1)+IntToStr(ny))); end;        end;     end;   end else Result := inttostr(x)+inttostr(y)+'->End'; end;

procedure TForm1.btn_3Click(Sender: TObject); begin //数组中0表示通路1表示不通   x1:= 1; //strtoint(edit1.Text);   y1:= 1; //strtoint(edit2.Text);  //入口坐标   x2:= x; //strtoint(edit3.Text);   y2:= y; //strtoint(edit4.Text);  //出口坐标   //判断(行列、辅助、对焦线)是否有断裂情况加速程序运行   Edit5.Text := Walk(x1,y1,1,1,True,'Begin->11') ;   if Edit5.Text = '' then Showmessage('不通!') end;

procedure TForm1.btn_1Click(Sender: TObject); var   i,j : Integer ; begin   Edit5.Text := '';   if (k<>1) then begin     for i := 1 to k-1 do     E[i].Free;   end;   k := 1;   x := 4;   y := 4;   for i := 1 to x do   for j := 1 to y do begin     A[i, j] := Random(2);     F[i, j] := True;     B[i, j] := 0;     C[i, j] := 0;     begin       E[k] := TEdit.Create(Self);       E[k].Parent:= pnl2;       E[k].Height:= 20;       E[k].Width := 20;       E[k].Top   := i*28-20;       E[k].Left  := j*28-20;       E[k].Name  := 'k' + IntToStr(k);       E[k].Text  := IntToStr(A[i,j]);       k:=k+1;     end;     Edit5.Text := Edit5.Text + IntToStr(A[i,j]);   end;   A[1, 1] := 0;   A[x, y] := 0;   E[1].Text   :='0';   E[k-1].Text :='0'; end;

procedure TForm1.FormCreate(Sender: TObject); begin   k:=1; end;

end.

作者写点废话哈: 1、先是看到手机上有个小游戏,填字游戏,横竖相连,像个迷宫 2、就用Delphi 做了个由 panel 数组 组成的迷宫,墙都是方块,丑死了。 3、再查查网上有不少迷宫样式,其中有的迷宫是单墙的,而且任意两处都是想通的。 4、再做了个四面墙都可打通的迷宫,甚至做了个斜线通道的。 5、觉得三角形迷宫更有挑战性,另外想试试以前学的数据结构指针、链表、树、连通图的知识是不是忘光了, 就做了个三角形迷宫,而且索性做成一个完善的 Delphi 控件,而且有不少属性。。。 6、有几个要解释下:1)迷宫是个连通图,每个正三角形与三个倒三角形相连,每个倒三角形与三个正三角形相连; 2)采用递归,从一个节点开始构造整个连通图;3)查找、遍历连通图时用外部二维数组标识来防止重复; 3)构造迷宫采用的是所谓 随机prim 算法;4)迷宫的宽与三角形边长、列数相互制约,迷宫的高由三角形的高 (正三角形的高通过边长计算的)与行数决定;5)使用指针时最容易丢掉 ^ 这个符号,例如某节点是 Pmm 指针型, 对其属性的引用就不能用 Pmm.Value 而必须用 Pmm^.Value ,机器编译时不会提示错误,但运行时老是出错! 6)绘图通过计算三角形的顶点坐标来构造;7)控件父类是 TGraphicControl ,试了好几种最后它最好, 要覆盖 paint 方法绘图;8)构造类时如 FGridWidth 的内部数据与属性 GridWidth 不要混淆使用, 记住 内部数据赋值,属性引用,属性(Published)是给运行期或者设计面板上别人使用的,内部数据是封装的; 9)发布自定义控件前先准备一个包含 类 一样名称的 ICO 的 DCR 文件,好像只有 Delphi7 里的 Image Editor 可以制作,这个工具包括两个文件 ImageEdit.exe 和 ImageD32.dll 两个文件 7、好像前后陆续花了近两个星期吧,终于基本完善了。该学点其他东西了 -- by chenxz
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值