基于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爬虫利用cookie实现模拟登陆实例详解
Jan 12 Python
浅谈python中copy和deepcopy中的区别
Oct 23 Python
Python实现简单求解给定整数的质因数算法示例
Mar 25 Python
Python异常处理操作实例详解
Aug 28 Python
Python一个简单的通信程序(客户端 服务器)
Mar 06 Python
python使用pandas处理大数据节省内存技巧(推荐)
May 05 Python
python使用writerows写csv文件产生多余空行的处理方法
Aug 01 Python
详解Python并发编程之创建多线程的几种方法
Aug 23 Python
Django通用类视图实现忘记密码重置密码功能示例
Dec 17 Python
pytorch:torch.mm()和torch.matmul()的使用
Dec 27 Python
Pytorch之view及view_as使用详解
Dec 31 Python
Python+Django+MySQL实现基于Web版的增删改查的示例代码
May 13 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
PHP的FTP学习(一)
2006/10/09 PHP
PHP中其实也可以用方法链
2011/11/10 PHP
Notice: Trying to get property of non-object problem(PHP)解决办法
2012/03/11 PHP
[原创]php实现子字符串位置相互对调互换的方法
2016/06/02 PHP
Yii 2.0实现联表查询加搜索分页的方法示例
2017/08/02 PHP
JS控制显示隐藏兼容问题(IE6、IE7、IE8)
2010/04/01 Javascript
js操作数组函数实例小结
2015/12/10 Javascript
jquery实现全选和全不选功能效果的实现代码【推荐】
2016/05/05 Javascript
js 上传文件预览的简单实例
2016/08/16 Javascript
基于javascript实现的快速排序
2016/12/02 Javascript
轻松理解Javascript变量的相关问题
2017/01/20 Javascript
Vue用v-for给src属性赋值的方法
2018/03/03 Javascript
Vue引入sass并配置全局变量的方法
2018/06/27 Javascript
vue 导航锚点_点击平滑滚动,导航栏对应变化详解
2020/08/10 Javascript
[47:53]DOTA2上海特级锦标赛主赛事日 - 1 败者组第一轮#2COL VS Spirit
2016/03/02 DOTA
[58:09]Spirit vs NB Supermajor小组赛 A组败者组决赛 BO3 第三场 6.2
2018/06/03 DOTA
[36:09]Secret vs VG 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.24
2019/09/10 DOTA
easy_install python包安装管理工具介绍
2013/02/10 Python
使用python统计文件行数示例分享
2014/02/21 Python
详解Python多线程
2016/11/14 Python
利用Anaconda简单安装scrapy框架的方法
2018/06/13 Python
[原创]Python入门教程4. 元组基本操作
2018/10/31 Python
PyCharm-错误-找不到指定文件python.exe的解决方法
2019/07/01 Python
python实现的读取网页并分词功能示例
2019/10/29 Python
Python re正则表达式元字符分组()用法分享
2020/02/10 Python
如何基于Python爬取隐秘的角落评论
2020/07/02 Python
英国的知名精品百货公司:House of Fraser(福来德)
2016/08/14 全球购物
英语专业个人求职自荐信
2013/09/21 职场文书
教师产假请假条
2014/04/10 职场文书
药剂专业求职信
2014/06/20 职场文书
金融专业毕业生自荐信
2014/06/26 职场文书
欢迎领导标语
2014/06/27 职场文书
国庆放假通知怎么写
2015/07/30 职场文书
Oracle11g R2 安装教程完整版
2021/06/04 Oracle
SQL Server 忘记密码以及重新添加新账号
2022/04/26 SQL Server
Java实现贪吃蛇游戏的示例代码
2022/09/23 Java/Android