您的位置:首页 > 大数据 > 人工智能

使用vb.net实现五子棋的人工智能五子棋的AI构想

2004-12-23 14:32 691 查看
五子棋的人工智能
———— 利用策略类AI和vb.net实现五子棋
作者:张宇
引言
人工智能也就是所谓的AI(Artificial Intelligence),它是一门很抽象的技术,AI程序的编写不需要依据任何既定的思考模式或者规则。尤其是游戏中的AI可以完全依程序设计者本身的思考逻辑制作。我个人认为人工智能的核心应该是使计算机具有自动的处理事件的能力,而我们的所有的研究也应该围绕着这一方向。我们今天讨论的是策略类的人工智能。
策略类人工智能可以说是AI中比较复杂的一种,最常见的策略类AI游戏就是棋盘式游戏。在这类游戏中,通常的策略类AI程序都是使计算机判断目前状况下所有可走的棋与可能的获胜状况,并计算当前计算机可走棋步的获胜分数或者玩家可走棋步的获胜分数,然后再决定出一个最佳走法。下面我们先介绍一下五子棋的AI构想。
第一部分 五子棋的AI构想
有句话叫“当局者迷,旁观者清。”,但这句话在由AI所控制的计算机玩家上是不成立的,因为计算机必须知道有那些获胜方式,并计算出每下一步棋到棋盘上任一格子的获胜几率,也就是说,一个完整的五子棋的AI构想必须:1,能够知道所有的获胜组合,2,建立和使用获胜表,3,设定获胜的分数,4,使电脑具有攻击和防守的能力。
一,求五子棋的获胜组合
在一场五子棋的游戏中,计算机必须要知道有那些的获胜组合,因此我们必须求得
获胜组合的总数。我们假定当前的棋盘为10*10。
(1),计算水平方向的获胜组合数,每一列的获胜组合是:6,共10列,所以水平方向的获胜组合数为:6*10=60
(2),计算垂直方向的获胜组合总数,每一行的获胜组合是:6,共10行,则垂直方向的获胜组合数为:6*10=60
(3),计算正对角线方向的获胜组合总数,正对角线上的获胜组合总数为6+(5+4+3+2+1)*2=36
(4),计算反对角线方向的获胜组合总数,反对角线上的获胜组合总数为6+(5+4+3+2+1)*2=36
这样所有的获胜组合数为:60+60+36+36=192
二,建立和使用获胜表
我们已经计算出了一个10*10

第二部分 使用vb.net编写五子棋
一,编写前的准备:
1, 用计算机的思想描述整个下棋的过程。
考虑步骤:
(1)为了简便我们可以先让电脑先走第一步棋,电脑每走一步就会封掉许多玩家的获胜可能情况。
(2)当玩家走棋的时候我们首先应该考虑玩家走棋的合法性。
(3)如果合法,那么玩家也会封掉许多电脑的获胜的可能情况。
(4)电脑的思考路径:首先判断当前玩家和电脑的所有获胜组合是否需要进行加强赋值,
是进行加强赋值,否则进行普通的赋值。
(5)比较当前玩家和电脑谁的分值最大。将分值最大的点作为电脑的下一步走法。
2, 利用vb.net窗体和图形工具建立五子棋的棋盘界面。
(1)添加一个picturebox控件。
作用:使用picturebox控件绘制棋子和棋盘
(2)添加一个label控件。
作用:显示当前的获胜标志,也就是当某一方获胜或和棋时显示此标签。
(3)添加一个mainmenu控件。
作用:控制游戏的开始或结束。
(4)添加一个mediaplay组件。
作用:使程序可以播放音乐。
3,设置整体框价
我们采取10*10的棋盘,为主要的平台。利用数组定义整个棋盘桌面,利用数组定义获胜组合以及获胜标志等。
二,声明全局数组和变量
定义虚拟桌面:
Dim table(9, 9) As Integer
定义当前玩家桌面空格的分数:
Dim pscore(9, 9) As Integer
定义当前电脑桌面空格的分数:
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
'**
'** 描述: 此函数主要功能如下:
'** 1. 设置背景音乐。
'** 2. 设置游戏状态有效。
'** 3. 初始化游戏状态标签。
'** 4. 直接指定电脑的第一步走法。
'** 5. 初始化基本得分桌面。
'** 6. 电脑和玩家获胜标志初始化。
'** 7. 初始化所有获胜组合。
'** 8. 重新设定玩家的获胜标志。
'**
'*****************************************************************************
Sub initplayenvironment()
player.FileName = "./music/zhyu01.mid"
player.Play()
theplayflag = True
'游戏有效
Label1.Visible = False
'游戏状态标签不显示
PictureBox1.Refresh()
'清空picturebox1的内容
yuandian(130, 130)
'调用绘图函数绘制当前电脑先走的位置
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

四,处理鼠标事件
'*****************************************************************************
'** 模块名称: themousedown
'**
'** 描述: 此函数主要实行以下功能:
'** 1. 判定当前游戏标志是否有效。
'** 2. 将实际坐标转化成虚拟坐标。
'** 3. 绘制玩家的棋子。
'** 4. 执行检查获胜函数。
'** 5. 执行电脑算法函数。
'**
'*****************************************************************************
Sub themousedown(ByVal x As Integer, ByVal y As Integer)
If theplayflag = False Then
Exit Sub
End If
'检查游戏状态是否有效
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()
'调用电脑算法
End Sub
五,获胜检查算法。
'*****************************************************************************
'** 模块名称: checkwin
'**
'** 描述: 此模块执行以下功能:
'** 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
'设定和棋规则
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六,电脑算法(1)
'*****************************************************************************
'** 模块名称: diannao
'**
'** 描述: 此程序主要执行以下功能:
'** 1. 初始化赋值系统。
'** 2. 赋值加强算法。
'** 3. 计算电脑和玩家的最佳攻击位。
'** 4. 比较电脑和玩家的最佳攻击位并决定电脑的最佳策略。
'** 5. 执行检查获胜函数。
'**
'*****************************************************************************

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
'初始化赋值数组
''' ******** 电脑加强算法 ********
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

六电脑算法(2)
''' ******** 赋值系统 ********
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
''' ******** 赋值系统结束 ********
''' ******** 分值比较算法 ********
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: