國際象棋是一種在棋盤上玩的雙人戰略棋盤游戲,棋盤格式為 64 格,排列在 8×8 網格中。有人無聊的時候會找電腦下國際象棋,但也有人無聊了會教電腦下棋。
國際象棋可以說是最棒的棋盤游戲之一,它是戰略戰術和純技術的完美融合。每位玩家開局時各有 16 枚棋子:一王、一后、兩車、兩馬、兩象和八兵,各具不同功能與走法。真人對弈可以憑借玩家的經驗,步步為營。那么,對于一個機器——計算機,你該如何教會它下棋?近日,有人在 medium 上發表了一篇文章,詳細解釋了如何教計算機玩國際象棋。
本文將從 5 個方面進行介紹:
在開始之前,你只需要提前安裝 Python3。
Board 表示
首先,你需要對棋子背后的邏輯進行編碼,即為每個棋子分配每一次可能的合法移動。
python-chess 庫為我們提供了棋子的移動生成和驗證,簡化了工作,安裝方式如下:
!pip install python-chess
python-chess 庫安裝好后,導入 chess 模塊并進行初始化:
import chess
board=chess.Board()
board
在 notebook 中的輸出如下所示:
board 對象是一個完整的 board 表示,該對象為我們提供了一些重要的函數,例如,board.is_checkmate() 函數檢查是否存在將殺(checkmate),board.push() 函數附加一個移動,board.pop() 函數撤銷最后一次移動等。閱讀完整的文檔請參閱:https://python-chess.readthedocs.io/en/latest/
Board 評估
為了對 board 進行初步評估,必須考慮一位大師在各自比賽中的想法。
我們應該想到的一些要點是:
將上述要點以方程形式進行表達:
通過化簡上述方程,可以得到:象 > 馬 > 3 個兵。同樣,第三個方程可以改寫成:象 + 馬=車 + 1.5 個兵,因為兩個小棋子相當于一個車和兩個兵。
使用 piece square table 來評估棋子,在 8x8 的矩陣中設置值,例如在國際象棋中,在有利的位置設置較高的值,在不利的位置設置較低的值。
例如,白色國王越過中線的概率將小于 20%,因此我們將在該矩陣中將數值設置為負值。
再舉一個例子,假設皇后希望自己被放在中間位置,因為這樣可以控制更多的位置,因此我們將在中心設置更高的值,其他棋子也一樣,因為國際象棋都是為了保衛國王和控制中心。
理論就講這些,現在我們來初始化 piece square table:
pawntable=[
0, 0, 0, 0, 0, 0, 0, 0,
5, 10, 10, -20, -20, 10, 10, 5,
5, -5, -10, 0, 0, -10, -5, 5,
0, 0, 0, 20, 20, 0, 0, 0,
5, 5, 10, 25, 25, 10, 5, 5,
10, 10, 20, 30, 30, 20, 10, 10,
50, 50, 50, 50, 50, 50, 50, 50,
0, 0, 0, 0, 0, 0, 0, 0]
knightstable=[
-50, -40, -30, -30, -30, -30, -40, -50,
-40, -20, 0, 5, 5, 0, -20, -40,
-30, 5, 10, 15, 15, 10, 5, -30,
-30, 0, 15, 20, 20, 15, 0, -30,
-30, 5, 15, 20, 20, 15, 5, -30,
-30, 0, 10, 15, 15, 10, 0, -30,
-40, -20, 0, 0, 0, 0, -20, -40,
-50, -40, -30, -30, -30, -30, -40, -50]
bishopstable=[
-20, -10, -10, -10, -10, -10, -10, -20,
-10, 5, 0, 0, 0, 0, 5, -10,
-10, 10, 10, 10, 10, 10, 10, -10,
-10, 0, 10, 10, 10, 10, 0, -10,
-10, 5, 5, 10, 10, 5, 5, -10,
-10, 0, 5, 10, 10, 5, 0, -10,
-10, 0, 0, 0, 0, 0, 0, -10,
-20, -10, -10, -10, -10, -10, -10, -20]
rookstable=[
0, 0, 0, 5, 5, 0, 0, 0,
-5, 0, 0, 0, 0, 0, 0, -5,
-5, 0, 0, 0, 0, 0, 0, -5,
-5, 0, 0, 0, 0, 0, 0, -5,
-5, 0, 0, 0, 0, 0, 0, -5,
-5, 0, 0, 0, 0, 0, 0, -5,
5, 10, 10, 10, 10, 10, 10, 5,
0, 0, 0, 0, 0, 0, 0, 0]
queenstable=[
-20, -10, -10, -5, -5, -10, -10, -20,
-10, 0, 0, 0, 0, 0, 0, -10,
-10, 5, 5, 5, 5, 5, 0, -10,
0, 0, 5, 5, 5, 5, 0, -5,
-5, 0, 5, 5, 5, 5, 0, -5,
-10, 0, 5, 5, 5, 5, 0, -10,
-10, 0, 0, 0, 0, 0, 0, -10,
-20, -10, -10, -5, -5, -10, -10, -20]
kingstable=[
20, 30, 10, 0, 0, 10, 30, 20,
20, 20, 0, 0, 0, 0, 20, 20,
-10, -20, -20, -20, -20, -20, -20, -10,
-20, -30, -30, -40, -40, -30, -30, -20,
-30, -40, -40, -50, -50, -40, -40, -30,
-30, -40, -40, -50, -50, -40, -40, -30,
-30, -40, -40, -50, -50, -40, -40, -30,
-30, -40, -40, -50, -50, -40, -40, -30]
通過以下四種方法得到評估函數:
第一步檢查游戲是否還在繼續。
這個階段的背后編碼邏輯是:如果它在 checkmate 時返回 true,程序將會檢查輪到哪方移動。如果當前輪到白方移動,返回值為 - 9999,即上次一定是黑方移動,黑色獲勝;否則返回值為 + 9999,表示白色獲勝。對于僵局或比賽材料不足,返回值為 0 以表示平局。
代碼實現方式:
if board.is_checkmate():
if board.turn:
return -9999
else:
return 9999
if board.is_stalemate():
return 0
if board.is_insufficient_material():
return 0
第二步,計算總的棋子數,并把棋子總數傳遞給 material 函數。
wp=len(board.pieces(chess.PAWN, chess.WHITE))
bp=len(board.pieces(chess.PAWN, chess.BLACK))
wn=len(board.pieces(chess.KNIGHT, chess.WHITE))
bn=len(board.pieces(chess.KNIGHT, chess.BLACK))
wb=len(board.pieces(chess.BISHOP, chess.WHITE))
bb=len(board.pieces(chess.BISHOP, chess.BLACK))
wr=len(board.pieces(chess.ROOK, chess.WHITE))
br=len(board.pieces(chess.ROOK, chess.BLACK))
wq=len(board.pieces(chess.QUEEN, chess.WHITE))
bq=len(board.pieces(chess.QUEEN, chess.BLACK))
第三步,計算得分。material 函數得分的計算方法是:用各種棋子的權重乘以該棋子黑白兩方個數之差,然后求這些結果之和。而每種棋子的得分計算方法是:該棋子在該游戲實例中所處位置的 piece-square 值的總和。
material=100 * (wp - bp) + 320 * (wn - bn) + 330 * (wb - bb) + 500 * (wr - br) + 900 * (wq - bq)pawnsq=sum([pawntable[i] for i in board.pieces(chess.PAWN, chess.WHITE)])
pawnsq=pawnsq + sum([-pawntable[chess.square_mirror(i)]
for i in board.pieces(chess.PAWN, chess.BLACK)])knightsq=sum([knightstable[i] for i in board.pieces(chess.KNIGHT, chess.WHITE)])
knightsq=knightsq + sum([-knightstable[chess.square_mirror(i)]
for i in board.pieces(chess.KNIGHT, chess.BLACK)])bishopsq=sum([bishopstable[i] for i in board.pieces(chess.BISHOP, chess.WHITE)])
bishopsq=bishopsq + sum([-bishopstable[chess.square_mirror(i)]
for i in board.pieces(chess.BISHOP, chess.BLACK)])rooksq=sum([rookstable[i] for i in board.pieces(chess.ROOK, chess.WHITE)])
rooksq=rooksq + sum([-rookstable[chess.square_mirror(i)]
for i in board.pieces(chess.ROOK, chess.BLACK)])queensq=sum([queenstable[i] for i in board.pieces(chess.QUEEN, chess.WHITE)])
queensq=queensq + sum([-queenstable[chess.square_mirror(i)]
for i in board.pieces(chess.QUEEN, chess.BLACK)])kingsq=sum([kingstable[i] for i in board.pieces(chess.KING, chess.WHITE)])
kingsq=kingsq + sum([-kingstable[chess.square_mirror(i)]
for i in board.pieces(chess.KING, chess.BLACK)])
第四步,計算評價函數,此時將會返回白棋的 material 得分和各棋子單獨得分之和。
eval=material + pawnsq + knightsq + bishopsq + rooksq + queensq + kingsq
if board.turn:
return eval
else:
return -eval
評價函數流程圖
移動選擇
算法的最后一步是用 Minimax 算法中的 Negamax 實現進行移動選擇,Minimax 算法是雙人游戲(如跳棋等)中的常用算法。之后使用 Alpha-Beta 剪枝進行優化,這樣可以減少執行的時間。
現在讓我們深入研究一下 minimax 算法。該算法被廣泛應用在棋類游戲中,用來找出失敗的最大可能性中的最小值。該算法廣泛應用于人工智能、決策論、博弈論、統計和哲學,力圖在最壞的情況下將損失降到最低。簡單來說,在游戲的每一步,假設玩家 A 試圖最大化獲勝幾率,而在下一步中,玩家 B 試圖最小化玩家 A 獲勝的幾率。
為了更好地理解 minimax 算法,請看下圖:
維基百科中 minimax 樹舉例
為了得到更好的結果,使用 minimax 變體 negamax,因為我們只需要一個最大化兩位玩家效用的函數。不同點在于,一個玩家的損失等于另一個玩家的收獲,反之亦然。
就游戲而言,給第一個玩家的位置值和給第二個玩家的位置值符號是相反的。
negamax 示例
首先,我們將 alpha 設為負無窮大,beta 設為正無窮大,這樣兩位玩家都能以盡可能差的分數開始比賽,代碼如下:
except:
bestMove=chess.Move.null()
bestValue=-99999
alpha=-100000
beta=100000
for move in board.legal_moves:
board.push(move)
boardValue=-alphabeta(-beta, -alpha, depth - 1)
if boardValue > bestValue:
bestValue=boardValue
bestMove=move
if (boardValue > alpha):
alpha=boardValue
board.pop()
return bestMove
下面讓我們以流程圖的方式來解釋:
search 函數的流程圖
下一步是進行 alpha-beta 的剪枝來優化執行速度。
來自維基百科的 alpha-beta 剪枝說明
代碼如下:
def alphabeta(alpha, beta, depthleft): bestscore=-9999 if (depthleft==0): return quiesce(alpha, beta) for move in board.legal_moves: board.push(move) score=-alphabeta(-beta, -alpha, depthleft - 1) board.pop() if (score >=beta): return score if (score > bestscore): bestscore=score if (score > alpha): alpha=score return bestscore
現在,讓我們用下面給出的流程圖來調整 alphabeta 函數:
現在是靜態搜索,這種搜索旨在僅評估靜態位置,即不存在致勝戰術移動的位置。該搜索需要避免由搜索算法的深度限制所引起的水平線效應(horizon effect)。
代碼如下:
def quiesce(alpha, beta):
stand_pat=evaluate_board()
if (stand_pat >=beta):
return beta
if (alpha < stand_pat):
alpha=stand_pat
for move in board.legal_moves:
if board.is_capture(move):
board.push(move)
score=-quiesce(-beta, -alpha)
board.pop()
if (score >=beta):
return beta
if (score > alpha):
alpha=score
return alpha
簡單總結一下 quiesce 函數:
quiesce 函數流程圖。
測試 AI
開始測試前,需要導入一些庫:
測試有 3 項:
1. AI 對弈人類:
AI 選擇從 g1 到 f3,這是一個很明智的選擇。
2. AI 對弈 AI:
3. AI 對弈 Stockfish:
可以得出:AI 還不夠智能,不足以打敗 stockfish 12,但仍然堅持走了 20 步。
接口測試
上述測試方式看起來代碼很多,你也可以寫一個接口測試 AI。
然后執行:
最終輸出
湃新聞記者 吳遇利
Neuralink首位腦機芯片植入受試者已經可以下棋了。
當地時間3月20日,特斯拉CEO埃隆·馬斯克旗下腦機接口公司Neuralink披露了首位腦機芯片植入受試者的最新情況,并表示這位四肢癱瘓的男子已經能夠通過意念玩游戲和在線國際象棋。
視頻顯示,病人Noland Arbaugh能夠使用電腦下國際象棋、玩游戲《文明VI》。他在直播中一邊移動棋子一邊說,“如果你們都能看到光標移動,沒錯,那就是我,這很酷吧?”
病人Noland Arbaugh展示其如何使用意念下國際象棋
Arbaugh描述了自己如何學習使用腦機,“我會嘗試移動我的右手,向左、向右、向前、向后,然后,從那里開始想象光標在移動”。
29歲的Arbaugh說,他八年前在一次“離奇的潛水事故”中脊髓受傷,肩部以下無法活動。在今年1月份進行Neuralink手術后的第二天,他就出院了,手術進展十分順利。不過他補充說,“仍有工作要做”。
Arbaugh說,他覺得自己很幸運能成為Neuralink首位測試者,“它已經改變了我的生活”。
威斯康星大學轉化神經工程研究所聯席主任Kip Allan Ludwig評價說,“我為他感到高興,因為他能夠以植入前無法做到的方式,與電腦進行交互。”針對技術本身,Ludwig表示,“與此前其他人所展示的成果相比,這并不是一個突破。但這無疑是一個很好的起點。”
Neuralink成立于2016年,這家公司的主要研究方向就是腦機接口,通過研發一種能夠植入大腦的設備,來實現“人腦與機器交互”。
腦機接口核心是在人或動物腦與計算機或其他電子設備之間建立的不依賴于常規大腦信息輸出通路(外周神經和肌肉組織)的一種全新通訊和控制技術。根據通信技術路徑,其技術主要歸為“非侵入式(腦外)”“侵入式”和“半侵入式”三類。而Neuralink采用的正是侵入式,即通過手術等方式直接將電極植入到大腦皮層,以獲得高質量的神經信號。
據馬斯克介紹,Neuralink的首個產品,也就是Arbaugh所使用產品,名叫“心靈感應”(Telepathy)。
今年1月30日,馬斯克宣布,29日首位人類接受了Neuralink的植入,恢復良好。他介紹,“只需思考即可控制你的手機或計算機,并通過它們來控制幾乎任何設備。最初的使用者將是那些失去四肢的人。可以想象一下,如果史蒂芬·霍金的溝通速度比打字員或拍賣師更快。這就是我們的目標。”
2月20日,馬斯克在X上的一場SpaceX直播活動中再次透露新進展稱,Neuralink的首位人類受試者“似乎已完全康復,沒有出現我們所知的不良反應。受試者只需要思考就可以在電腦屏幕上移動鼠標”。
值得注意的是,周三,馬斯克在X平臺上暗示,Neuralink可能正在開發可以恢復視力功能的腦機接口。他寫道,“Blindsight(盲視能力)是繼Telepathy(心靈感應)之后的下一個產品。”
在今年一月份,馬斯克就曾在采訪中透露,第二款產品暫稱為“Blindsight”,即使有人失去了雙眼和視神經,Neuralink也能讓他重見光明。
來源: 澎湃新聞
家好,我是老蓋,文章有一個視頻教程,在文章最下方,視頻教程比較詳細,看視頻的朋友可以到文章最下方直接觀看視頻。
我們首先下載這aida64, cpuz,Fritz Chess Benchmark三個軟件。這三個軟件有中文版和英文版,根據自己的需要下載就行。
cpuz他這個軟件主要用于檢測CPU的一些基本信息頻率,國際象棋用于跑分和簡單的拷機。
這里我們打開adia64的傳感器,看一下CPU的溫度,在跑分拷機的過程中可以看到溫度的改變,如果在跑分的過程中溫度如果過高就是散熱器可能會有些問題了。
在沒有開始跑分之前,顯示的CPU溫度是40°左右,然后點擊國際象棋,開始跑分測試。
這個時候打開任務管理器,可以看到任務管理器CPU使用率已經到達了百分之百,已經CPU滿載了,這時候溫度會直線上升。
經過一小會的國際象棋跑分,這時候CPU溫度已經到達了60多度,核心溫度已經到達了70多度。
國際象棋經過一段時間的運行測試完畢后會得到結果。結果是相對性能倍數是24倍左右,每秒千步11534,當停止跑分測試之后,CPU溫度也直線下到了40°左右。
類似跑分拷機的軟件也有很多,aida64里邊也有一個cpu拷機測試,有興趣的朋友可以看一下我以前發布的aida64文章和視頻,在自己測試跑分和拷機的時候,只要電腦沒有藍屏,沒有死機的情況下,就證明CPU還是比較穩定的,如果溫度比較高的話,就需要檢查散熱器和硅脂一下看看是否有問題。
本篇文章的視頻在這里,視頻講的比較詳細,有興趣的朋友可以看一下。
<script src="https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>
感謝觀看本篇文章,希望對大家有所幫助,我是老蓋,經常會分享IT互聯網與電腦知識,有興趣的可以關注一下。