热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python大作业100行代码面向对象_两百行代码搞定!使用Python面向对象做个小游戏...

大家好,欢迎来到Python实战专题。我们今天同样实现一个小游戏,这个小游戏非常有名,我想大家都应该玩过。它就是tictactoe

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

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

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

课题

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

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

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

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

知识点

面向对象

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

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

比如:class Game:

pass

构造函数

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

def __init__(self):

self.board = Board()

self.players = []

self.markers = ['O', 'X']

self.numbers = [1, -1]

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

类方法

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

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

def __init__(self):

self.board = Board()

self.players = []

self.markers = ['O', 'X']

self.numbers = [1, -1]

def add_player(self, player):

if player == 'h' or player == 'human':

self.players.append(HumanPlayer())

elif player == 'r' or player == 'random':

self.players.append(RandomPlayer())

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

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

比如:class Test:

def say():

print("hello world")

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

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

方法的方法

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

def inner(arg1, arg2):

return arg1 + arg2

return inner(arg1, arg2)

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

arg2 = 10

def inner(arg1):

return arg1 + arg2

return inner(arg1)

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

比如:def outer(arg1):

arg2 = 10

def inner(arg1):

nonlocal arg2

arg2 += 1

return arg1 + arg2

return inner(arg1)

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

尾声

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

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

感兴趣的同学不妨小小期待一下,今天的文章就到这里,感谢你的阅读。如果喜欢本文的话,不妨给个三连吧~



推荐阅读
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • 提升Python编程效率的十点建议
    本文介绍了提升Python编程效率的十点建议,包括不使用分号、选择合适的代码编辑器、遵循Python代码规范等。这些建议可以帮助开发者节省时间,提高编程效率。同时,还提供了相关参考链接供读者深入学习。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • PHP中的单例模式与静态变量的区别及使用方法
    本文介绍了PHP中的单例模式与静态变量的区别及使用方法。在PHP中,静态变量的存活周期仅仅是每次PHP的会话周期,与Java、C++不同。静态变量在PHP中的作用域仅限于当前文件内,在函数或类中可以传递变量。本文还通过示例代码解释了静态变量在函数和类中的使用方法,并说明了静态变量的生命周期与结构体的生命周期相关联。同时,本文还介绍了静态变量在类中的使用方法,并通过示例代码展示了如何在类中使用静态变量。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
author-avatar
一夜知秋50050
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有