基于python纯函数实现井字棋游戏


Posted in Python onMay 27, 2020

1、定义全局变

'''全局变量:
 X 和 O 表示两方的棋子;
 EMPTY 表示棋位为空;
 TIE 表示平局;
 NUM_SQUARES 表示有 9 个棋位
 '''
 X = "X"
 O = "O"
 EMPTY = " "
 TIE = "TIE"
 NUM_SQUARES = 9

2、定义调用到的函数

def ask_yes_no(question):
  '''问一个是或否的问题,用 y 或 n 回答。'''
  response = None
  while response not in ('y', 'n'):
    response = input(question).lower()
  return response


def ask_number(question, low, high):
  '''讯问一个规定范围的数字。'''
  response = None
  while response not in range(low, high):
    response = int(input(question))
  return response


def pieces():
  '''决定在人和机器之间谁先行棋。'''
  go_first = ask_yes_no('你先走? (y/n): ')
  if go_first == 'y':
    print('\n好,你先请。')
    human = X
    computer = O
  else:
    print('\n你放弃先手,我先走。')
    computer = X
    human = O
  return computer, human


def new_board():
  '''创建一个棋盘。'''
  board = []
  for square in range(NUM_SQUARES):
    board.append(EMPTY)
  return board


def display_board(board):
  '''显示棋盘。'''
  print('\n\t', board[0], '|', board[1], '|', board[2])
  print('\t', '---------')
  print('\t', board[3], '|', board[4], '|', board[5])
  print('\t', '---------')
  print('\t', board[6], '|', board[7], '|', board[8], '\n')


def legal_moves(board):
  '''创建合法的行棋位置清单。'''
  moves = []
  for square in range(NUM_SQUARES):
    if board[square] == EMPTY: # 该棋位为空
      moves.append(square)
  return moves


def winner(board):
  '''判定游戏获胜者。'''
  WAYS_TO_WIN = ((0, 1, 2), # 横
          (3, 4, 5),
          (6, 7, 8),
          (0, 3, 6), # 竖
          (1, 4, 7),
          (2, 5, 8),
          (0, 4, 8), # 主对角线
          (2, 4, 6)) # 副对角线
  # 谁先有三个棋子在一条直线上谁就获胜。
  for row in WAYS_TO_WIN:
    if board[row[0]] == board[row[1]] == board[row[2]] != EMPTY:
      winner = board[row[0]]
      return winner
  
  # 没有获胜方,但棋盘已经下满,判为平局
  if EMPTY not in board:
    return TIE

  return None # 没有获胜方,且非平局


def human_move(board, human):
  '''获取玩家的行棋位置。''' 
  legal = legal_moves(board) # 合法的行棋位置清单
  move = None
  while move not in legal:
    move = ask_number('你走哪? (0 - 8):', 0, NUM_SQUARES)
    if move not in legal:
      print('\n你选的棋位已落子,重新选择。\n')
  print('落子无悔...')
  return move


def computer_move(board, computer, human):
  '''获取电脑的行棋位置。'''
  
  board = board[:] # 通过切片复制棋盘, 创建局部变量
  BEST_MOVES = (4, 0, 2, 6, 8, 1, 3, 5, 7) # 优先的行棋位置

  print('我走到:', end=' ')
  
  # 在局部空间确定可以获胜的走法
  for move in legal_moves(board): # 合法的行棋位置列表
    board[move] = computer # 更新棋盘副本
    if winner(board) == computer:
      # 计算机能获胜
      print(move)
      return move
    # 如果计算机在该棋位行棋不能获胜,
    board[move] = EMPTY # 悔棋,更换下一个合法棋位
  
  # 阻止玩家获胜
  for move in legal_moves(board): # 合法的行棋位置列表
    board[move] = human # 更新棋盘
    if winner(board) == human:
      # 在该棋位玩家行棋后将获胜
      print(move)
      return move
    # 玩家不能获胜,不行棋至此
    board[move] = EMPTY

  # 没有能使行棋双方立决胜负的棋位,从优先棋位选择合法行棋位置
  for move in BEST_MOVES:
    if move in legal_moves(board):
      print(move)
      return move


def next_turn(turn):
  '''切换行棋方'''
  if turn == X:
    return O
  else:
    return X

  
def congrat_winner(the_winner, computer, human):
  '''向获胜方表示祝贺或声明平局'''
  if the_winner != TIE:
    print(the_winner, '祝贺你!\n')
  else:
    print('平局。。。\n')

  if the_winner == computer:
    print('如我所料,我又胜了。\n这是否能说明计算机在给方面都优于人类呢?')

  elif the_winner == human:
    print('真是匪夷所思,你没捣鬼吧?人类怎么会胜? \n不会有下次了。' )

  elif the_winner == TIE:
    print('你很厉害嘛,能跟计算机打成平手。')

3、定义主函数

def main():
  display_instruct() # 显示游戏操作指南
  computer, human = pieces() # 决定谁先行棋
  turn = X # 先行棋方执子 X
  board = new_board() # 创建空棋盘
  display_board(board) # 显示棋盘

  while not winner(board): 
    # 判定结果,在没有获胜方且不是平局时进入循环
    if turn == human:
      # 轮到玩家行棋,玩家行棋
      move = human_move(board, human) # 玩家的行棋位置
      board[move] = human # 更新棋盘
    else:
      # 轮到电脑行棋
      move = computer_move(board, computer, human) # 电脑的行棋位置
      board[move] = computer # 更新棋盘
    display_board(board) # 显示更新后的棋盘
    turn = next_turn(turn) # 切换行棋方

  the_winner = winner(board) # 判定获胜者,返回获胜方的执子,平局返回 None
  congrat_winner(the_winner, computer, human) # 向获胜方表示祝贺或声明是平局

4、调用主函数,启动程序

main()
input('\n\n按回车键退出程序。') # 等待用户

在 jupyter 中演练如下:

基于python纯函数实现井字棋游戏

基于python纯函数实现井字棋游戏

基于python纯函数实现井字棋游戏基于python纯函数实现井字棋游戏

基于python纯函数实现井字棋游戏

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中使用item()方法遍历字典的例子
Aug 26 Python
使用Python操作Elasticsearch数据索引的教程
Apr 08 Python
简述Python中的进程、线程、协程
Mar 18 Python
Python 安装setuptools和pip工具操作方法(必看)
May 22 Python
Python内置模块logging用法实例分析
Feb 12 Python
利用pyinstaller将py文件打包为exe的方法
May 14 Python
解决python3中的requests解析中文页面出现乱码问题
Apr 19 Python
Tensorflow模型实现预测或识别单张图片
Jul 19 Python
python实现数据清洗(缺失值与异常值处理)
Dec 02 Python
Django跨域资源共享问题(推荐)
Mar 09 Python
Python实现进度条和时间预估的示例代码
Jun 02 Python
Python中的np.argmin()和np.argmax()函数用法
Jun 02 Python
Python实现读取并写入Excel文件过程解析
May 27 #Python
Python正则表达式如何匹配中文
May 27 #Python
使用python创建Excel工作簿及工作表过程图解
May 27 #Python
Python实现疫情通定时自动填写功能(附代码)
May 27 #Python
Python unittest单元测试openpyxl实现过程解析
May 27 #Python
python实现爱奇艺登陆密码RSA加密的方法示例详解
May 27 #Python
python如何求100以内的素数
May 27 #Python
You might like
把77A收信机改造成收音机
2021/03/02 无线电
php flv视频时间获取函数
2010/06/29 PHP
php中OR与|| AND与&&的区别总结
2013/10/26 PHP
php递归删除指定文件夹的方法小结
2015/04/20 PHP
使用纯php代码实现页面伪静态的方法
2015/07/25 PHP
php在windows环境下获得cpu内存实时使用率(推荐)
2018/02/08 PHP
在Laravel5.6中使用Swoole的协程数据库查询
2018/06/15 PHP
php字符串函数 str类常见用法示例
2020/05/15 PHP
javascript div 遮罩层封锁整个页面
2009/07/10 Javascript
jquery在IE、FF浏览器的差别详细探讨
2013/04/28 Javascript
老生常谈Javascript中的原型和this指针
2016/10/09 Javascript
完美解决jQuery 鼠标快速滑过后,会执行多次滑出的问题
2016/12/08 Javascript
ES6 Promise对象概念与用法分析
2017/04/01 Javascript
深入理解 webpack 文件打包机制(小结)
2018/01/08 Javascript
动态加载权限管理模块中的Vue组件
2018/01/16 Javascript
vue对storejs获取的数据进行处理时遇到的几种问题小结
2018/03/20 Javascript
Express之托管静态文件的方法
2018/06/01 Javascript
JS使用canvas中的measureText方法测量字体宽度示例
2019/02/02 Javascript
详解js创建对象的几种方法及继承
2019/04/12 Javascript
Vuex持久化插件(vuex-persistedstate)解决刷新数据消失的问题
2019/04/16 Javascript
微信小程序实现侧边栏分类
2019/10/21 Javascript
Vue组件通信入门之Provide和Inject机制
2019/12/29 Javascript
JS数组进阶示例【数组的几种函数用法】
2020/01/16 Javascript
微信小程序国际化探索实现(附源码地址)
2020/05/20 Javascript
Python中List.index()方法的使用教程
2015/05/20 Python
Python中的自省(反射)详解
2015/06/02 Python
详解Python字符串对象的实现
2015/12/24 Python
python实现图片二值化及灰度处理方式
2019/12/07 Python
Python序列类型的打包和解包实例
2019/12/21 Python
Python3基于plotly模块保存图片表格
2020/08/03 Python
乌克兰网上珠宝商店:GoldSoveren
2020/03/31 全球购物
mysql_pconnect()和mysql_connect()有什么区别
2012/05/25 面试题
函数只定义了一次, 调用了一次, 但编译器提示非法重定义了-什么问题?
2014/10/03 面试题
2014幼儿园大班工作总结
2014/11/10 职场文书
MySQL EXPLAIN输出列的详细解释
2021/05/12 MySQL
使用CSS连接数据库的方式
2022/02/28 HTML / CSS