五子棋AI循序渐进【1】实现界面和位棋盘
先把這一個(gè)傳上來,關(guān)于局面評(píng)價(jià)的72向量和綜合比較、超出邊界的alpha-beta剪裁如何說明更清楚還得再考慮一下,以免表述的不清楚。因?yàn)檫@兩部分的代碼是整個(gè)代碼中最核心最重要也是最長(zhǎng)的。僅僅是下一集更新的源碼就超過600行。當(dāng)然了,邏輯是非常非常清晰的,因?yàn)楹芏喽际侵貜?fù)的邏輯內(nèi)容——硬編碼模板就這樣哎。而超出邊界的alpha-beta剪裁,是整個(gè)程序中最難理解的部分,說難理解不僅是因?yàn)檫f歸,更重要的是這種剪裁的思想。剩余的各個(gè)部分都非常好理解,編碼也很少了。就像將軍延伸和空步剪裁也就十行八行的代碼就實(shí)現(xiàn)了。而靜態(tài)搜索只是照著alpha-beta剪裁代碼稍微一改而已。好了,不多說閑話。
注:從這一篇開始都會(huì)對(duì)實(shí)現(xiàn)的內(nèi)容首先進(jìn)行解釋,然后傳本集的完整源碼,源碼都是VB2010編寫的。
一、位棋盤
1、為什么用位棋盤
按照通常我們的做法,可以用數(shù)組board(224),數(shù)據(jù)類型可以是byte,integer等,但是我們浪費(fèi)很多存儲(chǔ)空間,當(dāng)然這還不是主要問題,主要問題是速度太慢。原因很簡(jiǎn)單,尋址遠(yuǎn)慢于從integer中取某一位。
2、如何實(shí)現(xiàn)位棋盤
我們需要一個(gè)225位的數(shù)據(jù)類型,這種長(zhǎng)度的數(shù)據(jù)類型是沒有的,所以可以用integer數(shù)組來實(shí)現(xiàn)。幸好,VB.NET給我們提供了bitarray類,而這個(gè)類的內(nèi)部實(shí)現(xiàn)實(shí)際上也是用integer數(shù)組的。但是問題也隨之而來:1位只能是0或者1,而我們要表示白棋、黑棋、空三種數(shù)據(jù),怎么辦?其實(shí)很好解決,可以用2字代表一個(gè)位置,或者使用2個(gè)bitarray。我的程序采取第二種辦法:
Private wBitArr As BitArray
Private bBitArr As BitArray
3、如何操作位棋盤
直接上代碼:
'位棋盤
PublicClassmBitBoard
'用bitarray代替byte數(shù)組,提高讀寫速度。(bitarray內(nèi)部實(shí)現(xiàn)是用integer數(shù)組,每一個(gè)元素是32字節(jié),所以尋址速度要比用byte數(shù)組快很多)
'0=白方,1=黑方,2=空
PrivatewBitArrAsBitArray
PrivatebBitArrAsBitArray
'15*15的棋盤。
SubNew()
wBitArr=NewBitArray(225)
bBitArr=NewBitArray(225)
EndSub
'設(shè)置棋子
Sub[Set](indexAsInteger,valueAsInteger)
Ifvalue=0Then
wBitArr.Set(index,True)
ElseIfvalue=1Then
bBitArr.Set(index,True)
Else
bBitArr.Set(index,False)
wBitArr.Set(index,False)
EndIf
EndSub
'獲取棋子
Function[Get](indexAsInteger)AsInteger
IfwBitArr.Get(index)ThenReturn0
IfbBitArr.Get(index)ThenReturn1
Return2
EndFunction
EndClass
很清晰吧。這個(gè)類在后來進(jìn)行了一些小的修改——增加了一個(gè)函數(shù)。當(dāng)然這不是我們現(xiàn)在要討論的問題。好了,現(xiàn)在已經(jīng)有了棋盤的表示方法,那么我們來實(shí)現(xiàn)界面。其實(shí)界面簡(jiǎn)單得不能再簡(jiǎn)單了:
二、五子棋界面
1、搜索或者自己畫棋盤和棋子
2、獲取棋子偏移量、棋子大小、棋盤大小
3、根據(jù)mBitBoard實(shí)例繪制棋子
我實(shí)現(xiàn)的時(shí)候在窗體上面畫了一個(gè)panel,命名為pnlBoard。而后寫了這樣一個(gè)函數(shù):
'繪制棋子
Private Sub pnlBoard_Paint(sender As System.Object, e As System.Windows.Forms.PaintEventArgs) Handles pnlBoard.Paint
e.Graphics.DrawImage(My.Resources._2064, Point.Empty)
For i As Integer = 0 To 224
If ucpcSquares.Get(i) = 1 Then e.Graphics.DrawImage(bb, New Point((i Mod 15) * cs.Height, (i \ 15) * cs.Height) + co)
If ucpcSquares.Get(i) = 0 Then e.Graphics.DrawImage(bw, New Point((i Mod 15) * cs.Height, (i \ 15) * cs.Height) + co)
Next
End Sub
首先繪制棋盤圖像,然后繪制棋子。
下子的代碼是這樣的:
'下子
Private Sub pnlBoard_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles pnlBoard.MouseDown
Dim sdr = CType(sender, Panel)
'鼠標(biāo)坐標(biāo)轉(zhuǎn)棋盤坐標(biāo)
Dim p As Point = e.Location - co
p.X \= cs.Width
p.Y \= cs.Height
'下一個(gè)白子
If e.Button = Windows.Forms.MouseButtons.Left Then
ucpcSquares.Set(p.Y * 15 + p.X, 0)
'更新顯示
pnlBoard_Paint(sdr, New PaintEventArgs(sdr.CreateGraphics, sdr.DisplayRectangle))
End If
End Sub
很簡(jiǎn)單不是嗎。
完整的代碼如下:
PublicClassForm1
'黑白棋子
PrivatebbAsBitmap
PrivatebwAsBitmap
'棋子偏移
PrivatecoAsPoint=NewPoint(5,5)
'棋子大小
PrivatecsAsSize=NewSize(25,25)
'位棋盤
PrivateucpcSquaresAsmBitBoard
PrivateSubForm1_Load(senderAsSystem.Object,eAsSystem.EventArgs)HandlesMyBase.Load
'初始化棋子
DimresbmpAsBitmap=NewBitmap(My.Resources._7041,cs.Width*4,cs.Height)
DimallbmpAsBitmap=NewBitmap(resbmp.Width\2,resbmp.Height)
'獲取棋子圖像
ForyAsInteger=0Toallbmp.Height-1
ForxAsInteger=0Toallbmp.Width-1
Ifresbmp.GetPixel(x+allbmp.Width,y).ToArgb=Color.Black.ToArgbThenallbmp.SetPixel(x,y,resbmp.GetPixel(x,y))
Next
Next
bb=allbmp.Clone(NewRectangle(0,0,allbmp.Width/2,allbmp.Height),allbmp.PixelFormat)
bw=allbmp.Clone(NewRectangle(allbmp.Width/2,0,allbmp.Width/2,allbmp.Height),allbmp.PixelFormat)
'==========================開局棋型可在這里設(shè)置==============================
ucpcSquares=NewmBitBoard()
ucpcSquares.Set(7*15+7,1)
EndSub
'繪制棋子
PrivateSubpnlBoard_Paint(senderAsSystem.Object,eAsSystem.Windows.Forms.PaintEventArgs)HandlespnlBoard.Paint
e.Graphics.DrawImage(My.Resources._2064,Point.Empty)
ForiAsInteger=0To224
IfucpcSquares.Get(i)=1Thene.Graphics.DrawImage(bb,NewPoint((iMod15)*cs.Height,(i\15)*cs.Height)+co)
IfucpcSquares.Get(i)=0Thene.Graphics.DrawImage(bw,NewPoint((iMod15)*cs.Height,(i\15)*cs.Height)+co)
Next
EndSub
'下子
PrivateSubpnlBoard_MouseDown(senderAsObject,eAsSystem.Windows.Forms.MouseEventArgs)HandlespnlBoard.MouseDown
Dimsdr=CType(sender,Panel)
'鼠標(biāo)坐標(biāo)轉(zhuǎn)棋盤坐標(biāo)
DimpAsPoint=e.Location-co
p.X\=cs.Width
p.Y\=cs.Height
'下一個(gè)白子
Ife.Button=Windows.Forms.MouseButtons.LeftThen
ucpcSquares.Set(p.Y*15+p.X,0)
'更新顯示
pnlBoard_Paint(sdr,NewPaintEventArgs(sdr.CreateGraphics,sdr.DisplayRectangle))
EndIf
EndSub
EndClass
其中2064號(hào)資源是棋盤,7041是4個(gè)圖組成的:黑子、白子、各自的掩碼圖。我沒有使用掩碼圖,呵呵,用了一個(gè)循環(huán)。我的懶人原則是,初始化代碼,能省事就省事……
完整示例代碼:
/Files/zcsor/清月連珠0.1.7z
全部文章和源碼整理完成,以后更新也會(huì)在下面地址:
http://www.vbdevelopers.org
http://www.softos.org
騰訊云服務(wù)器安全可靠高性能,多種配置供您選擇
騰訊云數(shù)據(jù)庫性能卓越穩(wěn)定可靠,為您解決數(shù)據(jù)庫運(yùn)維難題
騰訊云CDN擁有頂尖加速能力,豐富的功能全面覆蓋各業(yè)務(wù)場(chǎng)景的加速需求,最為用戶考慮的加速產(chǎn)品
總結(jié)
以上是生活随笔為你收集整理的五子棋AI循序渐进【1】实现界面和位棋盘的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: poj2594(二分图,最小路径覆盖变形
- 下一篇: 四则运算2开发简介