返回
{***************************************************************}
{*** FVision Unit Version1.0 ***}
{*** 蓝蚂蚁工作室 ***}
{***************************************************************}
{*** 挖地雷单元 ***}
{***************************************************************}
{$O+,F+,X+,I-}
Unit FMine;
Interface
Uses
Graph,FGraph,FMouse,FEvent,FView,FDialog,
FControl,FWrite,FTool,FMenu;
Type
PMine=^TMine;
TMine=object(TWindow)
Die:TPoint;
Sign:array [1..30,1..20] of Byte;
Bob,Mark:array [0..31,0..21] of Byte;
R:TRect;
Wid,Numx,Numy,NumBob:Integer;
SignNum,FrBob:Integer;
GameDie,GameStart:Boolean;
TimeStr,BobStr,FBobStr:PStaticText;
Timer:PTimer;
TimeCount:Longint;
Constructor Init;
Procedure InitMenu;virtual;
Procedure InitJu;
Procedure NewGame;
Procedure Gird(x,y:Integer);
Procedure GirdAll;
Procedure InitBob;
Procedure UnGird(x,y:Integer);
Procedure MakeMark(ox,oy:Integer);
Procedure Show_End_Bob(x,y:Integer);
Procedure Show_Die_Bob(x,y:Integer);
Function Around_Bob(x,y:Integer):Integer;
Function Around_Sign(x,y:Integer):Integer;
Function TrueMark(x,y:Integer):Boolean;
Procedure Show_UnBob(x,y:Integer);
Procedure Clear_UnBob(x,y:Integer);
Procedure Clear_MarkBob(x,y:Integer);
Procedure Show_AllBob;
Procedure Paint;virtual;
Procedure Draw;virtual;
Procedure MoveTo(x,y:Integer);virtual;
Procedure Judge_Bob(x,y:Integer);
Procedure ProSign(x,y:Integer);
Procedure ProDouble(x,y:Integer);
Procedure HandleEvent(var Event:TEvent);virtual;
Procedure SetupPara;
end;
Implementation
Const
cmSetupMine = 550;
Const
ColorTab:array[1..8] of Byte=(1,4,5,13,8,9,10,15);
Const
MineWid:Integer=20;
MineHig:Integer=12;
MineBob:Integer=45;
Constructor TMine.Init;
var
T:TRect;
begin
Wid:=16;
Numx:=MineWid;
Numy:=MineHig;
NumBob:=MineBob;
AssignRect(T,0,0,Wid*Numx+16,Wid*Numy+83);
Inherited Init(T,'挖地雷',True);
AssignRect(R,8,50,8+Wid*Numx,50+Wid*Numy);
AssignRect(T,R.a.x-3,R.a.y-3,R.b.x+3,R.b.y+3);
Insert(New(PShape,Init(gcBroad+gcHideMouse,T,0,0,7,0,'')));
AssignRect(T,5,Broad.b.y-25,R.b.x+3,Broad.b.y-5);
Insert(New(PShape,Init(gcBroad+gcHideMouse,T,0,0,$0A,0,'')));
Insert(New(PStaticText,Init(stNormal+stFColor,6,Broad.b.y-23,
'总数: 剩余: 时间:',$A0)));
BobStr:=New(PStaticText,Init(stNormal+stFColor,48,Broad.b.y-23,IntStr(NumBob),$A4));
FBobStr:=New(PStaticText,Init(stNormal+stFColor,130,Broad.b.y-23,IntStr(NumBob),$A4));
TimeStr:=New(PStaticText,Init(stNormal+stFColor,210,Broad.b.y-23,'0',$A4));
Insert(BobStr);
Insert(FBobStr);
Insert(TimeStr);
Timer:=New(PTimer,Init(0));
Insert(Timer);
InitJu;
Timer^.StopTimer;
Center;
end;
Procedure TMine.InitMenu;
var
T:TRect;
begin
Inherited InitMenu;
AssignRect(T,5,27,Broad.b.x-5,44);
Insert(New(PMainMenu,Init(T,False,
NewSubMenu('游戏~P~',kbAltP,New(PMenu,Init(
NewMenuItem('新局',kbNoKey,cmNew,nil,
NewMenuItem('设置',kbNoKey,cmSetupMine,nil,
NewMenuItem('',0,0,nil,
NewMenuItem('关闭 ~Alt+F3~',kbAltF3,cmCloseWin,nil,nil)))))),
NewSubMenu('帮助~H~',kbAltH,New(PMenu,Init(
NewMenuItem('关于',kbNoKey,cmAbout,nil,nil))),nil)))));
end;
Procedure TMine.MoveTo;
begin
Inherited MoveTo(X,Y);
AssignRect(R,X+8,Y+50,X+8+Wid*Numx,Y+50+Wid*Numy);
end;
Procedure TMine.Paint;
begin
Inherited Paint;
Draw;
end;
Procedure TMine.Draw;
var
i,j:integer;
begin
HideMouse;
SetColor(8);
for i:=0 to Numx do
Line(r.a.x+i*Wid,r.a.y,r.a.x+i*Wid,r.b.y);
for i:=0 to Numy do
Line(r.a.x,r.a.y+i*Wid,r.b.x,r.a.y+i*Wid);
if GameDie then
begin
Show_AllBob;
Show_Die_Bob(Die.x,Die.y);
end else
begin
for i:=1 to Numx do
for j:=1 to Numy do
begin
if Sign[i,j]=0 then
Gird(i,j)
else if Around_Bob(i,j)>0 then
begin
SetTextStyle(0,0,1);
SetColor(ColorTab[Around_Bob(i,j)]);
OutTextXy(r.a.x+(i-1)*Wid+5,r.a.y+(j-1)*Wid+5,IntStr(Around_Bob(i,j)));
end;
if Mark[i,j]=1 then MakeMark(i,j);
end;
end;
end;
Procedure TMine.NewGame;
begin
InitJu;
Draw;
end;
Procedure TMine.InitJu;
var
i,j:Integer;
begin
for i:=1 to 30 do
for j:=1 to 20 do
Mark[i,j]:=10;
Randomize;
InitBob;
SignNum:=0;
FrBob:=NumBob;
for i:=1 to 30 do
for j:=1 to 20 do
Sign[i,j]:=0;
for i:=0 to Numx+1 do
for j:=0 to Numy+1 do
Mark[i,j]:=0;
GameDie:=False;
GameStart:=True;
TimeCount:=0;
Timer^.SetTime(100);
BobStr^.Modify(IntStr(NumBob));
FBobStr^.Modify(IntStr(NumBob));
TimeStr^.Modify('0');
end;
Procedure TMine.InitBob;
var
i,j,m,n,AllBob:Integer;
begin
for i:=0 to Numx+1 do
for j:=0 to Numy+1 do
Bob[i,j]:=0;
AllBob:=0;
while AllBob<NumBob do
begin
AllBob:=0;
m:=Random(Numx)+1;
n:=Random(Numy)+1;
Bob[m,n]:=1;
for i:=1 to Numx do
for j:=1 to Numy do
AllBob:=Bob[i,j]+AllBob;
end;
end;
Procedure TMine.Gird;
begin
HideMouse;
DrawBroad(R.a.x+(x-1)*Wid+1,R.a.y+(y-1)*Wid+1,
R.a.x+x*Wid-1,R.a.y+y*Wid-1,1);
ShowMouse;
end;
Procedure TMine.GirdAll;
var
i,j:Integer;
begin
HideMouse;
for i:=0 to Numx-1 do
for j:=0 to Numy-1 do
DrawBroad(R.a.x+i*Wid+1,R.a.y+j*Wid+1,
R.a.x+(i+1)*Wid-1,R.a.y+(j+1)*Wid-1,1);
ShowMouse;
end;
Procedure TMine.UnGird;
begin
HideMouse;
Full(R.a.x+(x-1)*Wid+1,R.a.y+(y-1)*Wid+1,
R.a.x+x*Wid-1,R.a.y+y*Wid-1,7);
ShowMouse;
end;
Procedure TMine.MakeMark;
var
x,y:Integer;
begin
x:=R.a.x+Wid*(ox-1);
y:=R.a.y+Wid*(oy-1);
HideMouse;
SetColor(0);
SetLineStyle(0,0,1);
Line(X+5,Y+Wid-5,X+Wid-4,Y+Wid-5);
Line(X+5,Y+Wid-4,X+Wid-4,Y+Wid-4);
Line(X+7,Y+Wid-6,X+Wid-6,Y+Wid-6);
Line(X+8,Y+Wid-5,X+Wid-6,Y+Wid-5);
Line(X+9,Y+4,X+9,Y+Wid-5);
SetFillStyle(1,4);
Bar(X+5,Y+4,X+9,Y+7);
ShowMouse;
end;
Procedure TMine.Show_End_Bob;
begin
HideMouse;
SetLineStyle(0,0,2);
SetColor(0);
SetFillstyle(0,0);
FillEllipse(R.a.x+x*Wid-Wid div 2,R.a.y+y*Wid-Wid div 2,Wid div 2-3,Wid div 2-3);
Line(r.a.x+(x-1)*Wid+1,r.a.y+y*Wid-Wid div 2,r.a.x+x*Wid-1,r.a.y+y*Wid-Wid div 2);
Line(r.a.x+x*Wid-Wid div 2,r.a.y+(y-1)*Wid+1,r.a.x+x*Wid-Wid div 2,r.a.y+y*Wid-1);
Line(r.a.x+(x-1)*Wid+3,r.a.y+(y-1)*Wid+3,r.a.x+x*Wid-3,r.a.y+y*Wid-3);
Line(r.a.x+(x-1)*Wid+3,r.a.y+y*Wid-3,r.a.x+x*Wid-3,r.a.y+(y-1)*Wid+3);
SetFillStyle(1,15);
Bar(R.a.x+(x-1)*Wid+5,R.a.y+(y-1)*Wid+5,R.a.x+(x-1)*Wid+Wid div 2-1,
R.a.y+(y-1)*Wid+Wid div 2-1);
ShowMouse;
end;
Procedure TMine.Show_Die_Bob;
begin
UnGird(x,y);
SetFillStyle(1,4);
HideMouse;
FloodFill(R.a.x+(x-1)*Wid+2,R.a.y+(y-1)*Wid+2,8);
Show_End_Bob(x,y);
Die.x:=x;
Die.y:=y;
end;
Function TMine.Around_Bob;
var
i,j,Around:Integer;
begin
Around:=0;
for i:=x-1 to x+1 do
for j:=y-1 to y+1 do
Inc(Around,Bob[i,j]);
Around_Bob:=Around;
end;
Function TMine.Around_Sign;
var
i,j,Around:Integer;
begin
Around:=0;
for i:=x-1 to x+1 do
for j:=y-1 to y+1 do
Around:=Around+Mark[i,j];
Around_Sign:=Around;
end;
Function TMine.TrueMark;
var
i,j:Byte;
begin
TrueMark:=True;
for i:=x-1 to x+1 do
for j:=y-1 to y+1 do
if Bob[i,j]<>Mark[i,j] then
TrueMark:=False;
end;
Procedure TMine.Show_UnBob;
var
Color:Byte;
begin
if (x<1)or(x>Numx)or(y<1)or(y>Numy) then Exit;
if Bob[x,y]=0 then
begin
UnGird(x,y);
if Sign[x,y]=0 then
begin
Sign[x,y]:=1;
Inc(SignNum);
end;
if Around_Bob(x,y)<>0 then
begin
HideMouse;
SetTextJustify(0,2);
SetTextStyle(0,0,1);
SetColor(ColorTab[Around_Bob(x,y)]);
OutTextxy(R.a.x+(x-1)*Wid+5,R.a.y+(y-1)*Wid+5,
IntStr(Around_Bob(x,y)));
ShowMouse;
end;
end;
end;
Procedure TMine.Clear_UnBob;
var
i,j:Integer;
begin
if (Around_Bob(x,y)<1) then
begin
for i:=x-1 to x+1 do
for j:=y-1 to y+1 do
if (i>0)and(i<=Numx)and(j>0)and(j<=Numy)and(Sign[i,j]=0) then
begin
Show_UnBob(i,j);
Clear_UnBob(i,j);
end;
end;
Show_UnBob(x,y);
end;
Procedure TMine.Clear_MarkBob;
var
i,j:Byte;
begin
for i:=x-1 to x+1 do
for j:=y-1 to y+1 do
if (i>0)and(i<=Numx)and(j>0)and(j<=Numy) then
Clear_UnBob(i,j);
end;
Procedure TMine.Show_AllBob;
var
i,j:Integer;
begin
for i:=1 to Numx do
for j:=1 to Numy do
begin
if Bob[i,j]=1 then
begin
UnGird(i,j);
Show_End_Bob(i,j);
end else
Show_UnBob(i,j);
end;
end;
Procedure TMine.Judge_Bob;
begin
if Bob[x,y]=1 then
begin
Show_AllBob;
Show_Die_Bob(x,y);
GameDie:=True;
GameStart:=False;
end else
Clear_UnBob(x,y);
end;
Procedure TMine.ProSign;
begin
if Sign[x,y]<>0 then Exit;
if Mark[x,y]=0 then
begin
Mark[x,y]:=1;
MakeMark(x,y);
Dec(FrBob);
end else
begin
Mark[x,y]:=0;
Gird(x,y);
Inc(FrBob);
end;
FBobStr^.Modify(IntStr(FrBob));
end;
Procedure TMine.ProDouble;
begin
if TrueMark(x,y) then
Clear_MarkBob(x,y)
else if Around_Bob(x,y)=Around_Sign(x,y) then
begin
Show_AllBob;
Show_Die_Bob(x,y);
GameDie:=True;
GameStart:=False;
end;
end;
Procedure TMine.HandleEvent;
var
x,y:Integer;
begin
Inherited HandleEvent(Event);
if GameStart and (not GameDie) and (SignNum=Numx*Numy-NumBob) then
begin
GameStart:=False;
RunView(New(PMsgDialog,Init('挖地雷','很好,地雷全部排除!',mbOkOnly)),Event);
ClearEvent(Event);
end;
if (Event.What and evMouse)<>0 then
begin
x:=(Event.Where.x-R.a.x) div Wid +1;
y:=(Event.Where.y-R.a.y) div Wid +1;
end;
if GameStart and ((Event.What and evMouse)<>0) and IsIn(Event.Where,R) and
((Event.Buttons and mbLeftButton)<>0) and ((Event.Buttons and mbRightButton)<>0) then
begin
ProDouble(x,y);
ClearEvent(Event);
end;
case Event.What of
evMouseDown:if GameStart and IsIn(Event.Where,R) then
begin
if Event.Buttons=mbLeftButton then
Judge_Bob(x,y)
else if Event.Buttons=mbRightButton then
ProSign(x,y);
end else Exit;
evCommand:case Event.Command of
cmAbout:RunView(New(PMsgDialog,Init('关于',
#3'挖地雷游戏v1.0'#13#3'蓝蚂蚁工作室',mbOkOnly)),Event);
cmNew:NewGame;
cmSetupMine:SetupPara;
cmTimer:begin
Inc(TimeCount);
TimeStr^.Modify(IntStr(TimeCount));
Timer^.Reset;
if not GameStart then Timer^.StopTimer;
end;
else Exit;
end;
else Exit;
end;
ClearEvent(Event);
end;
Procedure TMine.SetupPara;
var
T:TRect;
P:PWindow;
Q:PRadioButton;
Mode:Byte;
begin
Mode:=2;
AssignRect(T,0,0,220,150);
P:=New(PWindow,Init(T,'设置大小',True));
Q:=New(PRadioButton,Init(20,40,200,110,'模式:',Mode));
Q^.Insert('15*10,30颗雷');
Q^.Insert('20*12,45颗雷');
Q^.Insert('25*18,95颗雷');
P^.Insert(Q);
P^.Insert(New(PButton,Init(95,120,145,140,'确定',0,cmOk)));
P^.Insert(new(pbutton,init(150,120,200,140,'放弃',0,cmCancel)));
P^.Next;
P^.Center;
RunView(P,Event);
case Mode of
1:begin MineWid:=15;MineHig:=10;MineBob:=30; end;
2:begin MineWid:=20;MineHig:=12;MineBob:=45; end;
3:begin MineWid:=25;MineHig:=18;MineBob:=95; end;
end;
end;
end.