Python實現(xiàn)的井字棋(Tic Tac Toe)游戲示例
本文實例講述了Python實現(xiàn)的井字棋(Tic Tac Toe)游戲。分享給大家供大家參考,具體如下:
說明
用python實現(xiàn)了井字棋,整個框架是本人自己構(gòu)思的,自認(rèn)為比較滿意。另外,90%+的代碼也是本人逐字逐句敲的。
minimax算法還沒完全理解,所以參考了這里的代碼,并作了修改。
特點
可以選擇人人、人機(jī)、機(jī)人、機(jī)機(jī)四種對戰(zhàn)模式之一
電腦玩家的AI使用了minimax算法,帶apha-beta剪枝
電腦玩家在思考時,時時刻刻都有一個“假想敵”。以便使得minimax算法運(yùn)轉(zhuǎn)起來
代碼
#作者:hhh5460 #時間:2017年6月26日 # 棋盤 class Board(object): def __init__(self): #self._board = '-'*9 # 坑?。? self._board = ['-' for _ in range(9)] self._history = [] # 棋譜 # 按指定動作,放入棋子 def _move(self, action, take): if self._board[action] == '-': self._board[action] = take self._history.append((action, take)) # 加入棋譜 # 撤銷動作,拿走棋子 def _unmove(self, action): self._board[action] = '-' self._history.pop() # 棋盤快照 def get_board_snapshot(self): return self._board[:] # 取棋盤上的合法走法 def get_legal_actions(self): actions = [] for i in range(9): if self._board[i] == '-': actions.append(i) return actions # 判斷走法是否合法 def is_legal_action(self, action): return self._board[action] == '-' # 終止檢測 def teminate(self): board = self._board lines = [board[0:3], board[3:6], board[6:9], board[0::3], board[1::3], board[2::3], board[0::4], board[2:7:2]] if ['X']*3 in lines or ['O']*3 in lines or '-' not in board: return True else: return False # 勝負(fù)檢查 def get_winner(self): board = self._board lines = [board[0:3], board[3:6], board[6:9], board[0::3], board[1::3], board[2::3], board[0::4], board[2:7:2]] if ['X']*3 in lines: return 0 elif ['O']*3 in lines: return 1 else: return 2 # 打印棋盤 def print_b(self): board = self._board for i in range(len(board)): print(board[i], end='') if (i+1)%3 == 0: print() # 打印棋譜 def print_history(self): print(self._history) # 玩家 class Player(object): ''' 玩家只做兩件事:思考、落子 1. 思考 --> 得到走法 2. 落子 --> 執(zhí)行走法,改變棋盤 ''' def __init__(self, take='X'): # 默認(rèn)執(zhí)的棋子為 take = 'X' self.take=take def think(self, board): pass def move(self, board, action): board._move(action, self.take) # 人類玩家 class HumanPlayer(Player): def __init__(self, take): super().__init__(take) def think(self, board): while True: action = input('Please input a num in 0-8:') if len(action)==1 and action in '012345678' and board.is_legal_action(int(action)): return int(action) # 電腦玩家 class AIPlayer(Player): def __init__(self, take): super().__init__(take) def think(self, board): print('AI is thinking ...') take = ['X','O'][self.take=='X'] player = AIPlayer(take) # 假想敵?。?! _, action = self.minimax(board, player) #print('OK') return action # 極大極小法搜索,α-β剪枝 def minimax(self, board, player, depth=0) : '''參考:https://stackoverflow.com/questions/44089757/minimax-algorithm-for-tic-tac-toe-python''' if self.take == "O": bestVal = -10 else: bestVal = 10 if board.teminate() : if board.get_winner() == 0 : return -10 + depth, None elif board.get_winner() == 1 : return 10 - depth, None elif board.get_winner() == 2 : return 0, None for action in board.get_legal_actions() : # 遍歷合法走法 board._move(action, self.take) val, _ = player.minimax(board, self, depth+1) # 切換到 假想敵!??! board._unmove(action) # 撤銷走法,回溯 if self.take == "O" : if val > bestVal: bestVal, bestAction = val, action else : if val < bestVal: bestVal, bestAction = val, action return bestVal, bestAction # 游戲 class Game(object): def __init__(self): self.board = Board() self.current_player = None # 生成玩家 def mk_player(self, p, take='X'): # p in [0,1] if p==0: return HumanPlayer(take) else: return AIPlayer(take) # 切換玩家 def switch_player(self, player1, player2): if self.current_player is None: return player1 else: return [player1, player2][self.current_player == player1] # 打印贏家 def print_winner(self, winner): # winner in [0,1,2] print(['Winner is player1','Winner is player2','Draw'][winner]) # 運(yùn)行游戲 def run(self): ps = input("Please select two player's type:\n\t0.Human\n\t1.AI\nSuch as:0 0\n") p1, p2 = [int(p) for p in ps.split(' ')] player1, player2 = self.mk_player(p1, 'X'), self.mk_player(p2, 'O') # 先手執(zhí)X,后手執(zhí)O print('\nGame start!\n') self.board.print_b() # 顯示棋盤 while True: self.current_player = self.switch_player(player1, player2) # 切換當(dāng)前玩家 action = self.current_player.think(self.board) # 當(dāng)前玩家對棋盤進(jìn)行思考后,得到招法 self.current_player.move(self.board, action) # 當(dāng)前玩家執(zhí)行招法,改變棋盤 self.board.print_b() # 顯示當(dāng)前棋盤 if self.board.teminate(): # 根據(jù)當(dāng)前棋盤,判斷棋局是否終止 winner = self.board.get_winner() # 得到贏家 0,1,2 break self.print_winner(winner) print('Game over!') self.board.print_history() if __name__ == '__main__': Game().run()
下圖是人人對戰(zhàn)的結(jié)果
更多關(guān)于Python相關(guān)內(nèi)容可查看本站專題:《Python游戲開發(fā)技巧總結(jié)》、《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python Socket編程技巧總結(jié)》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》、《Python入門與進(jìn)階經(jīng)典教程》及《Python文件與目錄操作技巧匯總》
希望本文所述對大家Python程序設(shè)計有所幫助。
相關(guān)文章
Python實現(xiàn)數(shù)據(jù)透視表詳解
今天小編就為大家分享一篇用Python實現(xiàn)數(shù)據(jù)的透視表的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-10-10python concurrent.futures模塊的使用測試
大家都知道concurrent.futures 是 3.2 中引入的新模塊,它為異步執(zhí)行可調(diào)用對象提供了高層接口,今天通過本文給大家介紹python concurrent.futures模塊的使用測試 ,感興趣的朋友一起看看吧2021-07-07Python selenium模塊實現(xiàn)定位過程解析
這篇文章主要介紹了python selenium模塊實現(xiàn)定位過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-07-07PyTorch加載模型model.load_state_dict()問題及解決
這篇文章主要介紹了PyTorch加載模型model.load_state_dict()問題及解決,具有很好的參考價值,希望對大家有所幫助。2023-02-02