首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
第 13章 性能测量和大O算法分析
13.1 timeit模块
13.2 cProfile分析器
13.3 大O算法分析
13.4 大O阶
13.4.1 使用书架打比方描述大O阶
13.4.2 大O 测量的是最坏情况
13.5 确定代码的大O 阶
13.5.1 为什么低阶项和系数不重要
13.5.2 大O 分析实例
13.5.3 常见函数调用的大O 阶
13.5.4 一眼看出大O 阶
13.5.5 当n 很小时,大O并不重要,而n通常都很小
第 14章 项目实战
14.1 汉诺塔
14.1.1 汉诺塔输出
14.1.2 汉诺塔源代码
14.1.3 汉诺塔编写代码
14.2 四子棋
14.2.1 四子棋输出
14.2.2 四子棋源代码
14.2.3 四子棋编写代码
第 15章 面向对象编程和类
15.1 拿现实世界打比方:填写表格
15.2 基于类创建对象
15.3 创建一个简单的类——WizCoin
15.3.1 方法__init__()和self
15.3.2 特性
15.3.3 私有特性和私有方法
15.4 函数type()和特性__qualname__
15.5 非OOP 和OOP 的例子:井字棋
15.6 为现实世界设计类是一件难事儿
第 16章 面向对象编程和继承
16.1 继承的原理
16.1.1 重写方法
16.1.2 super()函数
16.1.3 倾向于组合而非继承
16.1.4 继承的缺点
16.2 函数isinstance()和issubclass()
16.3 类方法
16.4 类特性
16.5 静态方法
16.6 何时应该使用类和静态的面向对象特性
16.7 面向对象的行话
16.7.1 封装
16.7.2 多态性
16.8 何时不应该使用继承
16.9 多重继承
16.10 方法解析顺序
第 17章 Python 风格的面向对象编程:属性和魔术方法
17.1 属性
17.1.1 将特性转换为属性
17.1.2 使用setter 验证数据
17.1.3 只读属性
17.1.4 什么时候应该使用属性
17.2 Python 的魔术方法
17.2.1 字符串表示魔术方法
17.2.2 数值魔术方法
17.2.3 反射数值魔术方法
17.2.4 原地魔术方法
17.2.5 比较魔术方法
当前位置:
首页>>
技术小册>>
Python编程轻松进阶(五)
小册名称:Python编程轻松进阶(五)
### 15.5 非OOP 和OOP 的例子:井字棋 在Python编程的旅途中,理解面向对象编程(OOP)与非面向对象编程(非OOP)的区别与优势是至关重要的。井字棋(Tic-Tac-Toe),作为一种简单却经典的两人游戏,为我们提供了一个绝佳的实践平台,用以对比和展示这两种编程范式。本章节将通过实现井字棋游戏的两个版本——一个基于非OOP方式,另一个采用OOP方式,来深入探讨这两种编程风格的特点。 #### 15.5.1 井字棋游戏概述 井字棋,也被称为三子棋或圈圈叉叉,是一种在3x3格子上进行的两人回合制游戏。游戏双方轮流在格子中放置自己的标记(通常是X和O),首先连成一线(横、竖、斜)的玩家获胜。若所有格子都被填满且无人获胜,则游戏平局。 #### 15.5.2 非OOP版本的井字棋 **步骤1:初始化棋盘** 非OOP版本的井字棋通常使用列表(或其他数据结构)来直接表示棋盘。例如,可以使用一个二维列表来存储每个格子的状态(空、X、O)。 ```python def initialize_board(): return [[' ' for _ in range(3)] for _ in range(3)] board = initialize_board() ``` **步骤2:打印棋盘** 定义一个函数来打印当前的棋盘状态。 ```python def print_board(board): for row in board: print('|'.join(row)) print('-' * 7) ``` **步骤3:玩家输入与棋盘更新** 通过接收玩家输入的行和列号来更新棋盘。 ```python def update_board(board, player, row, col): if board[row][col] == ' ': board[row][col] = player else: print("该位置已被占用,请重新输入!") def get_move(player): while True: try: row = int(input(f"{player}的回合,请输入行号(1-3): ")) - 1 col = int(input(f"请输入列号(1-3): ")) - 1 if 0 <= row < 3 and 0 <= col < 3: return row, col else: print("输入的行号或列号超出范围,请重新输入!") except ValueError: print("请输入有效的数字!") # 游戏循环(简化版,未包含胜负判断) while True: # 玩家X和玩家O轮流输入 row, col = get_move('X') update_board(board, 'X', row, col) print_board(board) # ... 类似地处理玩家O的回合 ... ``` **注意**:上述代码片段未包含完整的游戏逻辑,如检查胜负、处理平局等,仅用于展示非OOP的基本结构。 #### 15.5.3 OOP版本的井字棋 在OOP版本中,我们会定义一些类来表示游戏中的不同实体,如`Board`(棋盘)、`Player`(玩家)以及`Game`(游戏)等。 **步骤1:定义棋盘类** ```python class Board: def __init__(self): self.grid = [[' ' for _ in range(3)] for _ in range(3)] def update(self, row, col, player): if self.grid[row][col] == ' ': self.grid[row][col] = player else: print("该位置已被占用,请重新输入!") def print_board(self): for row in self.grid: print('|'.join(row)) print('-' * 7) # 实例化棋盘 board = Board() ``` **步骤2:定义玩家类(可选)** 虽然对于井字棋来说,玩家类可能不是必需的,但为了演示OOP,我们可以简单定义一个。 ```python class Player: def __init__(self, marker): self.marker = marker # 示例用法:player_x = Player('X') ``` **步骤3:游戏逻辑** 游戏逻辑通常不直接封装在类中,但可以作为一个单独的函数或另一个类(如`Game`)的方法。这里我们继续使用函数来管理游戏流程。 ```python def play_game(): board = Board() players = ['X', 'O'] current_player = 0 while True: # 获取玩家输入并更新棋盘 row, col = get_move(players[current_player]) # 假设get_move已修改以返回正确值 board.update(row, col, players[current_player]) board.print_board() # 检查胜负或平局(此处省略具体实现) # 切换玩家 current_player = 1 - current_player # 调用游戏函数 play_game() ``` #### 15.5.4 比较与总结 **非OOP的优势**: - 对于小型、简单的项目,非OOP代码可能更直观、易于理解。 - 减少了类的定义和维护成本。 **OOP的优势**: - 提高了代码的可重用性、可维护性和可扩展性。 - 通过封装、继承和多态等特性,促进了更好的代码组织和模块化。 - 使得复杂系统的构建和管理变得更加容易。 在井字棋这个例子中,虽然非OOP版本已经足够处理游戏的基本逻辑,但当我们考虑更复杂的游戏或需要更多游戏功能的扩展时,OOP版本将展现出其显著的优势。通过定义清晰的类和对象,我们能够更灵活地添加新功能、调整游戏规则,并更容易地实现代码的重用和测试。 因此,在实际项目开发中,选择OOP还是非OOP,应基于项目的具体需求、团队的技术栈以及预期的维护和发展需求来综合考虑。
上一篇:
15.4 函数type()和特性__qualname__
下一篇:
15.6 为现实世界设计类是一件难事儿
该分类下的相关小册推荐:
Python合辑9-判断和循环
Python数据分析与挖掘实战(下)
Python合辑7-集合、列表与元组
Python机器学习实战
Python与办公-玩转Excel
Python3网络爬虫开发实战(下)
Python合辑12-面向对象
Python与办公-玩转PPT
Python编程轻松进阶(二)
Python编程轻松进阶(一)
Python与办公-玩转PDF
Python编程轻松进阶(三)