程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi 五子棋制作教程

Delphi 五子棋制作教程

編輯:Delphi

Delphi制作實現的五子棋游戲,巧妙地利用Delphi的DrawGrid 控件屬性進行編程。當程序初始化時,對DrawGrid 控件進行操作,繪制程序所需的表格;然後添加代碼,使得當鼠標單擊表格時,按順序依次在點擊位置添加黑棋子和白棋子,直至一方勝利,給出獲勝消息。同時借助Timer 控件,隨時間的變化,不斷地修改窗體的圖標Icon 屬性,實現窗體的圖標動態變換。

編寫後的五子棋測試截圖:

Delphi五子棋

設計步驟:

本例中首先繪制程序所需的表格,然後處理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 print? 001 unit main; 002 interface 003 uses 004 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 005 ComCtrls, ScktComp, Grids, Menus, StdCtrls, ExtCtrls; 006 type 007 TmainForm = class(TForm) 008 Panel1: TPanel; 009 DrawGrid1: TDrawGrid; 010 Timer1: TTimer; 011 procedure FormCreate(Sender: TObject); 012 procedure Timer1Timer(Sender: TObject); 013 procedure DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; 014 Rect: TRect; State: TGridDrawState); 015 procedure DrawGrid1MouseDown(Sender: TObject; Button: TMouseButton; 016 Shift: TShiftState; X, Y: Integer); 017 private 018 { Private declarations } 019 Tag:array[0..18,0..18]of integer; 020 {0 for none,1 for black,2 for white} 021 IsBlack:boolean; 022 public 023 { Public declarations } 024 MainDir:String[80];//程序目錄 025 function IsWin(IsBlack:boolean):boolean//是否獲勝 026 end; 027 var 028 mainForm: TmainForm; 029 implementation 030 {$R *.DFM} 031 function TmainForm.IsWin(IsBlack:boolean):boolean; 032 Label exit1; 033 var 034 i,j:integer; 035 wTag:integer; 036 begin 037 IsWin:=False; 038 if IsBlack then 039 wTag:=1 else 040 wTag:=2; 041 for i:=0 to 18 do 042 for j:=0 to 14 do 043 begin 044 if (i<15//是否有行連成 045 and(Tag[i,j]=wTag) 046 and(Tag[i+1,j]=wTag) 047 and(Tag[i+2,j]=wTag) 048 and(Tag[i+3,j]=wTag) 049 and(Tag[i+4,j]=wTag) 050 then 051 begin 052 IsWin:=True; 053 goto exit1; 054 end; 055 if (Tag[i,j]=wTag) //是否有列連成 056 and(Tag[i,j+1]=wTag) 057 and(Tag[i,j+2]=wTag) 058 and(Tag[i,j+3]=wTag) 059 and(Tag[i,j+4]=wTag) 060 then 061 begin 062 IsWin:=True; 063 goto exit1; 064 end; 065 if (i<15//是否有主對角線連成 066 and(Tag[i,j]=wTag) 067 and(Tag[i+1,j+1]=wTag) 068 and(Tag[i+2,j+2]=wTag) 069 and(Tag[i+3,j+3]=wTag) 070 and(Tag[i+4,j+4]=wTag) 071 then 072 begin 073 IsWin:=True; 074 goto exit1; 075 end; 076 if (Tag[i,j]=wTag) //是否有副對角線連成 077 and(Tag[i-1,j+1]=wTag) 078 and(Tag[i-2,j+2]=wTag) 079 and(Tag[i-3,j+3]=wTag) 080 and(Tag[i-4,j+4]=wTag) 081 then 082 begin 083 IsWin:=True; 084 goto exit1; 085 end; 086 end; 087 exit1: 088 end; 089 procedure TmainForm.FormCreate(Sender: TObject); 090 var 091 i,j:integer; 092 begin 093 for i:=0 to 18 do 094 for j:=0 to 18 do 095 begin 096 Tag[i,j]:=0; 097 end; 098 IsBlack:=true//設置IsBlack 初值,第一局黑棋先下 099 MainDir:=Extract"文件"Path(ParamStr(0)); //獲取程序路徑 100 end; 101 procedure TMainForm.Timer1Timer(Sender: TObject); //循環播放圖標 102 begin 103 case Timer1.Tag of 104 0:MainForm.Icon.LoadFrom"文件" (MainDir+’Icon\’+’Face01.ico’); 105 1:MainForm.Icon.LoadFrom"文件" (MainDir+’Icon\’+’Face02.ico’); 106 2:MainForm.Icon.LoadFrom"文件" (MainDir+’Icon\’+’Face03.ico’); 107 3:MainForm.Icon.LoadFrom"文件" (MainDir+’Icon\’+’Face04.ico’); 108 end; 109 if Timer1.Tag>2 then //更新圖標 110 Timer1.Tag:=0 111 else 112 Timer1.Tag:=Timer1.Tag+1; 113 end; 114 procedure TmainForm.DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; 115 Rect: TRect; State: TGridDrawState); 116 begin 117 DrawGrid1.Canvas.Pen.Color :=clBlack; //設置畫筆顏色 118 DrawGrid1.Canvas.Brush.Color :=clBlack; //設置畫刷顏色 119 if Tag[acol,arow]=1 then 120 DrawGrid1.Canvas.Ellipse(acol*21,arow*21,(acol+1)*21,(arow+1)*21//繪制黑棋 121 else if Tag[acol,arow]=2 then 122 DrawGrid1.Canvas.Arc(acol*21,arow*21,(acol+1)*21,(arow+1)*21,acol*21, 123 arow*21,acol*21,arow*21//繪制白棋 124 else 125 begin 126 DrawGrid1.Canvas.Pen.Color :=clWhite; //設置畫筆顏色 127 DrawGrid1.Canvas.Brush.Color :=clWhite; //設置畫刷顏色 128 DrawGrid1.Canvas.Ellipse(acol*21,arow*21,(acol+1)*21,(arow+1)*21); 129 end; 130 end; 131 procedure TmainForm.DrawGrid1MouseDown(Sender: TObject; 132 Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 133 var 134 col,row:integer; 135 i,j:integer; 136 begin 137 DrawGrid1.Canvas.Pen.Color :=clBlack; //設置畫筆顏色 138 DrawGrid1.Canvas.Brush.Color :=clBlack; //設置畫刷顏色 139 DrawGrid1.MouseToCell(x,y,col,row); //繪制網格 140 if Tag[col,row]=0 then 141 begin 142 if IsBlack then 143 begin 144 DrawGrid1.Canvas.Ellipse(col*21,row*21,(col+1)*21,(row+1)*21); 145 Tag[col,row]:=1//判斷黑棋的標志 146 end else 147 begin 148 DrawGrid1.Canvas.Arc(col*21,row*21,(col+1)*21,(row+1)*21,col*21,row*21,col*21,row*21); 149 Tag[col,row]:=2//判斷白棋的標志 150 end; 151 if IsWin(IsBlack) then 152 begin 153 if IsBlack then 154 if MessageDlg(’黑方勝利’,mtInFormation,[mbOK],0)=mrOK then 155 begin 156 for i:=0 to 18 do 157 for j:=0 to 18 do 158 begin 159 Tag[i,j]:=0; 160 end; 161 DrawGrid1.Invalidate; //網格初始化,下局白方先下 162 end; 163 if not IsBlack then 164 if MessageDlg(’白方勝利’,mtInFormation,[mbOK],0)=mrOK then 165 begin 166 for i:=0 to 18 do 167 for j:=0 to 18 do 168 begin 169 Tag[i,j]:=0; 170 end; 171 DrawGrid1.Invalidate; //網格初始化 172 end; 173 end; 174 IsBlack:=not IsBlack; //白方勝利,則下局黑方先下 175 end; 176 end;
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved