大侠帮我看看我得扫雷源代码,退出老是有异常(100分)

C

chenmq

Unregistered / Unconfirmed
GUEST, unregistred user!
没词玩好几盘后 玩到一半退出的话会出现异常,einvalid pointer...请问各位到
底是哪里的问题?
谢谢
代码如下:

unit main;

interface

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

type
TForm1 = class(TForm)
ImageList1: TImageList;
Timer1: TTimer;
Button1: TButton;
procedure FormPaint(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure showaround(i:integer;j:integer);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Timer1Timer(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);

private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
BombFlag : Array of Array of Integer ;
CurrentFlag : Array of Array of Integer ;
M,N:integer;
CurrentI , CurrentJ : Integer;
tops:integer=15;
lefts:integer=15;
flag:integer=0;
BombNum:Integer=10;
status:integer=0;//0 is initial 1 is gaming 2 is win
implementation

{$R *.dfm}



procedure TForm1.FormPaint(Sender: TObject);

var i,j:integer;


begin

for i:=0 to M-1 do
begin
for j:=0 to N-1 do
imagelist1.draw(form1.canvas, lefts+i*16, tops+j*16,0);
end;

end;


Procedure BombPosition(BombNum:Integer); //默认雷数为10
var i,j,b:integer;
Begin
form1.Timer1.Enabled:=true;
Randomize;
b:=0 ;
While b<BombNum do
Begin
i:=random(M); //产生两个随机数
j:=random(N);
If (BombFlag[j]<>-1) and ((i<>CurrentI )or(j<>CurrentJ)) then
Begin
BombFlag[j]:=-1;
b:=b+1;
End;
End;

End;

procedure BombSum();

var i,j:integer;

Begin

For i:=0 to M-1 do

Begin

For j:=0 to N-1 do

If BombFlag[j] = -1 then

Begin

If (i-1>=0) and (j-1>=0) and (BombFlag[i-1][j-1]<>-1) then

BombFlag[i-1][j-1]:= BombFlag[i-1][j-1]+1;

If (i-1>=0) and (BombFlag[i-1][j]<>-1) then

BombFlag[i-1][j]:= BombFlag[i-1][j]+1;

If (i-1>=0) and (j+1<=n) and (BombFlag[i-1][j+1]<>-1) then

BombFlag[i-1][j+1]:= BombFlag[i-1][j+1]+1;

If (j-1>=0) and (BombFlag[j-1]<>-1) then

BombFlag[j-1]:= BombFlag[j-1]+1;

If (j+1<=n-1) and (BombFlag[j+1]<>-1) then

BombFlag[j+1]:= BombFlag[j+1]+1;

If (i+1<=m-1) and (j-1>=0) and (BombFlag[i+1][j-1]<>-1) then

BombFlag[i+1][j-1]:= BombFlag[i+1][j-1]+1;

If (i+1<=m-1) and (BombFlag[i+1][j]<>-1) then

BombFlag[i+1][j]:= BombFlag[i+1][j]+1;

If (i+1<=m-1) and (j+1<=n-1) and (BombFlag[i+1][j+1]<>-1)then

BombFlag[i+1][j+1]:= BombFlag[i+1][j+1]+1;

End;
End;

End;

procedure tform1.showaround(i:integer;j:integer);
begin
If CurrentFlag[j]=0 then
begin
CurrentFlag[j]:=3;
If BombFlag[j]=0 then
begin
imagelist1.draw(form1.canvas, lefts+16*i ,tops+16*j,15);
If (i-1>=0) then //进行边界判断
showaround(i-1,j); //递归
If (i-1>=0) and (j-1>=0) then
showaround(i-1,j-1);
If (i-1>=0) and (j+1<=n-1) then //进行边界判断
showaround(i-1,j+1); //递归
If j-1>=0 then
showaround(i,j-1);
If j+1<=n-1 then //进行边界判断
showaround(i,j+1); //递归
If (i+1<=m-1) and (j-1>=0) then
showaround(i+1,j-1);
If I+1<=m-1 then //进行边界判断
showaround(I+1,j); //递归
If (i+1<=m-1) and (j+1<=n) then
showaround(I+1,j+1);


end
else imagelist1.draw(form1.canvas,lefts+16*(i) ,tops+16*(j) ,BombFlag[j]) ;
end;
end;

procedure init();
var i,j:integer;
begin

for i:=0 to M-1 do begin
for j:=0 to N-1 do begin

BombFlag[j]:=0;
currentflag[j]:=0;
end;
end;
end;



procedure TForm1.FormCreate(Sender: TObject);
begin
n:=9;m:=9;
SetLength(BombFlag,M,N);
SetLength(CurrentFlag,M,N);
init;


end;




procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin if status=1 then
if (x>lefts)and(x<lefts+m*16)and(y>tops)and(y<tops+n*16) then begin
CurrentI:=(X-lefts) Div 16;

CurrentJ:=(Y-tops) Div 16;


if button=mbright then begin

case currentFlag[currenti][currentj] of
0:begin currentFlag[currenti][currentj]:=1;
imagelist1.draw(form1.canvas,lefts+16*currenti, tops+16*currentj,9); end;
1:begin currentFlag[currenti][currentj]:=2;
imagelist1.draw(form1.canvas,lefts+16*currenti, tops+16*currentj,0);
imagelist1.draw(form1.canvas,lefts+16*currenti, tops+16*currentj,10); end;
2:begin currentFlag[currenti][currentj]:=0;
imagelist1.draw(form1.canvas,lefts+16*currenti, tops+16*currentj,0); end;
end;

end;

if button=mbleft then
begin
if flag=0 then

begin
BombPosition(bombnum); bombsum; flag:=1;
end ;

if BombFlag[currenti][currentj]=-1 then
begin
showmessage('You failed.try again!');
button1.Enabled:=true;
status:=2;
end ;
if BombFlag[currenti][currentj]<>0 then
begin
imagelist1.draw(form1.canvas, x-((x-lefts)mod 16), y-((y-tops)mod 16),Bombflag[CurrentI][CurrentJ]);
CurrentFlag[currenti][currentj]:=3;
end;
if BombFlag[currenti][currentj]=0 then
begin

showaround(currenti,currentj);
end;

end;
end;

end;

procedure TForm1.Timer1Timer(Sender: TObject);
var i,j,num:integer;
begin
//if wins?
num:=0;
for i:=0 to M-1 do begin
for j:=0 to N-1 do begin
if currentflag[j]=3 then num:=num+1;
end ;
end ;
if num=m*n-bombnum then begin
timer1.Enabled:=false;
for i:=0 to M-1 do begin
for j:=0 to N-1 do begin
if currentflag[j]=0 then imagelist1.draw(form1.canvas,lefts+16*(i) ,tops+16*(j) ,9) ;;
end ;
end ;
showmessage('yeah') ;
status:=2;
button1.Enabled:=true;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if status=2 then
begin
button1.Enabled:=false;
status:=1;
form1.Paint;
init;
flag:=0;
end
else
begin
button1.Enabled:=false;
status:=1;
end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin

timer1.Enabled:=false;
while form1.componentcount>0 do
components[0].Free;

end;

end.

 
最后timer1.Enabled:=false;
while form1.componentcount>0 do
components[0].Free
是我 实在找不出问题,自己加的,但是还没有解决:(
是不是什么没有释放?
 
其他代码太长,没时间看,问题可能出在定时器上
把定时器过程改一下试试,
进入定时器时先禁止,处理完后再允许,
在内部循环中对定时器状态进行判断
这样做主要是为了防止重入
 

Similar threads

I
回复
0
查看
673
import
I
I
回复
0
查看
655
import
I
I
回复
0
查看
586
import
I
I
回复
0
查看
503
import
I
I
回复
0
查看
636
import
I
顶部