?? unit_main.pas
字號:
randx,randy:integer;
i,j:integer;
i_bombCount:integer;
tempGridArray:TGridArray ;
//在生成數(shù)字的過程中使用
LargeUpGridArray:array[0..g_MaxCol+1 ,0..g_MaxRow+1 ] of integer;
begin
tempGridArray .LocalTotalCols :=s_DownGridArray .LocalTotalCols ;
tempGridArray .LocalTotalRows :=s_DownGridArray .LocalTotalRows ;
//如果是重新開局的游戲,則直接將上次的雷區(qū)的情況賦值給新的雷區(qū)信息。
if isGameofRestart then
for I := 1 to s_DownGridArray .LocalTotalCols do
for j:= 1 to s_DownGridArray .LocalTotalRows do
begin
//聲明:重新開局后,不能保證鼠標的第一次按鍵不是雷,原因不言而喻
s_DownGridArray .Grid [i][j] :=LastDownGridArray.grid[i][j];
//該退出了.
exit;
end;
//如果不是重新開局,則按原順序執(zhí)行。。。
for I := 1 to s_DownGridArray .LocalTotalCols do
for j:= 1 to s_DownGridArray .LocalTotalRows do
begin
s_DownGridArray .Grid [i][j] :=0;
tempGridArray .Grid [i][j]:=0;
end;
//
i_bombCount :=BombCount ;
randomize; //播隨機種子
while i_BombCount <> 0 do
//嚴格意義上講.這里需要有一個變量來控制 While 循環(huán)的次數(shù),以免死循環(huán),有些格子就是
//得不到,但是在這里,由于雷數(shù)畢竟不是很多,所以,就沒有考慮..
begin
randx:=random(s_DownGridArray .LocalTotalCols )+1;
randy:=random(s_DownGridArray .LocalTotalRows )+1;
if (s_DownGridArray .Grid [randx][randy]=0) //沒有被標過雷
and (random(2)=1) //隨機的幾率
and (not((randx=localx )and (randy =localy ))) //確保當前按下的那個方塊不會是雷
then
begin
s_DownGridArray .Grid [randx][randy]:=10;
i_BombCount :=i_BombCount -1;
end;
end;
for i := 0 to s_DownGridArray .LocalTotalCols+1 do
for j:= 0 to s_DownGridArray .LocalTotalRows+1 do
LargeUpGridArray [i][j]:=0;
for I := 1 to s_DownGridArray .LocalTotalCols do
for j:= 1 to s_DownGridArray .LocalTotalRows do
LargeUpGridArray [i][j]:=s_DownGridArray .grid [i][j];
for i:= 1 to s_DownGridArray .LocalTotalCols do
for j:= 1 to s_DownGridArray .LocalTotalRows do
if s_DownGridArray .grid[i][j]<> 10 then
tempGridArray .grid[i][j]:= LargeUpGridArray[i-1][j-1]
+ LargeUpGridArray[i][j-1]
+ LargeUpGridArray[i+1][j-1]
+ LargeUpGridArray[i-1][j]
+ LargeUpGridArray[i+1][j]
+ LargeUpGridArray[i-1][j+1]
+ LargeUpGridArray[i][j+1]
+ LargeUpGridArray[i+1][j+1];
for I := 1 to s_DownGridArray .LocalTotalCols do
for j:= 1 to s_DownGridArray .LocalTotalRows do
s_DownGridArray .grid [i][j] :=LargeUpGridArray [i][j];
//得到DownGridArray中除了雷以外的數(shù)字區(qū)域.(0~8)
for i:= 1 to s_DownGridArray .LocalTotalCols do
for j:= 1 to s_DownGridArray .LocalTotalRows do
begin
// "-10" 是轉(zhuǎn)換到0~8 的算法.
s_DownGridArray .grid[i][j]:=s_DownGridArray .grid[i][j]+ (tempGridArray .grid[i][j] div 10);
LastDownGridArray.grid[i][j]:=s_DownGridArray .grid[i][j];
end;
end;
{
isColorForce 是用來判斷是否是一定要重新畫.在改變"顏色"菜單的內(nèi)容時才會時 True,其余的都是 False
}
procedure TFrm_Main.DrawBackGround(const d_UpGridArray:TGridArray ; const isColorForce:boolean);
var
i,j:integer;
procedure Drawimage(const argCol,argRow:integer;argimage:integer);
var
num:integer;
comImage:TImage;
begin
//考慮顏色選項的狀態(tài)
if not isHaveColor then
begin
argimage := argimage +100;
comImage :=Image_gray_block
end else
comImage :=Image_Color_block ;
case argimage of
111,11 :num :=1 ; //沒有被按下方塊
112,12 :num :=16 ; //被展開的沒有數(shù)字的方塊
113,13 :num :=16 ;
121,21 :num :=15 ; //數(shù)字-1
122,22 :num :=14 ; //數(shù)字-2
123,23 :num :=13 ; //數(shù)字-3
124,24 :num :=12 ; //數(shù)字-4
125,25 :num :=11 ; //數(shù)字-5
126,26 :num :=10 ; //數(shù)字-6
127,27 :num :=9 ; //數(shù)字-7
128,28 :num :=8 ; //數(shù)字-8
131,31 :num :=2 ; //標有旗幟的方塊
132,32 :num :=3; //沒有被按下的標有問好的方塊
133,33 :num :=7 ; //被按下的標有問好的方塊
141,41 :num :=6 ; //顯示出來的雷
142,42 :num :=4 ; //被炸開了的雷
143,43 :num :=5 ; //因標錯了而炸開的雷
else exit;
end;
Image_BackGround .Canvas .CopyRect(rect((argCol -1)*g_BlockWidth ,
(argRow -1)*g_BlockHeight ,argCol*g_BlockWidth ,argRow *g_BlockHeight ),
comImage .Canvas ,rect(0,(num -1) * g_BlockHeight ,g_BlockWidth ,num * g_BlockHeight));
end;
begin
for i := 1 to UpGridArray .LocalTotalCols do
for j := 1 to UpGridArray .LocalTotalRows do
//如果有不同顯示的雷區(qū)或是強行要重畫的情況下需要重畫數(shù)字區(qū)域
if (LastUpGridArray .Grid [i][j] <> d_UpGridArray .Grid [i][j]) or isColorForce then
begin
drawimage(i,j,d_UpGridArray.grid[i][j]);
// LastUpGridArray 供可能發(fā)生的"重新開始本局"事件時用到.
LastUpGridArray .Grid [i][j] := d_UpGridArray .Grid[i][j];
end;
end;
procedure TFrm_Main.DrawHead(const Count:integer;d_Dir:TDisplayDir );
var
d_i:integer;
d_Count:integer;
BombCountArr:array[1..3] of integer;
comimage:Timage;
num:integer;
begin
if Count >= 0 then
d_Count :=Count
else
d_Count :=abs(Count);
if Count >999 then
d_Count :=999;
for d_i:=3 downto 1 do
begin
BombCountArr [d_i]:=d_Count mod 10;
d_Count:=d_Count div 10
end;
if Count < 0 then
BombCountArr [1]:= -1;
for d_i:=1 to 3 do
begin
if not isHaveColor then
begin
BombCountArr [d_i] :=BombCountArr [d_i]+100;
comimage := image_gray_num;
end else
comimage := Image_Color_Num;
case BombCountArr [d_i] of
-1,99:num:=1 ; //數(shù)字- 負號
0,100:num:=12 ; //數(shù)字- 0 (以下是 1-9)
1,101:num:=11 ;
2,102:num:=10 ;
3,103:num:=9 ;
4,104:num:=8 ;
5,105:num:=7 ;
6,106:num:=6 ;
7,107:num:=5 ;
8,108:num:=4 ;
9,109:num:=3 ;
else exit;
end;
if not isHaveColor then
BombCountArr [d_i] :=BombCountArr [d_i] - 100;
case d_Dir of
d_left:
Image_Dis_BombCount .Canvas .CopyRect(rect((d_i-1)*g_NumWidth ,
0 ,d_i*g_NumWidth ,g_NumHeight ),comimage.Canvas ,
rect(0,(num-1)*g_NumHeight ,g_NumWidth ,num * g_NumHeight ));
d_right:
Image_Dis_Time .Canvas .CopyRect (rect((d_i-1)*g_NumWidth ,
0,d_i*g_NumWidth ,g_NumHeight ),comimage.Canvas ,
rect(0,(num-1)* g_NumHeight ,g_NumWidth ,num * g_NumHeight ));
else exit;
end;
end
end;
{
重點是四連通算法的實現(xiàn)..
}
procedure SeekBlackBlock(s_DownGridArray:TGridArray;var s_UpGridArray:TGridArray;s_Col,s_Row:integer);
var
HeadBlock,myBlock,newBlock:BlockPointer ;
i,j:integer;
s_tempGridArray:TGridArray ;
PointerOutX,PointerOutY:integer;
//初始化指針連表,帶頭結(jié)點
procedure initPointer();
var
i_i,i_j:integer;
begin
new(myBlock);
myBlock ^.BlockX :=0;
myBlock ^.BlockY :=0;
myBlock ^.preBlock :=nil;
myBlock ^.nextBlock :=nil;
HeadBlock :=myBlock ;
for i_i := 1 to s_DownGridArray .LocalTotalCols do
for i_j:= 1 to s_DownGridArray .LocalTotalRows do
s_tempGridArray .Grid [i_i][i_j]:=0;
end;
//入棧操作
procedure push(h_BlockX,h_BlockY:integer);
begin
new(newBlock);
newBlock ^.BlockX :=h_BlockX ;
newBlock ^.BlockY :=h_BlockY ;
newBlock ^.preBlock :=myBlock ;
newBlock ^.nextBlock :=nil;
myBlock ^.nextBlock :=newBlock ;
myBlock :=myBlock ^.nextBlock ;
end;
//出棧操作
procedure pop(var p_BlockX,p_BlockY:integer);
begin
p_BlockX :=myblock ^.BlockX ;
p_BlockY :=myBlock ^.BlockY ;
myBlock :=myBlock ^.preBlock ;
Dispose (myBlock ^.nextBlock );
myBlock ^.nextBlock :=nil;
end;
//只要處理部分
procedure ChangeUpGridArray();
var
c_i,c_j:integer;
begin
for c_i:= -1 to 1 do
for c_j:= -1 to 1 do
//判斷越界
if ((PointerOutX +c_i )>=1 ) and ((PointerOutX +c_i) <= s_DownGridArray .LocalTotalCols )
and ((PointerOutY +c_j)>=1) and ((PointerOutY +c_j)<= s_DownGridArray .LocalTotalRows) then
// 判斷在DownGridArray中不是雷的塊將它顯示出來
if (s_DownGridArray .grid[PointerOutX +c_i ][PointerOutY + c_j] <> 10)
and ((s_UpGridArray .grid[PointerOutX +c_i][PointerOutY +c_j] =11)
or (s_UpGridArray .grid[PointerOutX +c_i][PointerOutY +c_j] =13)
or (s_UpGridArray .grid[PointerOutX +c_i][PointerOutY +c_j] =33)
or (s_UpGridArray .grid[PointerOutX +c_i ][PointerOutY +c_j] = 32)) then
begin
// 判斷條件是用來處理DownGridArray 中 "0" 與UpGridArray 中 "12"的關(guān)系
if s_DownGridArray .grid[PointerOutX +c_i ][PointerOutY + c_j] = 0 then
s_UpGridArray .grid[PointerOutX +c_i ][PointerOutY +c_j]:= 12
else
begin
//20 為DownGridArray 中數(shù)字與 UpGridArray 中數(shù)字的差量
s_UpGridArray .grid[PointerOutX +c_i ][PointerOutY +c_j]:=
s_DownGridArray .grid[PointerOutX +c_i ][PointerOutY + c_j]+ 20;
end;
BlockOpenCount :=BlockOpenCount +1;
end;
end;
begin
initPointer ;
push(s_Col ,s_Row );
while HeadBlock ^.nextBlock <> nil do
begin
pop(PointerOutX ,PointerOutY );
ChangeUpGridArray ;
for i:=-1 to 1 do
for j:= -1 to 1 do
begin
if not( (i=0 ) and (j= 0)) then
if ((PointerOutX +i )>=1 ) and ((PointerOutX +i) <= s_DownGridArray .LocalTotalCols )
and ((PointerOutY +j)>=1) and ((PointerOutY +j)<= s_DownGridArray .LocalTotalRows) then
if (s_tempGridArray .Grid [PointerOutX +i][PointerOutY +j] = 0)
and (s_DownGridArray .grid[PointerOutX +i][PointerOutY +j] = 0) then
begin
s_tempGridArray .Grid [PointerOutX +i][PointerOutY +j] := 1;
push(PointerOutX +i,PointerOutY +j);
end;
end;
end;
end;
procedure TFrm_Main.GameWin(w_DownGridArray:TGridArray ;var w_UpGridArray:TGridArray);
var
w_i,w_j:integer;
New_Name:string;
begin
Timer_Display .Enabled :=False;
//將沒有展開的方塊標為雷,即插上紅旗.
for w_i:= 1 to w_DownGridArray .LocalTotalCols do
for w_j:= 1 to w_DownGridArray .LocalTotalRows do
if (w_UpGridArray .grid[w_i][w_j]=11) or (w_UpGridArray .grid[w_i][w_j]=32) then
w_UpGridArray .grid[w_i][w_j] := 31;
if isHaveSound then
sndPlaySound(pchar(comdir+g_ResourceName +g_Sound_GameWin),SND_ASYNC );
DrawBackGround(w_UpGridArray,false);
DrawHead(0,d_left );
ChgSpbtnGlyph(f_glass);
//打破記錄并且級別不是自定義級別,則需要顯示打破記錄,輸入大名的對話框
if (TotalTime < LocalScore) and (UserLevel <> v_UserDefine) then
begin
Application.CreateForm(TFrm_HeroName , Frm_HeroName );
Frm_HeroName .showmodal;
New_Name :=Unit_HeroName.New_Name;
Unit_Hero.InputScore(UserLevel,TotalTime ,New_Name);
Application.CreateForm(TFrm_Hero, Frm_Hero);
Frm_Hero.ShowModal ;
end;
isGameOver :=true;
isGameWin :=true;
//屏蔽 暫停 菜單
Menu_Pause_Resume.Enabled :=false;
GameStatus :=s_win;
ChangeStatusBar(UserLevel ,UserTotalCols,UserTotalRows, UserBombCount,GameStatus,LocalScore,LanguageType);
end;
procedure TFrm_Main.GameLost(l_DownGridArray:TGridArray ;var l_UpGridArray:TGridArray;l_Col,l_Row:TOverColAndRow);
var
l_i,l_j:integer;
begin
Timer_Display .Enabled :=False;
if isHaveSound then
sndPlaySound(pchar(comdir+g_ResourceName +g_Sound_GameLost),SND_ASYNC );
//根據(jù)傳進來的數(shù)組的值將那些是雷而沒有標的塊用42-爆炸的雷表示
for l_i:=1 to 8 do
if l_Col [l_i] <> 0 then
begin
l_UpGridArray .grid[l_Col [l_i]][l_Row [l_i]] := 42;
end;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -