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