python井字棋ai_實現AI下井字棋的alpha-beta剪枝算法(python實現)

代碼參考自中國大學mooc上人工智能與信息社會陳斌老師的算法,我在原來的基礎上增加了玩家輸入的異常捕獲 AlphaBeta剪枝算法是對Minimax方法的優化,能夠極大提高搜索樹的效率,如果對這個算法感興趣的可以去參考相關資料。 當正確理解AlphaBeta剪枝算法后,還可以將它應用在象棋、圍棋等一些高級游戲的算法搜索上,使得電腦尋找最優勝率的速度加快

python代碼實現

#coding:utf-8

'''井字棋(Tic tac toe)Python3語言實現, 帶有Alpha-Beta剪枝的Minimax算法.

代碼參考自中國大學mooc 人工智能與信息社會(陳斌)'''

import random

# 用如下的9個數字來表示棋盤的位置:

# 0? 1? 2

# 3? 4? 5

# 6? 7? 8

# 設定獲勝的組合方式(橫、豎、斜)

WINNING_TRIADS = ((0, 1, 2), (3, 4, 5), (6, 7, 8),

(0, 3, 6), (1, 4, 7),(2, 5, 8),

(0, 4, 8), (2, 4, 6))

# 設定棋盤按一行三個打印

PRINTING_TRIADS = ((0, 1, 2), (3, 4, 5), (6, 7, 8))

# 用一維列表表示棋盤:

SLOTS = (0, 1, 2, 3, 4, 5, 6, 7, 8)

# -1表示X玩家 0表示空位 1表示O玩家.

X_token = -1

Open_token = 0

O_token = 1

MARKERS = ['_', 'O', 'X']

END_PHRASE = ('平局', '勝利', '失敗')

def alpha_beta_valuation(board, player, next_player, alpha, beta):

"""運用AlphaBeta剪枝來計算當前局面的分值

因為搜索層數少,總能搜索到最終局面,估值結果為[-1,0,1]

"""

wnnr = winner(board)

if wnnr != Open_token:

# 有玩家獲勝

return wnnr

elif not legal_move_left(board):

# 沒有空位,平局

return 0

# 檢查當前玩家"player"的所有可落子點

for move in SLOTS:

if board[move] == Open_token:

board[move] = player

# 落子之后交換玩家,繼續檢驗

val = alpha_beta_valuation(board, next_player, player, alpha, beta)

board[move] = Open_token

if player == O_token:? # 當前玩家是O,是Max玩家(記號是1)

if val > alpha:

alpha = val

if alpha >= beta:

return beta? # 直接返回當前的最大可能取值beta, 進行剪枝

else:? # 當前玩家是X,是Min玩家(記號是-1)

if val < beta:

beta = val

if beta <= alpha:

return alpha? # 直接返回當前的最小可能取值alpha, 進行剪枝

if player == O_token:

retval = alpha

else:

retval = beta

return retval

def print_board(board):

"""打印當前棋盤"""

for row in PRINTING_TRIADS:

r = ' '

for hole in row:

r += MARKERS[board[hole]] + ' '

print(r)

def legal_move_left(board):

""" 判斷棋盤上是否還有空位 """

for slot in SLOTS:

if board[slot] == Open_token:

return True

return False

def winner(board):

""" 判斷局面的勝者,返回值-1表示X獲勝,1表示O獲勝,0表示平局或者未結束"""

for triad in WINNING_TRIADS:

triad_sum = board[triad[0]] + board[triad[1]] + board[triad[2]]

if triad_sum == 3 or triad_sum == -3:

return board[triad[0]]? # 表示棋子的數值恰好也是-1:X,1:O

return 0

def determine_move(board):

"""決定電腦(玩家O)的下一步棋,若估值相同則隨機選取步數"""

best_val = -2? # 本程序估值結果只在[-1,0,1]中

my_moves = []

print("開始思考")

for move in SLOTS:

if board[move] == Open_token:

board[move] = O_token

val = alpha_beta_valuation(board, X_token, O_token, -2, 2)

board[move] = Open_token

print("Computer如果下在", move, ",將導致", END_PHRASE[val])

if val > best_val:

best_val = val

my_moves = [move]

if val == best_val:

my_moves.append(move)

return random.choice(my_moves)

HUMAN = 1

COMPUTER = 0

def main():

"""主函數,先決定誰是X(先手方),再開始下棋"""

next_move = HUMAN

opt = input("請選擇先手方,輸入X表示玩家先手,輸入O表示電腦先手:")

if opt == "X":

next_move = HUMAN

elif opt == "O":

next_move = COMPUTER

else:

print("輸入有誤,默認玩家先手")

# 初始化空棋盤

board = [Open_token for i in range(9)]

# 開始下棋

while legal_move_left(board) and winner(board) == Open_token:

print()

print_board(board)

if next_move == HUMAN and legal_move_left(board):

try:

humanmv = int(input("請輸入你要落子的位置(0-8):"))

if board[humanmv] != Open_token:

continue

board[humanmv] = X_token

next_move = COMPUTER

except:

print("輸入有誤,請重試")

continue

if next_move == COMPUTER and legal_move_left(board):

mymv = determine_move(board)

print("Computer最終決定下在", mymv)

board[mymv] = O_token

next_move = HUMAN

# 輸出結果

print_board(board)

print(["平局", "Computer贏了", "你贏了"][winner(board)])

if __name__ == '__main__':

main()

運行結果

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/534498.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/534498.shtml
英文地址,請注明出處:http://en.pswp.cn/news/534498.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Redis小計(2)

目錄 1.exists命令 2.del命令 3.expire/pexpire命令 4.ttl命令 5.redis對于key過期的刪除策略 1.exists命令 exists X1 X2 X3 X4&#xff1a;返回四個key存在的個數。 2.del命令 del X1 X2&#xff1a;刪除key。 3.expire/pexpire命令 給key設置超時時間。 expire key…

unity 彩帶粒子_iOS動畫開發----粒子系統---彩帶效果

參考博文地址:http://my.oschina.net/u/2340880/blog/485095?fromerrbgjLq4Mw一、粒子發射器iOS中的粒子效果有兩部分組成&#xff0c;一部分為發射器&#xff0c;設置例子發射的宏觀屬性&#xff0c;另一部分是粒子單元&#xff0c;用于設置相應的粒子屬性。粒子發射器是基于…

一秒執行一次_《一秒鐘》:一貫的粗曠式抓大放小,張藝謀的自命題作業總是要觀眾自己再做一遍...

還有不變的永遠在奔跑的大棉褲花棉襖的圓臉妮子&#xff0c;這是導演張藝謀最新作品《一秒鐘》的最直接觀感。張藝謀是個善于從普世情懷處挖掘題材的導演。之前諸多現實題材類型作品&#xff0c;諸如講父子和解的《千里走單騎》、夫妻愛情的《歸來》以及《我的父親母親》&#…

latex 作者加小標_Latex 寫期刊論文的小技巧

在不同文字處理系統(如 MiKTeX, TeX Live, CTeX, cwTex) 或 不同整合開發環境 ( 如Texstudio, WinEdt, TeXstudio, TeXmaker) 中&#xff0c;我用了 Miktex Texstudio 的常用組合 (win10環境中)。1: 先MiKTeX&#xff0c;后Texstudio ;2&#xff1a; 安裝包(packages);3&#…

unity 畸變_unity3d 幾種鏡頭畸變

1.Fisheye distortion 魚眼鏡頭解釋來自百度百科&#xff1a;魚眼鏡頭是一種焦距為16mm或更短的并且視角接近或等于180。 它是一種極端的廣角鏡頭&#xff0c;“魚眼鏡頭”是它的俗稱。為使鏡頭達到最大的攝影視角&#xff0c;這種攝影鏡頭的前鏡片直徑很短且呈拋物狀向鏡頭前…

restfull加簽_SpringBoot RestFull API簽名

一、需求如下對指定的API路徑進行簽名認證&#xff0c;對于沒有指定的無需認證&#xff0c;認證具體到方法。二、查閱資料與開發1.了解JWT&#xff0c;實際上用的開源jjwt2.編寫自定義注解3.編寫攔截器&#xff0c;主要是攔截特定的url進行簽名驗證&#xff0c;這里解析請求的h…

mysql 5.5.18下載_MySQL5.7.18下載和安裝過程圖文詳解

MySql下載1、打開官網找到下載路口&#xff0c;這里直接給出下載的地址2、選擇64位版本3、直接下載MySql5.7.18.1安裝過程1 、運行安裝軟件&#xff0c;接受協議2、選擇默認安裝3、下一步到檢查環境界面&#xff0c;點擊“Execute”執行檢查 (可以后面單獨下載插件安裝)&…

mysql找不到performance_Mysql安裝完畢運行時沒有mysql和performance_schema數據庫_MySQL

Mysql問題 ERROR 1045 (28000): Access denied for user ‘root’’localhost’ (using password: YES)Mysql安裝完畢運行時沒有 mysql 和 performance_schema 數據庫問題一&#xff1a;之前卸載未卸載干凈問題二&#xff1a;沒有管理員權限進入問題三&#xff1a;登錄時&#…

mysql latid1_mysql觸發器的實戰經驗

1 引言Mysql的觸發器和存儲過程一樣&#xff0c;都是嵌入到mysql的一段程序。觸發器是mysql5新增的功能&#xff0c;目前線上鳳巢系統、北斗系統以及哥倫布系統使用的數據庫均是mysql5.0.45版本&#xff0c;很多程序比如fc-star管理端&#xff0c;sfrd(das)&#xff0c;dorad…

mysql數據庫sql注入原理_SQL注入原理解析以及舉例1

sql注入是指web應用程序對用戶輸入數據的合法性沒有判斷&#xff0c;導致攻擊者可以構造不同的sql語句來實現對數據庫的操作。sql注入漏洞產生滿足條件&#xff1a;1&#xff1b;用戶能夠控制數據的輸入。2&#xff1b;原本需要執行的代碼&#xff0c;拼接了用戶的輸入。舉例&a…

mysql存儲map數據結構_map數據結構

Go map實現原理 - 戀戀美食的個人空間 - OSCHINA - 中文開源技術交流社區 https://my.oschina.net/renhc/blog/2208417// A header for a Go map.type hmap struct {// Note: the format of the hmap is also encoded in cmd/compile/internal/gc/reflect.go.// Make sure this…

四因素三水平正交表_做論文要用正交表?我打包送給你

正交試驗目前在國內的應用量仍然是比較高的&#xff0c;許多高校畢業生喜歡利用正交試驗來獲取研究數據&#xff0c;最終完成畢業論文的撰寫或者期刊投稿。正交試驗方案的設計&#xff0c;必然要用到(標準)正交表。那么大家都是從哪里獲取正交表的呢&#xff1f;小兵給這方面的…

plsql視圖添加表字段_Oracle-單表多字段查詢(不使用*)

環境&#xff1a;Oracle 11g&#xff0c;plsql 14目的&#xff1a;不使用*,查詢擁有上百個字段的表的所有字段。懶人大法&#xff1a;在文章末尾。sql實現邏輯&#xff1a;1、首先建一張100個字段以上的表&#xff0c;通過excel的方式將表建好后直接復制粘貼到plsql的建表界面。…

mysql 編譯安裝與rpm安裝的區別_編譯安裝與RPM安裝的區別

建議在安裝線上的生產服務器軟件包時都用源碼安裝&#xff0c;這是因為源碼安裝可以自行調整編譯參數&#xff0c;最大化地定制安裝結果。這里以MySQL 5線上環境的編譯安裝來說明之&#xff0c;其編譯參數如下所示&#xff1a;./configure-prefix/usr/local/mysql -without-deb…

python字符串變量s的值是python網絡爬蟲_【Python爬蟲作業】-字符串

一、定義字符串變量1.請定義三個字符串a,b,c值分別為 I,like, python2.請將上面三個變量合并輸出I like pythonaIblikecpythonprint(a)print(b)print(c)print(a,b,c)二、定義一個變量 s sdghHhf 1.請先將變量s的空白符去掉 賦值給新變量s1 打印輸出2.請分別將s1變為全部大寫(命…

lableimg閃退_CV學習筆記(二十五):數據集標注與制作

最近在做一些數據標注的工作&#xff0c;雖然標注數據比較枯燥&#xff0c;但這也是每個做算法的工程師升級打怪的必由之路。使用一些合適的工具往往可以事半功倍&#xff0c;效率UP。一&#xff1a;數據標注流程二&#xff1a;數據處理的一些小代碼1&#xff1a;重命名當得到這…

mysql show profile詳解_SQL 性能分析利器 show profile

本文首發個人公眾號《andyqian》, 期待你的關注&#xff5e;前言在之前的文章中&#xff0c;我們提到過一些慢SQL優化的步驟。其中就包括&#xff1a;使用 explain 關鍵字來查看執行計劃&#xff0c;是否命中索引。通過計算某列的區分度&#xff0c;來判斷該列是否適合新建索引…

php判斷給定的整數是否是2的冪_C++_C語言判斷一個數是否是2的冪次方或4的冪次方,快速判斷一個數是否是2的冪次 - phpStudy...

C語言判斷一個數是否是2的冪次方或4的冪次方快速判斷一個數是否是2的冪次方&#xff0c;若是&#xff0c;并判斷出來是多少次方&#xff01;將2的冪次方寫成二進制形式后&#xff0c;很容易就會發現有一個特點&#xff1a;二進制中只有一個1&#xff0c;并且1后面跟了n個0&…

python 包編譯安裝mysql_CentOS7編譯安裝MySQL8.0.23和Python3.1.9

卸載mariadbrpm -qa | grep mariadbmariadb-libs-5.5.64-1.el7.x86_64yum remove mariadb-libs.x86_64 -y安裝高版本GCC&#xff0c;解決編譯中會遇到的GCC 5.3 or newer is required (-dumpversion says 4.8.5)cd /optyum install centos-release-scl -yyum install devtoolse…

python3.0下載用什么瀏覽器_無法讓Python下載網頁源代碼:“不支持瀏覽器版本”...

查看您列出的url&#xff0c;我執行了以下操作&#xff1a;使用wget下載了頁面將urllib與ipython一起使用并下載了頁面使用chrome&#xff0c;只保存了url所有3個都給了我相同的結果文件(相同的大小&#xff0c;相同的內容)。在這可能是因為我沒有登錄&#xff0c;但我確實看到…