五子棋AI循序渐进【1】实现界面和位棋盘
先把這一個傳上來,關于局面評價的72向量和綜合比較、超出邊界的alpha-beta剪裁如何說明更清楚還得再考慮一下,以免表述的不清楚。因為這兩部分的代碼是整個代碼中最核心最重要也是最長的。僅僅是下一集更新的源碼就超過600行。當然了,邏輯是非常非常清晰的,因為很多都是重復的邏輯內容——硬編碼模板就這樣哎。而超出邊界的alpha-beta剪裁,是整個程序中最難理解的部分,說難理解不僅是因為遞歸,更重要的是這種剪裁的思想。剩余的各個部分都非常好理解,編碼也很少了。就像將軍延伸和空步剪裁也就十行八行的代碼就實現了。而靜態搜索只是照著alpha-beta剪裁代碼稍微一改而已。好了,不多說閑話。
注:從這一篇開始都會對實現的內容首先進行解釋,然后傳本集的完整源碼,源碼都是VB2010編寫的。
一、位棋盤
1、為什么用位棋盤
按照通常我們的做法,可以用數組board(224),數據類型可以是byte,integer等,但是我們浪費很多存儲空間,當然這還不是主要問題,主要問題是速度太慢。原因很簡單,尋址遠慢于從integer中取某一位。
2、如何實現位棋盤
我們需要一個225位的數據類型,這種長度的數據類型是沒有的,所以可以用integer數組來實現。幸好,VB.NET給我們提供了bitarray類,而這個類的內部實現實際上也是用integer數組的。但是問題也隨之而來:1位只能是0或者1,而我們要表示白棋、黑棋、空三種數據,怎么辦?其實很好解決,可以用2字代表一個位置,或者使用2個bitarray。我的程序采取第二種辦法:
Private wBitArr As BitArray
Private bBitArr As BitArray
3、如何操作位棋盤
直接上代碼:
'位棋盤
PublicClassmBitBoard
'用bitarray代替byte數組,提高讀寫速度。(bitarray內部實現是用integer數組,每一個元素是32字節,所以尋址速度要比用byte數組快很多)
'0=白方,1=黑方,2=空
PrivatewBitArrAsBitArray
PrivatebBitArrAsBitArray
'15*15的棋盤。
SubNew()
wBitArr=NewBitArray(225)
bBitArr=NewBitArray(225)
EndSub
'設置棋子
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
很清晰吧。這個類在后來進行了一些小的修改——增加了一個函數。當然這不是我們現在要討論的問題。好了,現在已經有了棋盤的表示方法,那么我們來實現界面。其實界面簡單得不能再簡單了:
二、五子棋界面
1、搜索或者自己畫棋盤和棋子
2、獲取棋子偏移量、棋子大小、棋盤大小
3、根據mBitBoard實例繪制棋子
我實現的時候在窗體上面畫了一個panel,命名為pnlBoard。而后寫了這樣一個函數:
'繪制棋子
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)
'鼠標坐標轉棋盤坐標
Dim p As Point = e.Location - co
p.X \= cs.Width
p.Y \= cs.Height
'下一個白子
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
很簡單不是嗎。
完整的代碼如下:
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)
'==========================開局棋型可在這里設置==============================
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)
'鼠標坐標轉棋盤坐標
DimpAsPoint=e.Location-co
p.X\=cs.Width
p.Y\=cs.Height
'下一個白子
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號資源是棋盤,7041是4個圖組成的:黑子、白子、各自的掩碼圖。我沒有使用掩碼圖,呵呵,用了一個循環。我的懶人原則是,初始化代碼,能省事就省事……
完整示例代碼:
/Files/zcsor/清月連珠0.1.7z
全部文章和源碼整理完成,以后更新也會在下面地址:
http://www.vbdevelopers.org
http://www.softos.org
騰訊云服務器安全可靠高性能,多種配置供您選擇
騰訊云數據庫性能卓越穩定可靠,為您解決數據庫運維難題
騰訊云CDN擁有頂尖加速能力,豐富的功能全面覆蓋各業務場景的加速需求,最為用戶考慮的加速產品
總結
以上是生活随笔為你收集整理的五子棋AI循序渐进【1】实现界面和位棋盘的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: poj2594(二分图,最小路径覆盖变形
- 下一篇: 四则运算2开发简介