Python实现的井字棋(Tic Tac Toe)游戏示例


Posted in Python onJanuary 31, 2018

本文实例讲述了Python实现的井字棋(Tic Tac Toe)游戏。分享给大家供大家参考,具体如下:

说明

用python实现了井字棋,整个框架是本人自己构思的,自认为比较满意。另外,90%+的代码也是本人逐字逐句敲的。

minimax算法还没完全理解,所以参考了这里的代码,并作了修改。

特点

可以选择人人、人机、机人、机机四种对战模式之一
电脑玩家的AI使用了minimax算法,带apha-beta剪枝
电脑玩家在思考时,时时刻刻都有一个“假想敌”。以便使得minimax算法运转起来

代码

#作者: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
 # 胜负检查
 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. 落子 --> 执行走法,改变棋盘
 '''
 def __init__(self, take='X'): # 默认执的棋子为 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])
 # 运行游戏
 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') # 先手执X,后手执O
  print('\nGame start!\n')
  self.board.print_b() # 显示棋盘
  while True:
   self.current_player = self.switch_player(player1, player2) # 切换当前玩家
   action = self.current_player.think(self.board) # 当前玩家对棋盘进行思考后,得到招法
   self.current_player.move(self.board, action) # 当前玩家执行招法,改变棋盘
   self.board.print_b() # 显示当前棋盘
   if self.board.teminate(): # 根据当前棋盘,判断棋局是否终止
    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()

下图是人人对战的结果

Python实现的井字棋(Tic Tac Toe)游戏示例

更多关于Python相关内容可查看本站专题:《Python游戏开发技巧总结》、《Python数据结构与算法教程》、《Python Socket编程技巧总结》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python海龟绘图实例教程
Jul 24 Python
完美解决Python2操作中文名文件乱码的问题
Jan 04 Python
Python内置模块turtle绘图详解
Dec 09 Python
Python用 KNN 进行验证码识别的实现方法
Feb 06 Python
Python视频爬虫实现下载头条视频功能示例
May 07 Python
实例讲解Python中整数的最大值输出
Mar 17 Python
django框架实现模板中获取request 的各种信息示例
Jul 01 Python
python 绘制拟合曲线并加指定点标识的实现
Jul 10 Python
Python3实现配置文件差异对比脚本
Nov 18 Python
python+Django+pycharm+mysql 搭建首个web项目详解
Nov 29 Python
python GUI库图形界面开发之PyQt5多线程中信号与槽的详细使用方法与实例
Mar 08 Python
Python中无限循环需要什么条件
May 27 Python
使用Python制作微信跳一跳辅助
Jan 31 #Python
python模块之paramiko实例代码
Jan 31 #Python
Python进度条实时显示处理进度的示例代码
Jan 30 #Python
Python3生成手写体数字方法
Jan 30 #Python
python字符串的方法与操作大全
Jan 30 #Python
Python实现带参数与不带参数的多重继承示例
Jan 30 #Python
Python实现的随机森林算法与简单总结
Jan 30 #Python
You might like
c#中的实现php中的preg_replace
2009/12/21 PHP
php引用返回与取消引用的详解
2013/06/08 PHP
php自定义截取中文字符串-utf8版
2017/02/27 PHP
Js之软键盘实现(js源码)
2007/01/30 Javascript
拉动滚动条加载数据的jquery代码
2012/05/03 Javascript
用JavaScript实现动画效果的方法
2013/07/20 Javascript
js取模(求余数)隔行变色
2014/05/15 Javascript
完美兼容IE,chrome,ff的设为首页、加入收藏及保存到桌面js代码
2014/12/17 Javascript
JS实现合并两个数组并去除重复项只留一个的方法
2015/12/17 Javascript
谈谈JS中常遇到的浏览器兼容问题和解决方法
2016/12/17 Javascript
WebSocket实现简单客服聊天系统
2017/05/12 Javascript
关于Mac下安装nodejs、npm和cnpm的教程
2018/04/11 NodeJs
JS实现鼠标拖拽盒子移动及右键点击盒子消失效果示例
2019/01/29 Javascript
vue中使用element组件时事件想要传递其他参数的问题
2019/09/18 Javascript
js实现跳一跳小游戏
2020/07/31 Javascript
Python实现爬取知乎神回复简单爬虫代码分享
2015/01/04 Python
浅谈Python中的数据类型
2015/05/05 Python
python使用正则表达式匹配字符串开头并打印示例
2017/01/11 Python
AI人工智能 Python实现人机对话
2017/11/13 Python
Flask框架响应、调度方法和蓝图操作实例分析
2018/07/24 Python
Random 在 Python 中的使用方法
2018/08/09 Python
python如何实现一个刷网页小程序
2018/11/27 Python
Python3.5实现的罗马数字转换成整数功能示例
2019/02/25 Python
Python根据当前日期取去年同星期日期
2019/04/14 Python
python 缺失值处理的方法(Imputation)
2019/07/02 Python
关于Python 常用获取元素 Driver 总结
2019/11/24 Python
python中提高pip install速度
2020/02/14 Python
Jupyter Notebook折叠输出的内容实例
2020/04/22 Python
Python爬虫破解登陆哔哩哔哩的方法
2020/11/17 Python
python中scrapy处理项目数据的实例分析
2020/11/22 Python
团员的自我评价
2013/12/01 职场文书
《雨霖铃》听课反思
2014/02/13 职场文书
高三学生评语大全
2014/04/25 职场文书
物业保安辞职信
2015/05/12 职场文书
工伤事故赔偿协议书
2015/08/06 职场文书
2019年12月24日平安夜祝福语集锦
2019/12/24 职场文书