五子棋的AI構想 有句話叫“當局者迷,旁觀者清?!?,但這句話在由AI所控制的計算機玩家上是不成立的,因為計算機必須知道有那些獲勝方式,并計算出每下一步棋到棋盤上任一格子的獲勝幾率,也就是說,一個完整的五子棋的AI構想必須:
成都創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設、高性價比興化網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式興化網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設找我們,業(yè)務覆蓋興化地區(qū)。費用合理售后完善,十年實體公司更值得信賴。
1、能夠知道所有的獲勝組合; 2、建立和使用獲勝表; 3、設定獲勝的分數(shù); 4、使電腦具有攻擊和防守的能力; 一、求五子棋的獲勝組合 在一場五子棋的游戲中,計算機必須要知道有那些的獲勝組合,因此我們必須求得獲勝組合的總數(shù)。我們假定當前的棋盤為10*10。 (1)計算水平方向的獲勝組合數(shù),每一列的獲勝組合是:6,共10列,所以水平方向的獲勝組合數(shù)為:6*10=60 (2)計算垂直方向的獲勝組合總數(shù),每一行的獲勝組合是:6,共10行,則垂直方向的獲勝組合數(shù)為:6*10=60 (3)計算正對角線方向的獲勝組合總數(shù),正對角線上的獲勝組合總數(shù)為6+(5+4+3+2+1)*2=36 (4)計算反對角線方向的獲勝組合總數(shù),反對角線上的獲勝組合總數(shù)為6+(5+4+3+2+1)*2=36 ,這樣所有的獲勝組合數(shù)為:60+60+36+36=192 二、建立和使用獲勝表 我們已經(jīng)計算出了一個10*10的五子棋盤會有192種獲勝方式,這樣我們可以利用數(shù)組建立獲勝表,獲勝表的主要作用是:1,判斷當前的獲勝方式是否有效;2,判斷當前的獲勝方式中到底有多少子落入該獲勝組合中。詳細的使用您將在后面的程序中可以看出。 三,分數(shù)的設定 在游戲中為了讓計算機能夠決定下一步最佳的走法,必須先計算出計算機下到棋盤上任一空格的分數(shù),而其中最高分數(shù)便是計算機下一步的最佳走法。 原理:我們判定當前討論的空格與當前討論的點有幾種獲勝的方式,有幾種該空格就加幾分。這種原理初聽起來似乎是無法入手,沒關系,當您了解我們后面的程序后您就會明白這種決策原理了。 這種決策有一些缺陷,因為如果只根據(jù)這個模型設計,就有可能出現(xiàn)電腦或玩家有三個子連成一線的時候,計算機卻判斷不出,它認為其他某些空格是當前的獲勝的最佳位置而不去攻擊或防守。沒關系我們完全可以通過一個加強算法來改變當前的分值情況,也就是說當電腦或玩家有三個子或四個子連成一線時,我們通過加強算法將當前與三個子或四個子有關的空格的分值提高,從而可以彌補這一缺憾。 四、攻擊與防守 以上的方式,事實上計算機只是計算出了最佳的攻擊位置,為了防守我們還應計算當前玩家的最佳的攻擊位置。這樣有什么用呢?道理很簡單,如果玩家最佳攻擊位置的分數(shù)大于計算機最佳攻擊位置上的分數(shù),那么計算機就將下一步的棋子擺在玩家的最佳攻擊位上以阻止玩家的進攻,否則計算機便將棋子下在自己的最佳攻擊位置上進行攻擊。 事實上,這個AI構想是很強大的如果你不是很厲害的五子棋高手的話,可能很快會被計算機打敗。我在聯(lián)眾上可是中級棋手啊,跟這種構想打的時候勝率也不是很高。 使用vb.net編寫五子棋 一、編寫前的準備: 1、用計算機的思想描述整個下棋的過程 考慮步驟: (1)為了簡便我們可以先讓電腦先走第一步棋,電腦每走一步就會封掉許多玩家的獲勝可能情況。 (2)當玩家走棋的時候我們首先應該考慮玩家走棋的合法性。 (3)如果合法,那么玩家也會封掉許多電腦的獲勝的可能情況。 (4)電腦的思考路徑:首先判斷當前玩家和電腦的所有獲勝組合是否需要進行加強賦值,
是進行加強賦值,否則進行普通的賦值。 (5)比較當前玩家和電腦誰的分值最大。將分值最大的點作為電腦的下一步走法。 2、利用vb.net窗體和圖形工具建立五子棋的棋盤界面 (1)添加一個picturebox控件 作用:使用picturebox控件繪制棋子和棋盤 (2)添加一個label控件 作用:顯示當前的獲勝標志,也就是當某一方獲勝或和棋時顯示此標簽。 (3)添加一個mainmenu控件 作用:控制游戲的開始或結束 (4)添加一個mediaplay組件 作用:使程序可以播放音樂。 3、設置整體框價 我們采取10*10的棋盤,為主要的平臺。利用數(shù)組定義整個棋盤桌面,利用數(shù)組定義獲勝組合以及獲勝標志等。 二,聲明全局數(shù)組和變量 定義虛擬桌面: Dim table(9, 9) As Integer 定義當前玩家桌面空格的分數(shù): Dim pscore(9, 9) As Integer 定義當前電腦桌面空格的分數(shù): Dim cscore(9, 9) As Integer 定義玩家的獲勝組合: Dim pwin(9, 9, 191) As Boolean 定義電腦的獲勝組合: Dim cwin(9, 9, 191) As Boolean 定義玩家的獲勝組合標志: Dim pflag(191) As Boolean 定義電腦的獲勝組合標志:
Dim cflag(191) As Boolean 定義游戲有效標志: Dim theplayflag As Boolean 三、初始化游戲 '*****************************************************************************
'** 模塊名稱: initplayenvironment
'**
'** 描述: 此函數(shù)主要功能如下:
'** 1. 設置背景音樂。
'** 2. 設置游戲狀態(tài)有效。
'** 3. 初始化游戲狀態(tài)標簽。
'** 4. 直接指定電腦的第一步走法。
'** 5. 初始化基本得分桌面。
'** 6. 電腦和玩家獲勝標志初始化。
'** 7. 初始化所有獲勝組合。
'** 8. 重新設定玩家的獲勝標志。
'**
'*****************************************************************************
Sub initplayenvironment()
player.FileName = ".\music\zhyu01.mid"
player.Play()
theplayflag = True
'游戲有效
Label1.Visible = False
'游戲狀態(tài)標簽不顯示
PictureBox1.Refresh()
'清空picturebox1的內(nèi)容
yuandian(130, 130)
'調(diào)用繪圖函數(shù)繪制當前電腦先走的位置
Dim i, j, m, n As Integer
For i = 0 To 9
For j = 0 To 9
table(i, j) = 0
Next
Next
'桌面初始化
For i = 0 To 191
pflag(i) = True
cflag(i) = True
Next
'獲勝標志初始化
table(4, 4) = 1
'由于我們設定電腦先手,并下了4,4位所以將其值設為1
''' ******** 初始化獲勝組合 ********
n = 0
For i = 0 To 9
For j = 0 To 5
For m = 0 To 4
pwin(j + m, i, n) = True
cwin(j + m, i, n) = True
Next
n = n + 1
Next
Next
For i = 0 To 9
For j = 0 To 5
For m = 0 To 4
pwin(i, j + m, n) = True
cwin(i, j + m, n) = True
Next
n = n + 1
Next
Next
For i = 0 To 5
For j = 0 To 5
For m = 0 To 4
pwin(j + m, i + m, n) = True
cwin(j + m, i + m, n) = True
Next
n = n + 1
Next
Next
For i = 0 To 5
For j = 9 To 4 Step -1
For m = 0 To 4
pwin(j - m, i + m, n) = True
cwin(j - m, i + m, n) = True
Next
n = n + 1
Next
Next
''' ******** 初始化獲勝組合結束 ********
For i = 0 To 191
If pwin(4, 4, i) = True Then
pflag(i) = False
End If
Next
'由于電腦已下了4,4位所以我們需要重新設定玩家的獲勝標志
End Sub
四,處理鼠標事件 '*****************************************************************************
'** 模塊名稱: themousedown
'**
'** 描述: 此函數(shù)主要實行以下功能:
'** 1. 判定當前游戲標志是否有效。
'** 2. 將實際坐標轉化成虛擬坐標。
'** 3. 繪制玩家的棋子。
'** 4. 執(zhí)行檢查獲勝函數(shù)。
'** 5. 執(zhí)行電腦算法函數(shù)。
'**
'*****************************************************************************
Sub themousedown(ByVal x As Integer, ByVal y As Integer)
If theplayflag = False Then
Exit Sub
End If
'檢查游戲狀態(tài)是否有效
Dim i, j As Integer
Dim zhx, zhy As Integer
zhx = Int((x - 10) / 30)
zhy = Int((y - 10) / 30)
For i = 0 To 9
For j = 0 To 9
If table(zhx, zhy) 0 Then
Exit Sub
End If
Next
Next
'檢查當前鼠標點擊的格子是否有效
Dim mycolor As Color
Dim g As System.Drawing.Graphics
g = PictureBox1.CreateGraphics
mycolor = Color.White
Dim brush1 As System.Drawing.Brush = New SolidBrush(mycolor)
g.FillEllipse(brush1, zhx * 30 + 10, zhy * 30 + 10, 30, 30)
'繪制玩家的棋子
table(zhx, zhy) = 2
For i = 0 To 191
If cwin(zhx, zhy, i) = True Then
cflag(i) = False
End If
Next
'重設電腦的獲勝標志
checkwin()
'檢查當前玩家是否獲勝
diannao()
'調(diào)用電腦算法
End Sub 五、獲勝檢查算法。 '*****************************************************************************
'** 模塊名稱: checkwin
'**
'** 描述: 此模塊執(zhí)行以下功能:
'** 1. 檢查是否和棋。
'** 2. 檢查電腦是否獲勝。
'** 3. 檢查玩家是否獲勝。
'**
'*****************************************************************************
Sub checkwin()
Dim i, j, k, m, n As Integer
Dim ca As Integer
Dim pa As Integer
Dim cnormal As Integer = 0
For i = 0 To 191
If cflag(i) = False Then
cnormal = cnormal + 1
End If
Next
If cnormal = 190 Then
Label1.Visible = True
Label1.Text = "和棋,請重新開始!"
PictureBox1.Refresh()
theplayflag = False
Exit Sub
End If
'設定和棋規(guī)則
For i = 0 To 191
If cflag(i) = True Then
ca = 0
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 1 Then
If cwin(j, k, i) = True Then
ca = ca + 1
End If
End If
Next
Next
If ca = 5 Then
Label1.Visible = True
Label1.Text = "電腦獲勝,請重新開始"
PictureBox1.Refresh()
theplayflag = False
Exit Sub
End If
End If
Next
'檢查電腦是否獲勝
For i = 0 To 191
If pflag(i) = True Then
pa = 0
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 2 Then
If pwin(j, k, i) = True Then
pa = pa + 1
End If
End If
Next
Next
If pa = 5 Then
Label1.Visible = True
Label1.Text = "玩家獲勝,請重新開始"
PictureBox1.Refresh()
theplayflag = False
Exit Sub
End If
End If
Next
'檢查玩家是否獲勝
End Sub 六、電腦算法 '*****************************************************************************
'** 模塊名稱: diannao
'**
'** 描述: 此程序主要執(zhí)行以下功能:
'** 1. 初始化賦值系統(tǒng)。
'** 2. 賦值加強算法。
'** 3. 計算電腦和玩家的最佳攻擊位。
'** 4. 比較電腦和玩家的最佳攻擊位并決定電腦的最佳策略。
'** 5. 執(zhí)行檢查獲勝函數(shù)。
'**
'***************************************************************************** Sub diannao()
Dim i, j, k, m, n As Integer
Dim dc As Integer
Dim cab As Integer
Dim pab As Integer
For i = 0 To 9
For j = 0 To 9
pscore(i, j) = 0
cscore(i, j) = 0
Next
Next
'初始化賦值數(shù)組
''' ******** 電腦加強算法 ********
For i = 0 To 191
If cflag(i) = True Then
cab = 0
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 1 Then
If cwin(j, k, i) = True Then
cab = cab + 1
End If
End If
Next
Next
Select Case cab
Case 3
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 0 Then
If cwin(m, n, i) = True Then
cscore(m, n) = cscore(m, n) + 5
End If
End If
Next
Next
Case 4
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 0 Then
If cwin(m, n, i) = True Then
yuandian(m * 30 + 10, n * 30 + 10)
table(m, n) = 1
For dc = 0 To 191
If pwin(m, n, dc) = True Then
pflag(dc) = False
checkwin()
Exit Sub
End If
Next
End If
End If
Next
Next
End Select
End If
Next
For i = 0 To 191
If pflag(i) = True Then
pab = 0
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 2 Then
If pwin(j, k, i) = True Then
pab = pab + 1
End If
End If
Next
Next
Select Case pab
Case 3
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 0 Then
If pwin(m, n, i) = True Then
pscore(m, n) = pscore(m, n) + 30
End If
End If
Next
Next
Case 4
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 0 Then
If pwin(m, n, i) = True Then
yuandian(m * 30 + 10, n * 30 + 10)
table(m, n) = 1
For dc = 0 To 191
If pwin(m, n, dc) = True Then
pflag(dc) = False
checkwin()
Exit Sub
End If
Next
End If
End If
Next
Next
End Select
End If
Next
''' ******** 電腦加強算法結束 ******** ' ******** 賦值系統(tǒng) ********
For i = 0 To 191
If cflag(i) = True Then
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 0 Then
If cwin(j, k, i) = True Then
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 1 Then
If cwin(m, n, i) = True Then
cscore(j, k) = cscore(j, k) + 1
End If
End If
Next
Next
End If
End If
Next
Next
End If
Next
For i = 0 To 191
If pflag(i) = True Then
For j = 0 To 9
For k = 0 To 9
If table(j, k) = 0 Then
If pwin(j, k, i) = True Then
For m = 0 To 9
For n = 0 To 9
If table(m, n) = 2 Then
If pwin(m, n, i) = True Then
pscore(j, k) = pscore(j, k) + 1
End If
End If
Next
Next
End If
End If
Next
Next
End If
Next
''' ******** 賦值系統(tǒng)結束 ********
''' ******** 分值比較算法 ********
Dim a, b, c, d As Integer
Dim cs As Integer = 0
Dim ps As Integer = 0
For i = 0 To 9
For j = 0 To 9
If cscore(i, j) cs Then
cs = cscore(i, j)
a = i
b = j
End If
Next
Next
For i = 0 To 9
For j = 0 To 9
If pscore(i, j) ps Then
ps = pscore(i, j)
c = i
d = j
End If
Next
Next
If cs ps Then
yuandian(a * 30 + 10, b * 30 + 10)
table(a, b) = 1
For i = 0 To 191
If pwin(a, b, i) = True Then
pflag(i) = False
End If
Next
Else
yuandian(c * 30 + 10, d * 30 + 10)
table(c, d) = 1
For i = 0 To 191
If pwin(c, d, i) = True Then
pflag(i) = False
End If
Next
End If
''' ******** 分值比較算法結束 ********
checkwin()
End Sub 七、繪制棋子 '*****************************************************************************
'** 模塊名稱: yuandian
'**
'** 描述: 此函數(shù)主要進行電腦棋子的繪制。
'**
'***************************************************************************** Sub yuandian(ByVal x As Integer, ByVal y As Integer)
Dim mycolor As Color
Dim g As System.Drawing.Graphics
g = PictureBox1.CreateGraphics
Dim zhx, zhy As Integer
zhx = Int((x - 10) / 30)
zhy = Int((y - 10) / 30)
mycolor = Color.Black
Dim brush1 As System.Drawing.Brush = New SolidBrush(mycolor)
g.FillEllipse(brush1, zhx * 30 + 10, zhy * 30 + 10, 30, 30)
End Sub
軟糖有一個五子棋源碼,不過是VB.net的。
棋盤是用int[,]二維數(shù)組做的,值為0就是空,1是白方,2是黑方。
落子判斷值是否為0,然后根據(jù)當前玩家的賦值為1或2。
'''?summary
'''?返回玩家能否在棋盤(X,Y)的位置下棋
'''?/summary
'''?param?name="X"橫向坐標/param
'''?param?name="Y"縱向坐標/param
'''?returns如果已經(jīng)有棋子或不在棋盤上,則返回False/returns
'''?remarks本函數(shù)會調(diào)用檢查五子并對檢查結果進行判斷/remarks
Public?Function?下棋(ByVal?X?As?Integer,?ByVal?Y?As?Integer)?As?Boolean
If?棋盤(X,?Y)??0?Then?Return?False
棋盤(X,?Y)?=?M當前玩家
Dim?檢查結果?As?Integer
檢查結果?=?檢查五子(X,?Y)
If?檢查結果??0?Then?玩家獲勝(檢查結果)?Else?交換玩家()
Return?True
End?Function
vbs是解釋執(zhí)行的,在網(wǎng)頁上運行的一般用的是 IE的庫,或者是ASP的庫,直接改后綴那種用的是mscrpt 的庫,所以很多對象是不能通用的
VB.net 編寫的程序當然可以XP上運行,但是要用到.NET的庫,就是要裝相應版本的net framework 才可以運行!
人工智能也就是所謂的AI(Artificial Intelligence) 是一門很抽象的技術 AI程序的編寫不需要依據(jù)任何既定的思考模式或者規(guī)則 尤其是游戲中的AI可以完全依程序設計者本身的思考邏輯制作 我個人認為人工智能的核心應該是使計算機具有自動的處理事件的能力 而我們的所有的研究也應該圍繞著這一方向 主體是策略類的人工智能
策略類人工智能可以說是AI中比較復雜的一種 最常見的策略類AI游戲就是棋盤式游戲 在這類游戲中 通常的策略類AI程序都是使計算機判斷目前狀況下所有可走的棋與可能的獲勝狀況 并計算當前計算機可走棋步的獲勝分數(shù)或者玩家可走棋步的獲勝分數(shù) 然后再決定出一個最佳走法 下面先介紹一下五子棋的AI構想
五子棋的AI構想
有句話叫 當局者迷 旁觀者清 但這句話在由AI所控制的計算機玩家上是不成立的 因為計算機必須知道有那些獲勝方式 并計算出每下一步棋到棋盤上任一格子的獲勝幾率 也就是說 一個完整的五子棋的AI構想必須 能夠知道所有的獲勝組合
建立和使用獲勝表
設定獲勝的分數(shù)
使電腦具有攻擊和防守的能力
一 求五子棋的獲勝組合
在一場五子棋的游戲中 計算機必須要知道有那些的獲勝組合 因此我們必須求得獲勝組合的總數(shù) 我們假定當前的棋盤為 *
( )計算水平方向的獲勝組合數(shù) 每一列的獲勝組合是 共 列 所以水平方向的獲勝組合數(shù)為 * =
( )計算垂直方向的獲勝組合總數(shù) 每一行的獲勝組合是 共 行 則垂直方向的獲勝組合數(shù)為 * =
( )計算正對角線方向的獲勝組合總數(shù) 正對角線上的獲勝組合總數(shù)為
+( + + + + )* =
( )計算反對角線方向的獲勝組合總數(shù) 反對角線上的獲勝組合總數(shù)為?? +( + + + + )* = 這樣所有的獲勝組合數(shù)為 + + + =
二 建立和使用獲勝表
我們已經(jīng)計算出了一個 * 的五子棋盤會有 種獲勝方式 這樣我們可以利用數(shù)組建立獲勝表 獲勝表的主要作用是 判斷當前的獲勝方式是否有效 判斷當前的獲勝方式中到底有多少子落入該獲勝組合中 詳細的使用您將在后面的程序中可以看出
三 分數(shù)的設定
在游戲中為了讓計算機能夠決定下一步最佳的走法 必須先計算出計算機下到棋盤上任一空格的分數(shù) 而其中最高分數(shù)便是計算機下一步的最佳走法
原理 我們判定當前討論的空格與當前討論的點有幾種獲勝的方式 有幾種該空格就加幾分 這種原理初聽起來似乎是無法入手 沒關系 當您了解我們后面的程序后您就會明白這種決策原理了
這種決策有一些缺陷 因為如果只根據(jù)這個模型設計 就有可能出現(xiàn)電腦或玩家有三個子連成一線的時候 計算機卻判斷不出 它認為其他某些空格是當前的獲勝的最佳位置而不去攻擊或防守 沒關系我們完全可以通過一個加強算法來改變當前的分值情況 也就是說當電腦或玩家有三個子或四個子連成一線時 我們通過加強算法將當前與三個子或四個子有關的空格的分值提高 從而可以彌補這一缺憾
四 攻擊與防守
以上的方式 事實上計算機只是計算出了最佳的攻擊位置 為了防守我們還應計算當前玩家的最佳的攻擊位置 這樣有什么用呢?道理很簡單 如果玩家最佳攻擊位置的分數(shù)大于計算機最佳攻擊位置上的分數(shù) 那么計算機就將下一步的棋子擺在玩家的最佳攻擊位上以阻止玩家的進攻 否則計算機便將棋子下在自己的最佳攻擊位置上進行攻擊
事實上 這個AI構想是很強大的如果你不是很厲害的五子棋高手的話 可能很快會被計算機打敗 我在聯(lián)眾上可是中級棋手啊 跟這種構想打的時候勝率也不是很高
使用編寫五子棋
一 編寫前的準備
用計算機的思想描述整個下棋的過程
考慮步驟
( )為了簡便我們可以先讓電腦先走第一步棋 電腦每走一步就會封掉許多玩家的獲勝可能情況
( )當玩家走棋的時候我們首先應該考慮玩家走棋的合法性
( )如果合法 那么玩家也會封掉許多電腦的獲勝的可能情況
( )電腦的思考路徑 首先判斷當前玩家和電腦的所有獲勝組合是否需要進行加強賦值 是進行加強賦值 否則進行普通的賦值
( )比較當前玩家和電腦誰的分值最大 將分值最大的點作為電腦的下一步走法
利用窗體和圖形工具建立五子棋的棋盤界面
( )添加一個picturebox控件
作用 使用picturebox控件繪制棋子和棋盤
( )添加一個label控件
作用 顯示當前的獲勝標志 也就是當某一方獲勝或和棋時顯示此標簽
( )添加一個mainmenu控件
作用 控制游戲的開始或結束
( )添加一個mediaplay組件
作用 使程序可以播放音樂
設置整體框價
我們采取 * 的棋盤 為主要的平臺 利用數(shù)組定義整個棋盤桌面 利用數(shù)組定義獲勝組合以及獲勝標志等
二 聲明全局數(shù)組和變量
定義虛擬桌面
Dim table( ) As Integer定義當前玩家桌面空格的分數(shù)
Dim pscore( ) As Integer定義當前電腦桌面空格的分數(shù)
Dim cscore( ) As Integer定義玩家的獲勝組合
Dim pwin( ) As Boolean定義電腦的獲勝組合
Dim cwin( ) As Boolean定義玩家的獲勝組合標志
Dim pflag( ) As Boolean定義電腦的獲勝組合標志
Dim cflag( ) As Boolean定義游戲有效標志
lishixinzhi/Article/program/ASP/201311/21668