国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

VB.NET實現五子棋的人工智能

2024-07-10 13:00:47
字體:
來源:轉載
供稿:網友
vb.net實現五子棋的人工智能

人工智能也就是所謂的ai(artificial intelligence),是一門很抽象的技術,ai程序的編寫不需要依據任何既定的思考模式或者規則。尤其是游戲中的ai可以完全依程序設計者本身的思考邏輯制作。我個人認為人工智能的核心應該是使計算機具有自動的處理事件的能力,而我們的所有的研究也應該圍繞著這一方向。主體是策略類的人工智能。
策略類人工智能可以說是ai中比較復雜的一種,最常見的策略類ai游戲就是棋盤式游戲。在這類游戲中,通常的策略類ai程序都是使計算機判斷目前狀況下所有可走的棋與可能的獲勝狀況,并計算當前計算機可走棋步的獲勝分數或者玩家可走棋步的獲勝分數,然后再決定出一個最佳走法。下面先介紹一下五子棋的ai構想。

五子棋的ai構想

  有句話叫“當局者迷,旁觀者清?!保@句話在由ai所控制的計算機玩家上是不成立的,因為計算機必須知道有那些獲勝方式,并計算出每下一步棋到棋盤上任一格子的獲勝幾率,也就是說,一個完整的五子棋的ai構想必須:
 
  1、能夠知道所有的獲勝組合;

  2、建立和使用獲勝表;

  3、設定獲勝的分數;

  4、使電腦具有攻擊和防守的能力;

  一、求五子棋的獲勝組合

  在一場五子棋的游戲中,計算機必須要知道有那些的獲勝組合,因此我們必須求得獲勝組合的總數。我們假定當前的棋盤為10*10。

 ?。?)計算水平方向的獲勝組合數,每一列的獲勝組合是:6,共10列,所以水平方向的獲勝組合數為:6*10=60

 ?。?)計算垂直方向的獲勝組合總數,每一行的獲勝組合是:6,共10行,則垂直方向的獲勝組合數為:6*10=60

 ?。?)計算正對角線方向的獲勝組合總數,正對角線上的獲勝組合總數為
6+(5+4+3+2+1)*2=36

 ?。?)計算反對角線方向的獲勝組合總數,反對角線上的獲勝組合總數為
6+(5+4+3+2+1)*2=36 ,這樣所有的獲勝組合數為:60+60+36+36=192

  二、建立和使用獲勝表

  我們已經計算出了一個10*10的五子棋盤會有192種獲勝方式,這樣我們可以利用數組建立獲勝表,獲勝表的主要作用是:1,判斷當前的獲勝方式是否有效;2,判斷當前的獲勝方式中到底有多少子落入該獲勝組合中。詳細的使用您將在后面的程序中可以看出。

  三,分數的設定

  在游戲中為了讓計算機能夠決定下一步最佳的走法,必須先計算出計算機下到棋盤上任一空格的分數,而其中最高分數便是計算機下一步的最佳走法。

  原理:我們判定當前討論的空格與當前討論的點有幾種獲勝的方式,有幾種該空格就加幾分。這種原理初聽起來似乎是無法入手,沒關系,當您了解我們后面的程序后您就會明白這種決策原理了。

  這種決策有一些缺陷,因為如果只根據這個模型設計,就有可能出現電腦或玩家有三個子連成一線的時候,計算機卻判斷不出,它認為其他某些空格是當前的獲勝的最佳位置而不去攻擊或防守。沒關系我們完全可以通過一個加強算法來改變當前的分值情況,也就是說當電腦或玩家有三個子或四個子連成一線時,我們通過加強算法將當前與三個子或四個子有關的空格的分值提高,從而可以彌補這一缺憾。

  四、攻擊與防守

  以上的方式,事實上計算機只是計算出了最佳的攻擊位置,為了防守我們還應計算當前玩家的最佳的攻擊位置。這樣有什么用呢?道理很簡單,如果玩家最佳攻擊位置的分數大于計算機最佳攻擊位置上的分數,那么計算機就將下一步的棋子擺在玩家的最佳攻擊位上以阻止玩家的進攻,否則計算機便將棋子下在自己的最佳攻擊位置上進行攻擊。

  事實上,這個ai構想是很強大的如果你不是很厲害的五子棋高手的話,可能很快會被計算機打敗。我在聯眾上可是中級棋手啊,跟這種構想打的時候勝率也不是很高。

使用vb.net編寫五子棋

  一、編寫前的準備:

  1、用計算機的思想描述整個下棋的過程

  考慮步驟:

  (1)為了簡便我們可以先讓電腦先走第一步棋,電腦每走一步就會封掉許多玩家的獲勝可能情況。

  (2)當玩家走棋的時候我們首先應該考慮玩家走棋的合法性。

 ?。?)如果合法,那么玩家也會封掉許多電腦的獲勝的可能情況。

 ?。?)電腦的思考路徑:首先判斷當前玩家和電腦的所有獲勝組合是否需要進行加強賦值,是進行加強賦值,否則進行普通的賦值。

  (5)比較當前玩家和電腦誰的分值最大。將分值最大的點作為電腦的下一步走法。

  2、利用vb.net窗體和圖形工具建立五子棋的棋盤界面

  (1)添加一個picturebox控件

  作用:使用picturebox控件繪制棋子和棋盤

  (2)添加一個label控件

  作用:顯示當前的獲勝標志,也就是當某一方獲勝或和棋時顯示此標簽。

 ?。?)添加一個mainmenu控件

  作用:控制游戲的開始或結束

 ?。?)添加一個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
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
'**
'** 描述: 此函數主要實行以下功能:
'** 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
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
'**
'** 描述: 此程序主要執行以下功能:
'** 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
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
''' ******** 電腦加強算法結束 ********

' ******** 賦值系統 ********
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
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
'**
'** 描述: 此函數主要進行電腦棋子的繪制。
'**
'*****************************************************************************

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







發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 英德市| 岫岩| 庆阳市| 格尔木市| 枣庄市| 陆良县| 小金县| 和静县| 石台县| 南江县| 方城县| 藁城市| 云林县| 定州市| 怀仁县| 道真| 崇文区| 黄大仙区| 房山区| 南汇区| 楚雄市| 阜阳市| 邯郸县| 百色市| 马龙县| 祁连县| 杨浦区| 含山县| 汤原县| 栾川县| 江安县| 治多县| 卢龙县| 洛南县| 榕江县| 天全县| 合水县| 东乌珠穆沁旗| 弋阳县| 和田市| 城市|