Delphi制作實現的五子棋游戲,巧妙地利用Delphi的DrawGrid 控件屬性進行編程。當程序初始化時,對DrawGrid 控件進行操作,繪制程序所需的表格;然後添加代碼,使得當鼠標單擊表格時,按順序依次在點擊位置添加黑棋子和白棋子,直至一方勝利,給出獲勝消息。同時借助Timer 控件,隨時間的變化,不斷地修改窗體的圖標Icon 屬性,實現窗體的圖標動態變換。
編寫後的五子棋測試截圖:
設計步驟:
本例中首先繪制程序所需的表格,然後處理DrawGrid1MouseDown()事件,根據變量IsBlack 確定該繪制黑棋子還是白棋子,然後設置畫筆和畫刷的顏色,繪制棋子。再利用Tag[]來判斷是否有5 個棋子連成一條線,在處理Tag[]值的變化時,利用布爾變量IsWin來判斷哪方獲勝。關於動態改變窗體圖標,則在程序開始時,利用Extract“文件”的Path()
函數獲取圖標文件所在路徑,再從中讀取圖標。
1.新建工程
(1)啟動Delphi 6.0 程序。選擇“文件”菜單下的“新建”命令,從彈出的子菜單中選擇Application 選項,則出現新建工程的Form1 窗口。
(2)選擇“文件”菜單下的“工程另存為”命令,彈出Save Unit1 As 對話框。在“保存在”列表框中選擇需要存放該窗口文件所在的目錄名;在“文件名”編輯框中填寫文件名,這裡填寫“Main”,點擊“保存”按鈕,保存上面的選項。
(3)執行上一步後,將彈出“工程另存為”對話框。在“保存在”列表框中選擇需要存放該工程的目錄名,最好和第(2)步選取相同的目錄;在“文件名”編輯框中填寫保存處理該工程的源代碼的文件名,這裡填寫“Five”,點擊“保存”按鈕,保存上面的選項。
2.修改窗口
(1)激活Main 窗口,在“屬性”中設置該窗體的Caption 屬性為“五子棋游戲”,Color 屬性設置為“clBtnFace”。
(2)在構件選項板上選擇“標准”頁上的Panel 選項,將鼠標移到窗口中點擊,生產Panel 控件,用鼠標調整其合適大小和在窗體上的位置。在“屬性”中設置BevelInner 屬性為bvRaised,BevelOuter 屬性為bvLowered,BevelWidth 屬性為2,BiDiMode 屬性為bdLeftToRight,BorderStyle 屬性為bsSingle,BorderWidth 屬性為2,Color 屬性為clBtnFace。
(3)在構件選項板上選擇“附加”頁上的DrawGrid 選項,將鼠標移到窗口中點擊,生產DrawGrid 控件,用鼠標調整其合適大小和在窗體上的位置。在“屬性”中設置ColCount和RowCount 屬性均為19,DefaultColWidth 和DefaultRowHeight 屬性均為20。
(4)在構件選項板上選擇“系統”頁上的Timer 選項,將鼠標移到窗口中點擊,生產Timer 控件。
代碼分析:
(1)實現動態更改窗體圖標,首先自動獲取程序所在路徑,然後讀取圖標文件,更改窗體圖標Icon 屬性:
01
procedure
TmainForm
.
FormCreate(Sender: TObject);
02
var
03
MainDir:
String
[
80
];
04
begin
05
MainDir:=Extract"文件"Path(ParamStr(
0
));
//獲取程序路徑
06
end
;
07
procedure
TMainForm
.
Timer1Timer(Sender: TObject);
//循環播放圖標
08
begin
09
case
Timer1
.
Tag
of
10
0
:MainForm
.
Icon
.
LoadFrom"文件" (MainDir+’Icon\’+’Face01
.
ico’);
11
1
:MainForm
.
Icon
.
LoadFrom"文件" (MainDir+’Icon\’+’Face02
.
ico’);
12
2
:MainForm
.
Icon
.
LoadFrom"文件" (MainDir+’Icon\’+’Face03
.
ico’);
13
3
:MainForm
.
Icon
.
LoadFrom"文件" (MainDir+’Icon\’+’Face04
.
ico’);
14
end
;
15
if
Timer1
.
Tag>
2
then
//更新圖標
16
Timer1
.
Tag:=
0
17
else
18
Timer1
.
Tag:=Timer1
.
Tag+
1
;
19
end
;
這部分的關鍵是如何得到程序的圖標信息,得到該信息後,對該信息進行處理就可以達到目的。Delphi 6.0 的窗體屬性中有一個Icon 屬性,專門用來存放程序的圖標信息,通過對它的控制可以輕易地改變圖標。
(2)程序的初始化時,需要設置網格線的屬性。同時,利用
for I:=0 to 18 do for j:=0 to 18 do begin Tag[i,j]:=0;end;
循環來完成網格的初始化。Tag[]用來判別是否有5 個棋子連成一條線。網格中的每一個小方格用Tag[]中的一個值來表示,當該方格沒有棋子時,Tag[]為0,當該方格有一個黑色棋子時,Tag[]值為1,當為白色棋子時,Tag[]值為2,通過對Tag[]值的變化可以很方便得知網格中棋子的情況。
(3)下面處理鼠標點擊事件。當單擊鼠標左鍵時,根據游戲進行的情況,分別生成黑棋子和白棋子。利用一個布爾變量IsBlack 來確定每次點擊鼠標時應該生成黑棋還是白棋。當IsBlack 為真時,生成黑色棋子,反之,生成白色棋子。因為鼠標點擊事件貫穿於整個游戲,所以布爾變量IsBlack 設置為全局變量。
01
DrawGrid1
.
Canvas
.
Pen
.
Color :=clBlack;
//設置畫筆顏色
02
DrawGrid1
.
Canvas
.
Brush
.
Color :=clBlack;
//設置畫刷顏色
03
DrawGrid1
.
MouseToCell(x,y,col,row);
//繪制網格
04
if
Tag[col,row]=
0
then
05
begin
06
if
IsBlack
then
//當布爾變量IsBlack 為真時
07
begin
08
DrawGrid1
.
Canvas
.
Ellipse(col*
21
,row*
21
,(col+
1
)*
21
,(row+
1
)*
21
);
09
Tag[col,row]:=
1
;
//判斷黑棋的標志
10
end
else
11
begin
12
DrawGrid1
.
Canvas
.
Arc(col*
21
,row*
21
,(col+
1
)*
21
,(row+
1
)*
21
,col*
21
,row*
21
,col*
21
,row*
21
);
13
Tag[col,row]:=
2
;
//判斷白棋的標志
14
end
;
(4)為了准確判斷何時哪方最先獲勝,還需設置一個子函數IsWin()來判定是否有一方有5 個棋子連在同一條線上。IsWin 為布爾變量,初始時,設置其為False,從是否有行連成,是否有列連成,是否有主對角線連成和是否有副對角線連成四個方面來判斷IsWin變量是否為真。
01
function
TmainForm
.
IsWin(IsBlack:
boolean
):
boolean
;
02
Label
exit1;
03
var
04
i,j:
integer
;
05
wTag:
integer
;
06
begin
07
IsWin:=
False
;
08
if
IsBlack
then
09
wTag:=
1
10
else
11
wTag:=
2
;
12
for
i:=
0
to
18
do
13
for
j:=
0
to
14
do
14
begin
15
if
(i<
15
)
//是否有行連成
16
and
(Tag[i,j]=wTag)
17
and
(Tag[i+
1
,j]=wTag)
18
and
(Tag[i+
2
,j]=wTag)
19
and
(Tag[i+
3
,j]=wTag)
20
and
(Tag[i+
4
,j]=wTag)
21
then
22
begin
23
IsWin:=
True
;
24
goto
exit1;
25
end
;
26
if
(Tag[i,j]=wTag)
//是否有列連成
27
and
(Tag[i,j+
1
]=wTag)
28
and
(Tag[i,j+
2
]=wTag)
29
and
(Tag[i,j+
3
]=wTag)
30
and
(Tag[i,j+
4
]=wTag)
31
then
32
begin
33
IsWin:=
True
;
34
goto
exit1;
35
end
;
36
if
(i<
15
)
//是否有主對角線連成
37
and
(Tag[i,j]=wTag)
38
and
(Tag[i+
1
,j+
1
]=wTag)
39
and
(Tag[i+
2
,j+
2
]=wTag)
40
and
(Tag[i+
3
,j+
3
]=wTag)
41
and
(Tag[i+
4
,j+
4
]=wTag)
42
then
43
begin
44
IsWin:=
True
;
45
goto
exit1;
46
end
;
47
if
(Tag[i,j]=wTag)
//是否有副對角線連成
48
and
(Tag[i-
1
,j+
1
]=wTag)
49
and
(Tag[i-
2
,j+
2
]=wTag)
50
and
(Tag[i-
3
,j+
3
]=wTag)
51
and
(Tag[i-
4
,j+
4
]=wTag)
52
then
53
begin
54
IsWin:=
True
;
55
goto
exit1;
56
end
;
57
end
;
58
exit1:
59
end
;
(5)當布爾變量IsWin 為真時,也即有一方獲勝時,需要給出獲勝信息,並開始新的一局比賽,在新的一局裡,上局的敗方先執棋:
01
if
IsWin(IsBlack)
then
02
begin
03
if
IsBlack
then
04
if
MessageDlg(’黑方勝利’,mtInFormation,[mbOK],
0
)=mrOK
then
05
begin
06
for
i:=
0
to
18
do
07
for
j:=
0
to
18
do
08
begin
09
Tag[i,j]:=
0
;
10
end
;
11
DrawGrid1
.
Invalidate;
//網格初始化,下局白方先下
12
end
;
13
if
not
IsBlack
then
14
if
MessageDlg(’白方勝利’,mtInFormation,[mbOK],
0
)=mrOK
then
15
begin
16
for
i:=
0
to
18
do
17
for
j:=
0
to
18
do
18
begin
19
Tag[i,j]:=
0
;
20
end
;
21
DrawGrid1
.
Invalidate;
//網格初始化
22
end
;
23
end
;
24
IsBlack:=
not
IsBlack;
//白方勝利,則下局黑方先下
25
end
;
下面來看完整的代碼:
vIEw source