python实现井字棋
?參考學習:Python實現井字棋游戲
閑扯
井字棋(Tic-Tac-Toe),初高中進行打發時間的一種畫x畫o的游戲,3*3的格子組成,一方把行列斜行連成相同的就算獲勝。
那么怎么利用進行人機對弈這種簡單的小游戲那。我們先不急于寫代碼,先進行思考,程序的實現是進行方便人們的,我們設計井字棋,肯定想讓程序智能化,能夠最大程度的模擬人,所以我們設計一個無敵的“人”,最后的結果只能是玩家輸或者平局,機器必不可能輸。
順著這個思想想,怎么讓機器無敵,這個時候就要考慮這個游戲本身了,因為游戲簡單,我們很輕松就可以推到想贏所對應的步驟,把這種思想步驟灌輸給計算機,讓他學習到,想輸都難,大概這就是人工智能(AI)吧,不過我們的這個游戲簡單,簡易的不能準確的稱為標準的人工智能,做不到AlphaGo那樣可以對戰世界冠軍,但是總體AlphaGo也是通過不斷學習不斷增強的。
言歸正傳,說我們的井字棋。井字棋我們分為0-8,橫著排就是這樣。
想要獲勝就要:
(第一個下角,后面的下中)(第一個下中,后面的下角)(不然的必定有一個死棋)
設計
棋盤采用包含9個元素的列表來實現
棋盤為board
board[0]到board[8]存儲代表棋子的字符串
字符串0到8代表未落子
字符串X、O表示兩種棋子,也就是玩家和機器進行下的棋子
程序
1.先有一個棋盤
? ? ? ? 棋盤的設計不唯一,可以設計多種樣式的棋盤,有興趣的話可以進行自行探索。
board = list("012345678") def dis_board(board):#顯示出棋盤print("\t{0} | {1} | {2}".format(board[0], board[1], board[2]))print("\t_ | _ | _")print("\t{0} | {1} | {2}".format(board[3], board[4], board[5]))print("\t_ | _ | _")print("\t{0} | {1} | {2}".format(board[6], board[7], board[8]))2.進行詢問:是x先走還是o先走
3.人機進行交互落子
AI尋求落子算法
首要目的是要確保AI的每一步都不能出錯,一出錯可能就滿盤皆輸
- ?AI判定某個位置可以贏那么就選擇這個位置落子
- ?否則,AI進行判定如果玩家下一步落某個位置贏,那么AI不讓他贏,就落子落在這個位? ?置
- ?否則,按照中心,角,邊的位置進行落子
這樣就可以讓AI立于不敗之地了。
AI先找到可以落子的位置
def _moves(board):#尋求可落子的位置moves = []for i in range(9):if board[i] in list("012345678"): #遍歷了棋盤的位置如果位置為0-8那么這個位置可以落子moves.append(i)return moves詢問玩家落子位置,無效落子重復詢問
def playermove(board):#詢問并確定玩家的選擇落子位置,無效落子重復詢問move = 9while move not in _moves(board):move = int(input("請選擇落子位置(0-8):"))return move參數:棋盤,AI棋子,玩家棋子
并且運用winner函數,贏就返回True?
def computermove(board,computerletter,playerletter):#核心算法:計算AI的落子位置boardcopy = board.copy()#規則一:判斷如果某位置落子可以獲勝,則選擇這個位置for move in _moves(boardcopy):boardcopy[move] = computerletterif winner(boardcopy):return moveboardcopy[move] = str(move)#規則二:某個位置玩家下一步落子就可以獲勝,則選擇該位置for move in _moves(boardcopy):boardcopy[move] = playerletterif winner(boardcopy):return moveboardcopy[move] = str(move)#規則三:按照中心、角、邊的選擇空的位置for move in(4,0,2,6,8,1,3,5,7):if move in _moves(board):return movewinner函數:判斷怎樣是獲勝
分為八種情況,三種橫線,三種豎線,兩種對角線
def winner(board):#判斷所給棋子是否獲勝_to_win = {(0,1,2),(3,4,5),(6,7,8),(0,3,6),(1,4,7),(2,5,8),(0,4,8),(2,4,6)} for r in _to_win:if board[r[0]] == board[r[1]] == board[r[2]]:return Truereturn FalseTie函數:還有判定平局的情況?
def Tie(board):#判斷是否平局for i in list("012345678"):if i in board:return Falsereturn True完整代碼實現
# python菜鳥 # 2022.01.10 def dis_board(board):#顯示出棋盤print("\t{0} | {1} | {2}".format(board[0], board[1], board[2]))print("\t_ | _ | _")print("\t{0} | {1} | {2}".format(board[3], board[4], board[5]))print("\t_ | _ | _")print("\t{0} | {1} | {2}".format(board[6], board[7], board[8]))def _moves(board):#尋求可落子的位置moves = []for i in range(9):if board[i] in list("012345678"): #遍歷了棋盤的位置如果位置為0-8那么這個位置可以落子moves.append(i)return movesdef playermove(board):#詢問并確定玩家的選擇落子位置,無效落子重復詢問move = 9while move not in _moves(board):move = int(input("請選擇落子位置(0-8):"))return movedef computermove(board,computerletter,playerletter):#核心算法:計算AI的落子位置boardcopy = board.copy()#規則一:判斷如果某位置落子可以獲勝,則選擇這個位置for move in _moves(boardcopy):boardcopy[move] = computerletterif winner(boardcopy):return moveboardcopy[move] = str(move)#規則二:某個位置玩家下一步落子就可以獲勝,則選擇該位置for move in _moves(boardcopy):boardcopy[move] = playerletterif winner(boardcopy):return moveboardcopy[move] = str(move)#規則三:按照中心、角、邊的選擇空的位置for move in(4,0,2,6,8,1,3,5,7):if move in _moves(board):return movedef winner(board):#判斷所給棋子是否獲勝_to_win = {(0,1,2),(3,4,5),(6,7,8),(0,3,6),(1,4,7),(2,5,8),(0,4,8),(2,4,6)}for r in _to_win:if board[r[0]] == board[r[1]] == board[r[2]]:return Truereturn Falsedef Tie(board):#判斷是否平局for i in list("012345678"):if i in board:return Falsereturn Truedef tic_tac_toe():#井字棋board = list("012345678")playerletter = input("請選擇棋子x(玩家)或者o(AI)——(x先走,o后走):")if playerletter in("X","x"):turn = "player"playerletter = "x"computerletter = "o"else:turn = "AI"computerletter = "x"playerletter = "o"print("{}先走!".format(turn))while True:dis_board(board)if turn == 'player':move = playermove(board)board[move] = playerletterif winner(board):dis_board(board)print("恭喜玩家獲勝!")breakelse:turn = "AI"else:move = computermove(board, computerletter, playerletter)print("人工智能AI落子位置:",move)board[move] = computerletterif winner(board):dis_board(board)print("人工智能AI獲勝!")breakelse:turn = "player"if Tie(board):dis_board(board)print('平局!')breakif __name__=='__main__':tic_tac_toe()其中一個實現效果?
請選擇棋子x(玩家)或者o(AI)——(x先走,o后走):x player先走!0 | 1 | 2_ | _ | _3 | 4 | 5_ | _ | _6 | 7 | 8 請選擇落子位置(0-8):80 | 1 | 2_ | _ | _3 | 4 | 5_ | _ | _6 | 7 | x 人工智能AI落子位置: 40 | 1 | 2_ | _ | _3 | o | 5_ | _ | _6 | 7 | x 請選擇落子位置(0-8):20 | 1 | x_ | _ | _3 | o | 5_ | _ | _6 | 7 | x 人工智能AI落子位置: 50 | 1 | x_ | _ | _3 | o | o_ | _ | _6 | 7 | x 請選擇落子位置(0-8):30 | 1 | x_ | _ | _x | o | o_ | _ | _6 | 7 | x 人工智能AI落子位置: 0o | 1 | x_ | _ | _x | o | o_ | _ | _6 | 7 | x 請選擇落子位置(0-8):7o | 1 | x_ | _ | _x | o | o_ | _ | _6 | x | x 人工智能AI落子位置: 6o | 1 | x_ | _ | _x | o | o_ | _ | _o | x | x 請選擇落子位置(0-8):1o | x | x_ | _ | _x | o | o_ | _ | _o | x | x 平局!進程已結束,退出代碼0遇到的一些問題
- 縮進問題:python中是有著嚴格的縮進的,一旦縮進不規整,就會出現邏輯上的錯誤
- ?其他都是碼代碼的小問題,符號的錯誤,語言的錯誤,等等,需要后期認真糾正
總結
以上是生活随笔為你收集整理的python实现井字棋的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Red5 流媒体技术(初级了解)
- 下一篇: Python + 高德API实现自助找房