当前位置: 首页 > article >正文

【python】游戏设计 --- 双人井字棋小游戏

1. 游戏介绍

一个简单的 python 双人井字棋小游戏

1.1 游戏规则:
  1. 双人轮流输入下入点坐标
  2. 横竖撇捺先成三点连线者胜
  3. 同一坐标点不允许重复输入
1.2 开始界面与游戏界面

2. 源代码:

def print_board(board):
    for row in board:
        print(" | ".join(row))
        print("-" * 5)

def check_winner(board, player):
    for i in range(3):
        if all([cell == player for cell in board[i]]) or \
           all([board[j][i] == player for j in range(3)]):
            return True
    if board[0][0] == player and board[1][1] == player and board[2][2] == player:
        return True
    if board[0][2] == player and board[1][1] == player and board[2][0] == player:
        return True
    return False

def check_draw(board):
    return all(all(cell != ' ' for cell in row) for row in board)

def tic_tac_toe():
    board = [[' ' for _ in range(3)] for _ in range(3)]
    current_player = 'X'

    while True:
        print_board(board)
        print(f"Player {current_player}'s turn.")
        while True:
            try:
                row = int(input("Enter the row (0, 1, 2): "))
                col = int(input("Enter the column (0, 1, 2): "))
                if row in range(3) and col in range(3):
                    if board[row][col] == ' ':
                        board[row][col] = current_player
                        break
                    else:
                        print("This cell is already taken. Please choose another one.")
                else:
                    print("Invalid input. Please enter a number between 0 and 2.")
            except ValueError:
                print("Invalid input. Please enter a valid integer.")

        if check_winner(board, current_player):
            print_board(board)
            print(f"Player {current_player} wins!")
            break
        if check_draw(board):
            print_board(board)
            print("It's a draw!")
            break
        current_player = 'O' if current_player == 'X' else 'X'

tic_tac_toe()

3. 主要函数释解:

  1. print_board(board) 函数:
    • 该函数用于打印当前棋盘的状态。
    • 参数 board 是一个二维列表,表示棋盘。
    • 使用两个嵌套的循环,外层循环遍历棋盘的每一行,内层循环使用 join 方法将每一行的元素用竖线分隔,并打印出来。
    • 每打印完一行,使用 print 函数打印一行由减号组成的分隔线。
  2. check_winner(board, player) 函数:
    • 该函数用于检查是否有玩家获胜。
    • 参数 board 是棋盘,player 是当前玩家的标记(‘X’ 或 ‘O’)。
    • 首先,检查每一行和每一列是否全部由当前玩家的标记组成。如果是,返回 True
    • 接着,检查两个对角线是否全部由当前玩家的标记组成。如果是,返回 True
    • 如果以上条件都不满足,返回 False
  3. check_draw(board) 函数:
    • 该函数用于检查棋盘是否已满,即是否出现平局。
    • 使用两个嵌套的 all 函数,外层 all 遍历每一行,内层 all 遍历每一行的每个单元格。
    • 如果所有单元格都不为空格,说明棋盘已满,返回 True。否则,返回 False
  4. tic_tac_toe() 函数:
    • 这是 主函数,用于控制整个游戏的流程。
    • 初始化一个 3x3 的棋盘,所有单元格都为空格。
    • 当前玩家初始化为 ‘X’。
    • 进入一个无限循环,直到游戏结束。
    • 在循环中,首先打印当前棋盘状态,然后提示当前玩家输入。
    • 使用 input 函数获取用户输入的行和列,并进行异常处理,确保输入的是整数。
    • 检查输入的行和列是否有效,以及对应单元格是否已被占用。如果输入无效或单元格已被占用,提示用户重新输入。
    • 在用户输入有效后,将当前玩家的标记放置在对应位置。
    • 检查是否有玩家获胜,如果有,打印获胜信息并退出循环。
    • 检查是否出现平局,如果有,打印平局信息并退出循环。
    • 如果游戏未结束,切换当前玩家。

整个代码实现了一个基本的井字棋游戏,玩家可以轮流输入行和列来放置自己的标记,直到有一方获胜或出现平局。

4. 异常处理:

该代码中包含了如下错误处理和异常处理机制,以应对用户可能输入的越界或其他无效行为。

  1. 异常处理
    • 当用户输入行和列时,代码使用 tryexcept 块来捕获 ValueError 异常。这可以处理用户输入非整数的情况。
    • 代码示例:
      try:
          row = int(input("Enter the row (0, 1, 2): "))
          col = int(input("Enter the column (0, 1, 2): "))
          # 其他逻辑...
      except ValueError:
          print("Invalid input. Please enter a valid integer.")
      
  2. 越界检查
    • 在用户输入行和列之后,代码通过条件判断来检查输入的行和列是否在有效范围内(0到2)。
    • 如果输入的行或列不在0到2的范围内,代码会打印出错误信息,并要求用户重新输入。
    • 代码示例:
      if row in range(3) and col in range(3):
          # 其他逻辑...
      else:
          print("Invalid input. Please enter a number between 0 and 2.")
      
  3. 单元格占用检查
    • 在用户输入有效的行和列之后,代码会检查该单元格是否已被占用。
    • 如果单元格已被占用,代码会打印出错误信息,并要求用户重新选择一个单元格。
    • 代码示例:
      if board[row][col] == ' ':
          board[row][col] = current_player
          break
      else:
          print("This cell is already taken. Please choose another one.")
      

通过这些机制,代码能够妥善处理用户输入的异常情况,如非整数输入、越界输入以及尝试在一个已被占用的单元格中放置标记的行为。这些错误处理确保了游戏的正常运行,避免了程序崩溃或进入无效状态。


http://www.kler.cn/a/383166.html

相关文章:

  • springBoot Maven 剔除无用的jar引用
  • 【Linux探索学习】第二十三弹——理解文件系统:认识硬件、探索文件在硬件上的存储问题
  • JavaScript中函数调用时的参数传递
  • STM32HAL库中RTC闹钟设置时分秒,年月日
  • 解释下什么是面向对象?面向对象和面向过程的区别?
  • SQL server学习09-数据库编程(上)
  • OceanBase中,如何解读 obdiag 收集的火焰图 【DBA早下班系列】
  • 刷题强训 (day1) -- 数字统计
  • 软件工程笔记一
  • Redis 数据类型详解与应用
  • 加密货币行业与2024年美国大选
  • Linux sudo命令及权限设置
  • 【MongoDB】MongoDB的Java API及Spring集成(Spring Data)
  • 免费送源码:Java+springboot+MySQL springboot 线上线下一体化的宠物交易 计算机毕业设计原创定制
  • 大语言模型在交通领域的应用分析
  • mysql知识点
  • 如何搭建在线视频流媒体服务云直播
  • 【uni-app】*.vue 与 *.uvue
  • openssl生成加密,公钥实现非对称加密
  • 鸟害防治新选择:特力康|固定式智能激光驱鸟器的优势与挑战
  • 企业如何做好进销存管理?工厂进销存实现步骤
  • 小物体检测模型
  • 全网最全软件测试面试宝典,快看!
  • 解决 Fail to pip install mlc-llm
  • scala set集合
  • ubuntu中安装mysql