基于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 相关文章推荐
Python3.x版本中新的字符串格式化方法
Apr 24 Python
使用PyCharm配合部署Python的Django框架的配置纪实
Nov 19 Python
python读取视频流提取视频帧的两种方法
Oct 22 Python
Python中GIL的使用详解
Oct 03 Python
Python3内置模块之json编解码方法小结【推荐】
Dec 09 Python
Python使用pyserial进行串口通信的实例
Jul 02 Python
对Python 中矩阵或者数组相减的法则详解
Aug 26 Python
python根据时间获取周数代码实例
Sep 30 Python
简单了解Python3 bytes和str类型的区别和联系
Dec 19 Python
python调用HEG工具批量处理MODIS数据的方法及注意事项
Feb 18 Python
django实现日志按日期分割
May 21 Python
Keras 使用 Lambda层详解
Jun 10 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
Codeigniter出现错误提示Error with CACHE directory的解决方案
2014/06/12 PHP
php生成QRcode实例
2014/09/22 PHP
phpStudy访问速度慢和启动失败的解决办法
2015/11/19 PHP
Yii统计不同类型邮箱数量的方法
2016/10/18 PHP
php实现批量上传数据到数据库(.csv格式)的案例
2017/06/18 PHP
Laravel中日期时间处理包Carbon的简单使用
2017/09/21 PHP
php取出数组单个值的方法
2018/03/12 PHP
php 比较获取两个数组相同和不同元素的例子(交集和差集)
2019/10/18 PHP
DHTML 中的绝对定位
2006/11/26 Javascript
Javascript笔记一 js以及json基础使用说明
2010/05/22 Javascript
javascript 另一种图片滚动切换效果思路
2012/04/20 Javascript
jQuery fadeTo方法调整图片的透明度使用介绍
2013/05/06 Javascript
js禁止页面使用右键(简单示例代码)
2013/11/13 Javascript
JS判断客户端是手机还是PC的2个代码
2014/04/12 Javascript
jquery插件bxslider用法实例分析
2015/04/16 Javascript
Javascript的表单验证-提交表单
2016/03/18 Javascript
基于BootStrap Metronic开发框架经验小结【七】数据的导入、导出及附件的查看处理
2016/05/12 Javascript
微信小程序 页面跳转传参详解
2016/10/28 Javascript
JavaScript之RegExp_动力节点Java学院整理
2017/06/29 Javascript
vue项目中api接口管理总结
2018/04/20 Javascript
vue axios基于常见业务场景的二次封装的实现
2018/09/21 Javascript
Echart折线图手柄触发事件示例详解
2018/12/16 Javascript
解决ie11 SCRIPT5011:不能执行已释放Script的代码问题
2019/05/05 Javascript
js设置鼠标悬停改变背景色实现详解
2019/06/26 Javascript
利用vue3+ts实现管理后台(增删改查)
2020/10/30 Javascript
[05:06]2017亚洲邀请赛DAC回顾片
2017/04/19 DOTA
Python三级菜单的实例
2017/09/13 Python
python+selenium 脚本实现每天自动登记的思路详解
2020/03/11 Python
Python魔术方法专题
2020/06/19 Python
浅谈Python xlwings 读取Excel文件的正确姿势
2021/02/26 Python
澳大利亚最好的厨具店:Kitchen Warehouse
2018/03/13 全球购物
Scotch Porter官方网站:男士美容产品
2020/08/31 全球购物
大学中国梦演讲稿
2014/04/23 职场文书
《蚂蚁和蝈蝈》教学反思
2016/02/22 职场文书
个人工作失误的保证书怎么写?
2019/06/21 职场文书
详解nginx进程锁的实现
2021/06/14 Servers