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中random模块生成随机数详解
Mar 10 Python
Pycharm学习教程(3) 代码运行调试
May 03 Python
Python之文字转图片方法
May 10 Python
pandas中apply和transform方法的性能比较及区别介绍
Oct 30 Python
python实现图片彩色转化为素描
Jan 15 Python
python实现图书借阅系统
Feb 20 Python
python爬虫爬取笔趣网小说网站过程图解
Nov 18 Python
Python 定义只读属性的实现方式
Mar 05 Python
Python任务调度利器之APScheduler详解
Apr 02 Python
PyTorch实现重写/改写Dataset并载入Dataloader
Jul 14 Python
python绘制雷达图实例讲解
Jan 03 Python
Python深度学习之Pytorch初步使用
May 20 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+mysql事务rollback&amp;commit示例
2010/02/08 PHP
destoon安装出现Internal Server Error的解决方法
2014/06/21 PHP
详解PHP匿名函数与注意事项
2016/03/29 PHP
PHP中递归的实现实例详解
2017/11/14 PHP
javascript开发技术大全-第1章javascript概述
2011/07/03 Javascript
从jQuery.camelCase()学习string.replace() 函数学习
2011/09/13 Javascript
Jquery实现带动画效果的经典二级导航菜单
2013/03/22 Javascript
控制input输入框中提示信息的显示和隐藏的方法
2014/02/12 Javascript
js实现日历可获得指定日期周数及星期几示例分享(js获取星期几)
2014/03/14 Javascript
jQuery 计算iframe 窗口大小的方法
2014/05/13 Javascript
angularJS中$apply()方法详解
2015/01/07 Javascript
JS显示表格内指定行html代码的方法
2015/03/31 Javascript
vue.js学习之递归组件
2016/12/13 Javascript
EasyUI学习之Combobox级联下拉列表(2)
2016/12/29 Javascript
基于angular实现三级联动的生日插件
2017/05/12 Javascript
Node.js Express安装与使用教程
2018/05/11 Javascript
vue-cli3脚手架的配置及使用教程
2018/08/28 Javascript
layui 阻止图片上传的实例(before方法)
2019/09/26 Javascript
基于纯JS实现多张图片的懒加载Lazy过程解析
2019/10/14 Javascript
Tensorflow之构建自己的图片数据集TFrecords的方法
2018/02/07 Python
Python安装Flask环境及简单应用示例
2019/05/03 Python
对PyQt5的输入对话框使用(QInputDialog)详解
2019/06/25 Python
django基于restframework的CBV封装详解
2019/08/08 Python
python函数修饰符@的使用方法解析
2019/09/02 Python
python实现拼接图片
2020/03/23 Python
python 实现逻辑回归
2020/12/30 Python
HTML5上传文件显示进度的实现代码
2012/08/30 HTML / CSS
Mixbook加拿大:照片书,照片卡,剪贴簿,年历和日历
2017/02/21 全球购物
Hotels.com南非:酒店预订
2017/11/02 全球购物
美国滑雪和滑雪板商店:Buckman
2018/03/03 全球购物
公安局负责人查摆问题及整改方案
2014/09/27 职场文书
2015年医院科室工作总结范文
2015/05/26 职场文书
企业反腐倡廉心得体会
2015/08/15 职场文书
2016年度先进班组事迹材料
2016/03/01 职场文书
python实现批量移动文件
2021/04/05 Python
集英社今正式宣布 成立游戏公司“集英社Games”
2022/03/31 其他游戏