Python纯函数实现井字棋游戏详解

周予安
周予安
发布时间:2026-10-13 | 2人浏览过
原创

本文详细介绍如何使用Python纯函数构建井字棋游戏。通过定义全局常量、核心逻辑函数及主循环,实现人机交互与胜负判定。代码采用模块化设计,涵盖棋盘初始化、玩家与电脑走棋逻辑及最终结果展示,适合Python初学者理解函数式编程在游戏开发中的应用。

全局变量定义

首先定义游戏所需的全局变量。其中,X 和 O 分别代表两名玩家的棋子标识;EMPTY 用于表示棋盘上尚未落子的空位;TIE 代表平局状态;NUM_SQUARES 设定棋盘总格数为 9。这些常量构成了游戏状态的基础数据结构。

核心数据常量


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

辅助函数实现

接着定义游戏运行过程中调用的辅助函数。包括 ask_yes_no 用于获取用户的是否确认输入;ask_number 用于获取指定范围内的整数输入;pieces 函数决定人类玩家与计算机谁先手;new_board 负责初始化一个空的 9 格棋盘;display_board 用于在控制台打印当前棋盘布局。

交互与棋盘管理函数


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('你很厉害嘛,能跟计算机打成平手。')

主游戏逻辑

定义游戏的主逻辑函数 main。该函数依次执行:显示游戏操作指南、决定先行方、初始化棋盘并显示初始状态。随后进入主循环,只要未分出胜负且非平局,循环继续。在循环中,根据当前回合判断是执行人类玩家走棋还是计算机走棋,更新棋盘状态并显示,然后切换回合。循环结束后,判定获胜者并调用祝贺函数。

游戏流程控制


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) # 向获胜方表示祝贺或声明是平局

程序启动入口

最后,调用 main 函数启动游戏程序,并通过 input 等待用户按键以退出程序。这确保了程序在运行结束后不会立即关闭,方便用户查看结果。

执行与退出处理


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

Jupyter环境演练

在 Jupyter 环境中演练上述代码的执行流程,具体运行截图如下所示。

总结

以上即为本文的全部内容,希望这些代码示例能对您的学习有所帮助,也欢迎大家继续支持本站获取更多技术资源。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表