今天搞趣網小編為大家帶來我的世界五子棋AI怎麼做,下面小編為大家詳細講解我的世界五子棋AI制作教程,希望對大家有所幫助。
五子棋,作為一個擁有着先手必勝屬性的棋類,實際上是不公平的,就算是後人給加上了禁手,換子這樣的規則,先手依舊有着極大的優勢。正是因為這樣的不公平,五子棋的AI早就可以啪啪啪打死人類幾條街了,因為機器隻要是先手,就很容易推導出必勝下法。今天我帶來的五子棋AI,是一個無禁手的後手AI,理論上基本上是不能下赢人類的,不過你要是被這個AI下赢了的話,這輩子我推薦你不要再碰五子棋了。 那麼,閑談也就先告一段落,接下來來具體說說思路與方法。這裡附帶兩張被奕心吊打的棋局,奕心被限制在深度探索兩層,而這個ai沒有深度探索,所以不被吊打才不正常。
一、思路。
對于整個五子棋AI來說,玩家隻會在意兩點,時間和棋力。我們的目标是計算時間消耗更短,且棋力達到不會很蠢的地步。
網上所能找到的大多數五子棋AI,都有着這樣的特征,也就是每次局面更新的時候,都會對棋盤進行一次遍曆估值,或許對于别的平台或者别的語言來說,這并沒有什麼問題,但是,如果我們需要用mc來進行編寫的話,第一道難關就是mojang的辣雞優化。事實證明,每次對局面遍曆一次都将極大程度的延長計算時間。那麼我們的首要目标就是,通過代碼的優化來彌補這以先天不足。對于五子棋AI來說,則是減少需要讀寫的範圍。這裡也有大量的AI将遍曆區域縮小至棋子的周圍四格,這是很合理并且很容易執行的策略,這将是核心思路之一。
在時間壓縮下來後,我們需要提高AI的棋力,通常市面上的解法是博弈樹,但是這往往對于我們來說是無法忍受的,因為博弈樹就代表深度探索,不僅要遍曆棋局,更要遍曆各種可能性,這就代表着時間将呈指數級别的延長。就算是一些高優化的AI,對于一些局面的探索也會需要幾十秒甚至幾分鐘的計算,同樣的計算量放在mc裡就有可能需要幾小時甚至幾天來運行,那麼這樣的一個AI是沒有意義的。同樣的,mc對于變量的管理方式雖然不至于像前幾個版本那樣貧瘠,但是也是遠遠不能達到一般程序的需求的,所謂在夾縫中求生存嘛。
那麼我們隻有僅進行當前局面估值,完全放棄可能性計算。這也就代表了第一層的下法得盡可能的好。此外,經過實驗證明,過于頻繁的棋型判斷也會造成極大程度的延時,所以這一點我們也得盡可能的壓縮。
二,實際演練。
提前說一下,下子以及勝利判定之類的可替換操作我就不深入來說了,因為畢竟可替換也就是說有一萬種方法來實現,能看懂這篇文章的也就代表能夠自己制作出來了,所以篇幅留給核心算法。因為是要求快速的算法,所以基本上是簡約不簡單。
棋盤規格是19*19。以下這些不要問我為啥不用代碼格式而用引用格式,被吞無數次,這是不得已的下策。
x
y
l
h 以上四個計分闆是屬于每個格子的固有屬性,是代表着這個格子的行,列,以及第幾條斜線,所存儲的值是絕對不會更改的。
xc
yc
lc
hc以上四個是用來計算落子點與該格的行列差值的,0代表和落子點處于同一行。
b1
b2
b3
b4
w1
w2
w3
w4以上八個計分闆是用來存儲各個方向上的權值的。b代表防守,w代表進攻,下同。在開局時會根據格子位置給予一個微小的初始量,如最中間的是10,最外圍的是1。
b01 =b1 b2
b02 =b1 b3
b03 =b1 b4
b04 =b2 b3
b05 =b2 b4
b06 =b3 b4
w01
w02
w03
w04
w05
w06 以上12個計分闆僅用來做取最大值的中間計分闆。緩存用。
以上是我全部的計分闆。
接下來來從指令層面講解整體的流程。有關于一些特定棋型的判斷就是通過疊加execute然後探測方塊實現的,難是不難,就是很卡,所以為了防止你們想不到更好的答案,我這裡就講到這裡。補充:如出現必須堵上的點會給這個點一個high的tag标記。
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] xc = @e[type=ArmorStand,c=1,r=0] x
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] yc = @e[type=ArmorStand,c=1,r=0] y
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] hc = @e[type=ArmorStand,c=1,r=0] h
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] lc = @e[type=ArmorStand,c=1,r=0] l
以上四條是為了給每個單元的計算計分闆讀取所在的坐标值。
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] xc -= @e[name=b,c=1] x
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] yc -= @e[name=b,c=1] y
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] hc -= @e[name=b,c=1] h
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] lc -= @e[name=b,c=1] l
以上四條是計算該點與剛剛落子的那一點的坐标差值,0即代表是和落子位處于同一斜線。
execute @e[name=b] ~ ~ ~ scoreboard players add @e[r=6,score_yc=0,score_yc_min=0,name=o,score_b2=4100] b2 1300
execute @e[name=b] ~ ~ ~ scoreboard players add @e[r=6,score_xc=0,score_xc_min=0,name=o,score_b1=4100] b1 1300
execute @e[name=b] ~ ~ ~ scoreboard players add @e[r=4,score_hc=0,score_hc_min=0,name=o,score_b4=4100] b4 1300
execute @e[name=b] ~ ~ ~ scoreboard players add @e[r=4,score_lc=0,score_lc_min=0,name=o,score_b3=4100] b3 1300
execute @e[name=b] ~ ~ ~ scoreboard players remove @e[r=6,score_yc=0,score_yc_min=0,name=o,score_w2=4100] w2 1000
execute @e[name=b] ~ ~ ~ scoreboard players remove @e[r=6,score_xc=0,score_xc_min=0,name=o,score_w1=4100] w1 1000
execute @e[name=b] ~ ~ ~ scoreboard players remove @e[r=4,score_hc=0,score_hc_min=0,name=o,score_w4=4100] w4 1000
execute @e[name=b] ~ ~ ~ scoreboard players remove @e[r=4,score_lc=0,score_lc_min=0,name=o,score_wl=4100] w3 1000
這裡是落子點對周圍處在統一斜線上的空位權值的修正,這樣每次最多隻需要重新修改32個位置的權值,比重新遍曆一遍棋盤不知道高到哪裡去了。然後注意的是,防守的權值修正高于進攻權值修正,因為,反正後手劣勢,不如以防守為主。這樣的偏差雖然會導緻一點微小的差錯,但是基本上是難以預料到這一點的。
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] b01 = @e[type=ArmorStand,c=1,r=0] b1
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] b01 = @e[type=ArmorStand,c=1,r=0] b2
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] b02 = @e[type=ArmorStand,c=1,r=0] b1
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] b02 = @e[type=ArmorStand,c=1,r=0] b3
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] b03 = @e[type=ArmorStand,c=1,r=0] b1
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] b03 = @e[type=ArmorStand,c=1,r=0] b4
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] b04 = @e[type=ArmorStand,c=1,r=0] b2
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] b04 = @e[type=ArmorStand,c=1,r=0] b3
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] b05 = @e[type=ArmorStand,c=1,r=0] b2
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] b05 = @e[type=ArmorStand,c=1,r=0] b4
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] b06 = @e[type=ArmorStand,c=1,r=0] b3
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] b06 = @e[type=ArmorStand,c=1,r=0] b4
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] w01 = @e[type=ArmorStand,c=1,r=0] w1
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] w01 = @e[type=ArmorStand,c=1,r=0] w2
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] w02 = @e[type=ArmorStand,c=1,r=0] w1
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] w02 = @e[type=ArmorStand,c=1,r=0] w3
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] w03 = @e[type=ArmorStand,c=1,r=0] w1
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] w03 = @e[type=ArmorStand,c=1,r=0] w4
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] w04 = @e[type=ArmorStand,c=1,r=0] w2
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] w04 = @e[type=ArmorStand,c=1,r=0] w3
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] w05 = @e[type=ArmorStand,c=1,r=0] w2
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] w05 = @e[type=ArmorStand,c=1,r=0] w4
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] w06 = @e[type=ArmorStand,c=1,r=0] w3
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] w06 = @e[type=ArmorStand,c=1,r=0] w4
這裡是計算出之前結構的12個估值變量,注意,是每個格子都擁有各自的12個變量。
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] b01 > @e[type=ArmorStand,c=1,r=0] b02
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] b01 > @e[type=ArmorStand,c=1,r=0] b03
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] b01 > @e[type=ArmorStand,c=1,r=0] b04
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] b01 > @e[type=ArmorStand,c=1,r=0] b05
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] b01 > @e[type=ArmorStand,c=1,r=0] b06
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] w01 > @e[type=ArmorStand,c=1,r=0] w02
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] w01 > @e[type=ArmorStand,c=1,r=0] w03
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] w01 > @e[type=ArmorStand,c=1,r=0] w04
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] w01 > @e[type=ArmorStand,c=1,r=0] w05
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] w01 > @e[type=ArmorStand,c=1,r=0] w06
entitydata @e[name=b] {CustomName:"a"}
每個格子都選出自己最大的當前權值。
execute @e[tag=Start,name=!a] ~ ~ ~ /scoreboard players operation @e[type=ArmorStand,c=1,r=0] w01 > @e[type=ArmorStand,c=1,r=0] b01
判斷進攻權值是否大于防禦權值,取二者最大值。
scoreboard players add @e[name=o,tag=high] w01 2000
判斷這個點是否是需要被特殊照顧一下,如果是,進一步加大權值。
/scoreboard players operation @e[tag=head,c=1] x > @e[tag=Start,name=o] w01
/scoreboard players operation @e[tag=Start,name=o] w01 -= @e[tag=head,c=1] x
entitydata @r[type=ArmorStand,score_w01_min=0,c=1,name=o] {CustomName:"b"}
選出擁有最大權值的格子,并給予落子标簽。
execute @e[tag=Start,name=b] ~ ~ ~ setblock ~ ~1 ~ stained_glass 0
落子!
execute @e[name=b] ~ ~ ~ scoreboard players remove @e[r=6,score_yc=0,score_yc_min=0,name=o,score_b2=4100] b2 1300
execute @e[name=b] ~ ~ ~ scoreboard players remove @e[r=6,score_xc=0,score_xc_min=0,name=o,score_b1=4100] b1 1300
execute @e[name=b] ~ ~ ~ scoreboard players remove @e[r=4,score_hc=0,score_hc_min=0,name=o,score_b4=4100] b4 1300
execute @e[name=b] ~ ~ ~ scoreboard players remove @e[r=4,score_lc=0,score_lc_min=0,name=o,score_b3=4100] b3 1300
execute @e[name=b] ~ ~ ~ scoreboard players add @e[r=6,score_yc=0,score_yc_min=0,name=o,score_w2=4100] w2 1000
execute @e[name=b] ~ ~ ~ scoreboard players add @e[r=6,score_xc=0,score_xc_min=0,name=o,score_w1=4100] w1 1000
execute @e[name=b] ~ ~ ~ scoreboard players add @e[r=4,score_hc=0,score_hc_min=0,name=o,score_w4=4100] w4 1000
execute @e[name=b] ~ ~ ~ scoreboard players add @e[r=4,score_lc=0,score_lc_min=0,name=o,score_w3=4100] w3 1000
與之前相同的權值修正。
entitydata @e[name=b] {CustomName:"a"}将落子點的标記修正成已落子的标記。
/scoreboard players set @e[tag=head,c=1] x 0
清理最優解緩存。
以上就是搞趣網小編為您帶來的我的世界五子棋AI怎麼做,希望看後對您有所幫助。
小編推薦:
我的世界0.14.0版本更新大全
我的世界0.14.0下載
簡易歐式房子建造教程
水車 水井建造教程
我的世界0.15.0更新内容彙總
我的世界0.14.0紅石教程大全
我的世界故事模式第五章全劇情攻略
服務器彙總 | 解說視頻 |
新手攻略 | 紅石教程 |
我的世界手機版攻略大全 | |||
我的世界熱門攻略合集 | |||
載具合集 | 建築合集 | 房子設計圖 | 紅石大全 |
槍械大全 | 附魔大全 | 家具大全 | |
我的世界0.14.0更新内容彙總 | |||
中繼器 | 漏鬥 | 投擲器 | 發射器 |
比較器 | 物品展示框 | 地圖 | 附魔台 |
TNT礦車 | 運輸礦車 | 漏鬥礦車 | 大型陷阱箱 |
沼澤小屋 | 煉藥鍋 | 雞騎士 | 女巫 |
0.10.5資源大全 | 0.11.0資源大全 | ||
皮膚 | 材質包 | 皮膚 | 材質包 |
地圖存檔 | 建築存檔 | 地圖存檔 | 建築存檔 |
js下載 | 遊戲下載 | js下載 | 遊戲下載 |
0.12.0資源大全 | 0.13.0資源大全 | ||
皮膚 | 材質包 | 皮膚 | 材質包 |
地圖存檔 | 建築存檔 | 地圖存檔 | 建築存檔 |
js下載 | 遊戲下載 | js下載 | 遊戲下載 |
0.14.0資源大全 | 0.15.0資源大全 | ||
皮膚 | 材質包 | 皮膚 | 材質包 |
地圖存檔 | 建築存檔 | 地圖存檔 | 建築存檔 |
js下載 | 遊戲下載 | js下載 | 遊戲下載 |
我的世界pc版攻略大全 | |||
1.6資源大全 | 1.7資源大全 | ||
皮膚 | 材質包 | 皮膚 | 材質包 |
地圖存檔 | 建築存檔 | 地圖存檔 | 建築存檔 |
mod下載 | 遊戲下載 | mod下載 | 遊戲下載 |
1.8資源大全 | 1.9資源大全 | ||
皮膚 | 材質包 | 皮膚 | 材質包 |
地圖存檔 | 建築存檔 | 地圖存檔 | 建築存檔 |
mod下載 | 遊戲下載 | mod下載 | 遊戲下載 |
下載更多我的世界攻略,敬請關注搞趣網我的世界專區。
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!