两百行代码搞定!使用Python面向对象做个小游戏

开发 后端
我们今天同样实现一个小游戏,这个小游戏非常有名,我想大家都应该玩过。它就是tic tac toe,我们打开chrome搜索一下就可以直接找到游戏了。

 [[380175]]

大家好,欢迎来到Python实战专题。

我们今天同样实现一个小游戏,这个小游戏非常有名,我想大家都应该玩过。它就是tic tac toe,我们打开chrome搜索一下就可以直接找到游戏了。

由于我们使用Python来实现,并且不会制作UI界面,所以不会这么好看。虽然不够好看,但是逻辑却是一样的。并且和之前我们做的那些小游戏相比,今天做的这个游戏有一个非常大的特点就是非常适合设计AI。我们只需要用很简单的算法就可以做出一个还不错的ai来。当然我们循序渐进,先从最简单的游戏功能本身开始。

课题

今天的课题就是使用Python编写一个不带UI界面的tic tac toe的小游戏。

这一次,游戏当中会涉及两方,所以我们需要有判断游戏胜负手的相关逻辑。除此之外,由于涉及两个玩家,所以我们需要设计一个AI,让我们可以和电脑进行游戏。最后实现的效果差不多应该是这样的:

也就是在游戏一开始的时候,支持玩家选择参与游戏的两方。这里我们先把AI算法的设计放一放,可以先做出随机选择的弱智AI。

游戏开始之后,双方交替行动,每次执行都会在屏幕上输出相应的具体信息,以及棋盘当前的情况。

知识点

面向对象

tic tac的游戏虽然简单,但是它涉及的内容还是挺多的。需要棋盘,还需要玩家,还需要添加玩家以及执行步骤等等操作。这些逻辑如果不加以封装,全部都写成面向过程的话,会使得代码非常的混乱。很明显的,我们需要使用面向对象,对这些逻辑进行抽象和封装,来达到简化编码以及思考的目的。

我们目前的设计比较简单,也不需要用到继承以及抽象类等等高端的用法,就使用最基本的面向对象定义类就可以了。在Python当中定义一个类非常简单,通过关键字class完成。

比如:

  1. class Game: 
  2.     pass 

构造函数

一般来说当我们定义一个类的时候都需要为它设计构造函数,构造函数就是当我们创建这个类的实例的时候调用的方法。它会替我们完成一些初始化的工作。Python当中类的构造函数是__init__,我们直接在类当中实现它即可。

  1. class Game: 
  2.     def __init__(self): 
  3.         self.board = Board() 
  4.         self.players = [] 
  5.         self.markers = ['O''X'
  6.         self.numbers = [1, -1] 

比如在上面这个例子当中,我们就为Game这个类做了一些初始化的设定。比如给它赋予一个board以及players等等变量。

类方法

既然是类,自然会有属于类的类方法。类方法的定义和普通函数的定义是一样的,唯一不同的是它写在类的内部,并且第一个参数默认是self。self这个关键字相当于Java当中的this,指代的就是运行的时候调用方法的实例。

比如我们给Game这个类实现一个添加玩家的方法:

  1. class Game: 
  2.     def __init__(self): 
  3.         self.board = Board() 
  4.         self.players = [] 
  5.         self.markers = ['O''X'
  6.         self.numbers = [1, -1] 
  7.  
  8.  
  9.     def add_player(self, player): 
  10.         if player == 'h' or player == 'human'
  11.             self.players.append(HumanPlayer()) 
  12.         elif player == 'r' or player == 'random'
  13.             self.players.append(RandomPlayer()) 

我们看下add_player这个方法内部的逻辑,我们在这个方法当中通过self关键字调用了类实例当中的变量。这就是为什么我们需要设定一个self参数的原因,当我们调用的时候,并不需要理会self这个参数,它是Python自动为我们填充的。

当然我们定义类方法的时候也可以定义没有self参数的方法,只不过这样的方法不再属于类的实例,而属于类本身。我们想要调用的话,只能通过类名来访问。

比如:

  1. class Test: 
  2.     def say(): 
  3.         print("hello world"

在Test这个类当中我们实现了一个没有self关键字的say方法,如果我们通过Test的实例去调用它一定会出错。因为我们在通过实例调用方法的时候,Python会自动为我们把实例作为第一个参数传入。这样就导致了接受和传输的参数对应不上,于是引发报错,如果我们想要调用这个say方法,应该这样:

  1. Test.say() 

也就是说这个方法不再属于类创建的实例,而属于类本身。可以理解成Java类当中的static关键字修饰的方法。

方法的方法

Python当中对于方法的定义是比较灵活的,我们可以给一个类创建方法,同样也可以在一个方法的内部创建另外一个方法。比如下面这个例子:

  1. def outer(arg1, arg2): 
  2.      
  3.     def inner(arg1, arg2): 
  4.         return arg1 + arg2 
  5.      
  6.     return inner(arg1, arg2) 

由于Python支持函数式编程,所以方法内部的方法还可以实现像是闭包、 装饰器等等功能。不过这里我们用不到那么高端的用法,只需要会最基本的就可以了。最基本的也就是在函数内部定义一个函数,主要在这个inner函数当中是可以使用outer当中的定义的变量的。比如:

  1. def outer(arg1): 
  2.      
  3.     arg2 = 10 
  4.     def inner(arg1): 
  5.         return arg1 + arg2 
  6.      
  7.     return inner(arg1) 

上述的代码没有问题,不过还有一点需要注意。在inner当中虽然可以访问到outer中定义的参数和变量,但是它是不可以修改的。如果想要修改,需要使用nonlocal关键字声明这是一个外层变量。

比如:

  1. def outer(arg1): 
  2.      
  3.     arg2 = 10 
  4.     def inner(arg1): 
  5.         nonlocal arg2 
  6.         arg2 += 1 
  7.         return arg1 + arg2 
  8.      
  9.     return inner(arg1) 

通过在方法内实现方法,可以进一步简化函数内部代码的逻辑,把一些很复杂的函数功能进行进一步的拆分和简化。了解这个用法,也是后面学习闭包、函数式编程等进阶内容的基础。

尾声

这一次的课题相比之前的,整体的实现难度相差不大,主要是涉及的Python文件变多了,之前都是单文件运行的Python程序。这一次需要编写多个文件,以及这一次引入了面向对象的概念,需要对一些功能进行抽象。所以总体上还是有一定难度的,如果大家做不出来的话,可以点击查看原文,获取我的github地址。

在这一次的项目当中,我们创建的是最简单的随机选择的AI,完全没有任何难度。在接下来的课题当中,我们将会使用一些ai算法,给它加上一些ai,让它变得聪明起来,甚至变得不可战胜。

本文转载自微信公众号「TechFlow」,作者梁唐。转载本文请联系TechFlow公众号。

 

责任编辑:武晓燕 来源: TechFlow
相关推荐

2016-09-27 11:31:34

JavaScript编程语言

2020-12-07 16:20:53

Python 开发编程语言

2012-01-10 12:48:52

Java

2023-11-29 08:10:36

javascriptH5游戏

2022-04-19 07:45:40

代码Python美图秀秀

2019-05-05 09:46:01

Python代码神经网络

2013-08-20 18:50:46

JS模板引擎模块化Web App

2022-02-24 10:40:14

Python代码

2023-11-10 09:41:44

Python代码

2011-05-29 15:39:46

佳能喷墨打印机

2018-03-15 13:31:48

润乾LinuxGREP搜索

2019-11-18 17:05:02

JavaScript面向对象程序编程Java

2021-10-28 09:42:38

代码编码开发

2012-12-25 10:51:39

IBMdW

2012-07-03 10:25:53

HTML5

2021-11-08 07:48:48

Go语言对象

2021-04-13 06:35:13

Elixir语言编程语言软件开发

2021-08-02 13:20:31

代码Python文件

2020-04-24 12:16:48

Python 图像分类实战

2023-01-10 09:38:09

面向对象系统
点赞
收藏

51CTO技术栈公众号