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实现代理服务功能实例
Nov 15 Python
使用Python生成url短链接的方法
May 04 Python
完美解决Python2操作中文名文件乱码的问题
Jan 04 Python
一个基于flask的web应用诞生 使用模板引擎和表单插件(2)
Apr 11 Python
Python基于回溯法解决01背包问题实例
Dec 06 Python
详解python实现识别手写MNIST数字集的程序
Aug 03 Python
详解Python静态网页爬取获取高清壁纸
Apr 23 Python
Python 实现一行输入多个数字(用空格隔开)
Apr 29 Python
Anaconda3中的Jupyter notebook添加目录插件的实现
May 18 Python
Windows 下更改 jupyterlab 默认启动位置的教程详解
May 18 Python
Python绘制组合图的示例
Sep 18 Python
Python实现简单的猜单词
Jun 15 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
str_replace只替换一次字符串的方法
2013/04/09 PHP
php rsa 加密,解密,签名,验签详解
2016/12/06 PHP
PHP面向对象程序设计内置标准类,普通数据类型转为对象类型示例
2019/06/12 PHP
javascript下判断一个对象是否具有指定名称的属性的的代码
2010/01/11 Javascript
精通Javascript系列之Javascript基础篇
2011/06/07 Javascript
面向对象设计模式的核心法则
2013/11/10 Javascript
鼠标滑在标题上显示图片的JS代码
2013/11/19 Javascript
同域jQuery(跨)iframe操作DOM(示例代码)
2013/12/13 Javascript
IE浏览器IFrame对象内存不释放问题解决方法
2014/08/22 Javascript
JS 使用for循环遍历子节点查找元素
2014/09/06 Javascript
jquery 实现滚动条下拉时无限加载的简单实例
2016/06/01 Javascript
jquery中取消和绑定hover事件的实现代码
2016/06/02 Javascript
JS如何实现封装列表右滑动删除收藏按钮
2020/07/23 Javascript
[48:20]OpTic vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
python self,cls,decorator的理解
2009/07/13 Python
python和C语言混合编程实例
2014/06/04 Python
Python中利用sqrt()方法进行平方根计算的教程
2015/05/15 Python
wxPython之解决闪烁的问题
2018/01/15 Python
Python采集猫眼两万条数据 对《无名之辈》影评进行分析
2018/12/05 Python
python用plt画图时,cmp设置方法
2018/12/13 Python
python SQLAlchemy 中的Engine详解
2019/07/04 Python
python生成xml时规定dtd实例方法
2020/09/21 Python
python mock测试的示例
2020/10/19 Python
python 合并多个excel中同名的sheet
2021/01/22 Python
HTML5实现简单图片上传所遇到的问题及解决办法
2016/01/20 HTML / CSS
将一个数的从第5位开始的7个数取出,其余位置0
2016/05/26 面试题
应届毕业生个人自我评价
2013/09/20 职场文书
求职简历的自我评价怎样写好
2013/10/07 职场文书
财务专业大学生职业生涯规划范文
2013/12/30 职场文书
新入职员工的自我介绍演讲稿
2014/01/02 职场文书
招聘与培训专员岗位职责
2014/01/30 职场文书
餐饮投资计划书
2014/04/25 职场文书
2014年路政工作总结
2014/12/10 职场文书
2016年优秀团员事迹材料
2016/02/25 职场文书
励志语录:你若不勇敢,谁替你坚强
2019/11/08 职场文书
戴尔Win11系统no bootable devices found解决教程
2022/09/23 数码科技