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命令行参数解析模块getopt使用实例
Apr 13 Python
探究Python的Tornado框架对子域名和泛域名的支持
May 02 Python
详解Python的Django框架中Manager方法的使用
Jul 21 Python
Python调用C语言的方法【基于ctypes模块】
Jan 22 Python
TensorFlow实现RNN循环神经网络
Feb 28 Python
解决python报错MemoryError的问题
Jun 26 Python
Python面向对象之反射/自省机制实例分析
Aug 24 Python
解决安装python库时windows error5 报错的问题
Oct 21 Python
详解python常用命令行选项与环境变量
Feb 20 Python
Python Tornado之跨域请求与Options请求方式
Mar 28 Python
如何打包Python Web项目实现免安装一键启动的方法
May 21 Python
Python中threading库实现线程锁与释放锁
May 17 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
php数组的概述及分类与声明代码演示
2013/02/26 PHP
mod_php、FastCGI、PHP-FPM等PHP运行方式对比
2015/07/02 PHP
Yii2 输出xml格式数据的方法
2016/05/03 PHP
预加载css或javascript的js代码
2010/04/23 Javascript
关于URL中的特殊符号使用介绍
2011/11/03 Javascript
用jquery模仿的a的title属性(兼容ie6/7)
2013/01/21 Javascript
js禁止页面使用右键(简单示例代码)
2013/11/13 Javascript
JavaScript中Number.MAX_VALUE属性的使用方法
2015/06/04 Javascript
jQuery实现form表单基于ajax无刷新提交方法详解
2015/12/08 Javascript
实例详解jQuery表单验证插件validate
2016/01/18 Javascript
jQuery基于muipicker实现仿ios时间选择
2016/02/22 Javascript
AngularJS中的包含详细介绍及实现示例
2016/07/28 Javascript
JS实现图片手风琴效果
2020/04/17 Javascript
JavaScrip数组删除特定元素的几种方法总结
2017/09/06 Javascript
jquery获取transform里的值实现方法
2017/12/12 jQuery
Javascript实现异步编程的过程
2018/06/18 Javascript
vue 界面刷新数据被清除 localStorage的使用详解
2018/09/16 Javascript
原生javascript制作贪吃蛇小游戏的方法分析
2020/02/26 Javascript
Python实现115网盘自动下载的方法
2014/09/30 Python
Python实现批量修改文件名实例
2015/07/08 Python
Python中使用platform模块获取系统信息的用法教程
2016/07/08 Python
python3.7.0的安装步骤
2018/08/27 Python
PyQt5 在label显示的图片中绘制矩形的方法
2019/06/17 Python
python处理excel绘制雷达图
2019/10/18 Python
如何基于Python + requests实现发送HTTP请求
2020/01/13 Python
python烟花效果的代码实例
2020/02/25 Python
如何清空python的变量
2020/07/05 Python
python爬虫看看虎牙女主播中谁最“顶”步骤详解
2020/12/01 Python
pytorch下的unsqueeze和squeeze的用法说明
2021/02/06 Python
HTML5 body设置全屏背景图片的示例代码
2020/12/08 HTML / CSS
物流专业大学应届生求职信
2013/11/03 职场文书
经贸日语专业个人求职信
2013/12/13 职场文书
加强作风建设演讲稿
2014/10/24 职场文书
有限责任公司股东合作协议书
2014/12/02 职场文书
2014年幼儿园德育工作总结
2014/12/17 职场文书
读书笔记怎么写
2015/07/01 职场文书