通过游戏编程学Python

通过游戏编程学Python(3)— 赌大小
通过游戏编程学Python(2)— 脑筋急转弯
通过游戏编程学Python(1)— 猜数字


文章目录

  • 通过游戏编程学Python
  • 前言
  • 一、知识点
  • 二、第四个游戏 —— 猜成语
    • 1. 玩法简介
    • 2. 游戏流程
  • 三、程序代码
  • 四、代码详细分析
    • 1. 常量
    • 2. 面向对象
      • 字符串的split()方法
    • 3. 函数与方法
      • 方法的链式调用
    • 4. 列表
      • 调用列表元素
      • 元素的增删
      • 列表的切片操作
      • 列表的数学运算
      • len()函数
      • 字符串的列表属性
  • 总结与思考

前言

大家好,上节课我们学习了自定义函数,可以说已经前进了一大步。可以说所有的程序都是由各种类型的变量与大大小小的函数构成的,但往往这些函数的调用令人眼花缭乱,函数之间可以互相调用,甚至函数自己调用自己(递归)等等。。。大家别害怕,暂时我们还用不到这么复杂的函数,但随着我们掌握的知识越来越多,看懂了大部分程序的“套路”,一切就豁然开朗了。

上节课的小游戏已经有那么点意思了,后面几节课我们还要继续学习几个小游戏,掌握函数的用法。另外我们也要借着这几个小游戏学习容器类对象——列表、字典,以及range对象与for循环的基本用法。


一、知识点

  1. 常量
  2. 面向对象
  3. 函数与方法
  4. 列表及常用操作
  5. random模块里的其它函数(下)
  6. range对象(下)
  7. for循环(下)

二、第四个游戏 —— 猜成语

1. 玩法简介

首先准备一个四字成语词库,可多可少,不设限制(本例中准备了30个四字成语)。由计算机从里面随机抽取出一个成语,再从成语里随机取出两个汉字作为提示(如果太简单,可以改为只提示一个汉字),由玩家去猜这个成语是什么。程序会把成语里未知的部分汉字用X遮住打印出来。玩家共有6次机会,如果猜对了或者连续猜错6次,游戏结束。并询问玩家是否继续玩,如果玩家回答的不是yes或y,程序结束。

2. 游戏流程

#mermaid-svg-POjDqlnCEMDRTPdZ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-POjDqlnCEMDRTPdZ .error-icon{fill:#552222;}#mermaid-svg-POjDqlnCEMDRTPdZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-POjDqlnCEMDRTPdZ .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-POjDqlnCEMDRTPdZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-POjDqlnCEMDRTPdZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-POjDqlnCEMDRTPdZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-POjDqlnCEMDRTPdZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-POjDqlnCEMDRTPdZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-POjDqlnCEMDRTPdZ .marker.cross{stroke:#333333;}#mermaid-svg-POjDqlnCEMDRTPdZ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-POjDqlnCEMDRTPdZ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-POjDqlnCEMDRTPdZ .cluster-label text{fill:#333;}#mermaid-svg-POjDqlnCEMDRTPdZ .cluster-label span{color:#333;}#mermaid-svg-POjDqlnCEMDRTPdZ .label text,#mermaid-svg-POjDqlnCEMDRTPdZ span{fill:#333;color:#333;}#mermaid-svg-POjDqlnCEMDRTPdZ .node rect,#mermaid-svg-POjDqlnCEMDRTPdZ .node circle,#mermaid-svg-POjDqlnCEMDRTPdZ .node ellipse,#mermaid-svg-POjDqlnCEMDRTPdZ .node polygon,#mermaid-svg-POjDqlnCEMDRTPdZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-POjDqlnCEMDRTPdZ .node .label{text-align:center;}#mermaid-svg-POjDqlnCEMDRTPdZ .node.clickable{cursor:pointer;}#mermaid-svg-POjDqlnCEMDRTPdZ .arrowheadPath{fill:#333333;}#mermaid-svg-POjDqlnCEMDRTPdZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-POjDqlnCEMDRTPdZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-POjDqlnCEMDRTPdZ .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-POjDqlnCEMDRTPdZ .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-POjDqlnCEMDRTPdZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-POjDqlnCEMDRTPdZ .cluster text{fill:#333;}#mermaid-svg-POjDqlnCEMDRTPdZ .cluster span{color:#333;}#mermaid-svg-POjDqlnCEMDRTPdZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-POjDqlnCEMDRTPdZ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

yes
no
yes
no
no
no
yes
yes
游戏开始
请玩家选择难度(提示一个或两个汉字)
电脑随机抽出一个神秘成语
显示成语的一部分并列出玩家猜错的词
请玩家猜四字成语
玩家是否输入四个字
该四字是否就是神秘成语
游戏结束,询问玩家是否再玩一次
程序结束
玩家是否还有机会

三、程序代码

全部代码如下:

import randomWORD = '''春风化雨 天罗地网 一心一意 一言为定 头头是道 助人为乐 井井有条 乐极生悲 万水千山 桃红柳绿
贪生怕死 走马观花 一路平安 莺歌燕舞 鸟语花香 目中无人 旁若无人 百发百中 安居乐业 拔苗助长 风和日丽
风平浪静 东山再起 马到成功 满面春风 毛手毛脚 长年累月 面目全非 天网恢恢 瓜田李下'''.split()def 难度选择():# 玩家选择难度:提示一个汉字还是两个汉字难度 = ''while 难度 != '1' and 难度 != '2':print('请选择游戏难度:(1-简单,2-困难)')难度 = input()if 难度 == '1':return 2else:return 1def 显示状态(提示字, 电脑选词):# 打印出提示字在成语中的位置填空 = 'XXXX'for i in 提示字: # 把X换成提示字填空 = 填空[:i] + 电脑选词[i] + 填空[i+1:]for 字 in 填空: # 汉字之间加上空格打印出来print(字, end=' ')print('\n')def 猜字母(猜过啥):# 确保玩家输入四个字,且不会重复输入错误的词,并返回玩家猜的汉字while True:print('猜猜看,这是什么成语呢?')print()猜 = input()if len(猜) != 4:print('请输入一个四字成语')print()elif 猜 in 猜过啥:print('这个词你已经猜过了,换一个试试吧')print()else:return 猜def 再玩一次():# 如果玩家输入yes或y,则游戏从头再来,否则游戏结束print('还要继续玩吗?(yes-是,no-否)')return input().lower().startswith('y')print('《 开 心 猜 成 语 》\n')提示字数 = 难度选择()
提示字 = random.sample(range(4), 提示字数)
错词表 = []
游戏结束 = False
电脑选词 = random.choice(WORD)while True:显示状态(提示字, 电脑选词)# 请玩家猜一个四字成语猜 = 猜字母(错词表)if 猜 == 电脑选词:# 如果猜对了游戏结束print('没错!就是“' + 电脑选词 + '”!你赢了!')游戏结束 = Trueelse:print('不对哦~\n')错词表.append(猜)# 检查玩家是否猜错太多次if len(错词表) == 6:显示状态(提示字, 电脑选词)print('很遗憾,你已经猜错' + str(len(错词表)) + '次,游戏结束。' + '正确的成语是“' + 电脑选词 + '”。')游戏结束 = True# 询问玩家是否再玩一次if 游戏结束:if 再玩一次():提示字数 = 难度选择()提示字 = random.sample(range(4), 提示字数)错词表 = []游戏结束 = False电脑选词 = random.choice(WORD)else:break

四、代码详细分析

1. 常量

顾名思义,常量保存的内容在整个程序里不会被改变。由于某个值在程序里可能会被经常用到,将这个值保存起来,起个名字,更方便调用,也更方便维护。

比如本例中,WORD这个常量,作为一个成语库,保存了我们要用到的成语,内容较多。而且以后可能需要向里面添加新的成语,所以将其保存在一个常量里,更加方便调用和修改。

WORD = '''春风化雨 天罗地网 一心一意 一言为定 头头是道 助人为乐 井井有条 乐极生悲 万水千山 桃红柳绿
贪生怕死 走马观花 一路平安 莺歌燕舞 鸟语花香 目中无人 旁若无人 百发百中 安居乐业 拔苗助长 风和日丽
风平浪静 东山再起 马到成功 满面春风 毛手毛脚 长年累月 面目全非 天网恢恢 瓜田李下'''.split()

但是实际上Python并没有严格地定义常量这个概念,所以也没有给出声明常量的关键字。换句话说,Python里的常量也是变量,改不改变它的值,全靠程序员自己注意。尽管如此,为了便于别人阅读代码,也提醒自己不要随意修改常量的值,一般定义常量默认遵从以下规则:

  1. 使用全大写字母命名。在以往的程序里,问哥为了接地气,都尽量使用中文声明变量。这次考虑到区分常量,使用了全大写的WORD来保存成语词库,使其更加醒目。
  2. 在程序的开头声明常量。

2. 面向对象

大家千万不要一提到“面向对象编程”就感到头疼,其实没那么复杂,这全是英文翻译的锅。问哥觉得,可能翻译成“基于对象编程”会更加贴切。而且“对象”也是由英文单词Object翻译过来,而Object本意其实是指“某个东西”。所以大家把“对象”理解成一个“东西”就可以了,只不过要把这些“对象”拟人化。我们人类有个性化信息(比如名字、住址等)、可以做事情(比如吃饭、穿衣服等),对应的,程序里“对象”的信息叫做“属性”、可以做的事情叫做“方法”。

Python就是基于对象的编程语言,可以说,在Python里万事万物都是对象。调用Python里对象的属性和方法,只需要在对象名字后面加个点(“.”),再跟上属性或方法名即可。我们读程序的时候,可以直接把点(“.”)读成“的”。

字符串的split()方法

回到我们的程序里来,不知道大家有没有注意到,常量WORD其实是接收了一个长的字符串对象的split()方法运行后返回的结果。任何字符串都有split()方法。这个方法的作用是:以括号里接收的字符去分割字符串,如果括号里什么都没有,则默认使用空格分割,然后把分割后的一个个小字符串,按顺序保存在一个列表里并返回。所以WORD其实是包含了三十个成语(小字符串)的列表(list)。

关于列表的一些常用操作,我们稍候就会聊到,现在先让我们看看什么是方法。

3. 函数与方法

我们在前面已经学习了函数,不管是系统自带的函数,或者自定义函数,都是一段子程序,执行一段代码、实现某个功能。仔细想一想,这和对象的“方法”的作用是不是一样的呢?没错,其实所谓的“方法”就是对象所在的类中定义的函数,也是一段子程序而已(同理,所谓的“属性”其实也就是对象内部定义的变量)。同函数一样,有些方法有返回值,有些则没有。在以后的例子中,我们会逐渐接触到各种各样的方法,这其实并没有多么神秘,只是需要慢慢积累和总结。

方法的链式调用

如果方法(或函数)的返回值本身还有方法可以调用,可以直接用点“.”把方法连起来写在一行,像链条一样。比如本例中再玩一次() 的自定义函数里的return语句:

def 再玩一次():# 如果玩家输入yes或y,则游戏从头再来,否则游戏结束print('还要继续玩吗?(yes-是,no-否)')return input().lower().startswith('y')

我们知道,input()函数用来获取用户从键盘输入的信息,返回一个字符串,而字符串有一个方法叫做lower(),该方法将字符串的所有字母转换成小写字母,再返回一个新的字符串,而新的字符串又调用了自身的方法startswith(),来检查字符串是否以某个字符开头(本例中判断用户输入的是不是以字母‘y’开头,如果用户输入大写Y,会先被转换小写字母),返回一个布尔值(True或False),最后函数将布尔值返回到主程序。

如果使用临时变量a、b、c将这根“链条”拆解开的话,会是如下语句。

 a = input()b = a.lower()c = b.startswith('y')return c

而使用链式调用,完全不需要这些临时变量,代码也变得更加简洁,一行代码就完成了上面四行代码的工作。

4. 列表

今天我们终于接触到第一个容器类对象——列表(没错,列表也是“对象”)。列表可以简单地看成是像其他编程语言里数组一样的容器,里面有序地保存了一系列的数据。这些数据可以都是一个类型(比如下面例子里列表a的成员全是整数),也可以是完全不同的数据类型,甚至包括列表(嵌套)。

调用列表元素

列表是有序的,其中每个元素按列出的顺序都有自己的索引值。当我们需要调用或修改列表中的某个元素时,可以使用“列表名[索引值]”的形式。要注意的是,列表的索引是从0开始。a[0]就是代表列表a里的第一个元素,a[1]代表第2个,依次类推。

如果想要调用列表里最后一个元素,却不知道其索引值的话,可以使用“列表名[-1]”,同样,a[-2]代表列表a的倒数第二个元素,a[-3]代表倒数第三个,以此类推。

元素的增删

向现有列表里增加一个元素,最常用的的是使用列表的append()方法。比如a.append(‘abc’)将把字符串abc作为最后一个元素添加进列表a。

删除某个元素则有很多方法:

  1. 使用列表的remove()方法。比如a.remove(‘abc’)将把列表a里的字符串abc删除。但是要注意的是,如果列表a里存在多个相同的字符串abc,remove()方法只会删除第一个。
  2. 使用del。比如del a[0]会把列表a里第一个元素删掉,这种方法的好处是可以根据列表索引精确定位到想要删除的元素。
  3. 使用列表的pop()方法。该方法是把列表最后一个元素从列表中“弹”出,所以可以使用一个变量接收这个元素。比如 b = a.pop() 就把列表a里的最后一个元素从列表里移除,保存到变量b里。

列表的切片操作

可以使用“列表[索引:索引]”的形式对列表进行切片,中括号里冒号左边代表切片的起始索引值,右边代表切到哪个索引值的元素之前

比如a[1:5]表示切出列表a的第二个元素到第五个元素(a[5]代表第六个元素,所以冒号右边的数字代表切到这个元素之前,也就是第五个元素)。如果省略左边的数字,a[:5]则表示从第一个元素切到第五个元素;如果省略右边的数字,a[1:]则表示从第二个元素切到最后一个元素。

注意:列表的切片操作会返回一个新的列表,并不会修改原列表。

切片操作引申出一种复制列表的用法,就是只使用冒号,而省略左右的索引值,意思是从头切到尾,把所有元素都复制出来,形成一个新的列表。比如 b = a[:] 表示把列表a的所有元素复制一份,保存到一个新的列表,赋值给b,所以列表b和a的列表内容完全一样,却是完全不同的两个列表。

注意:复制列表不能使用赋值语句。b = a 不会产生新的列表,只表示变量b和a都指向同一个列表。这一点在以后的例子中还会经常看到。

列表的数学运算

列表加(“+”)列表会将两个列表的元素按先后顺序合在一起,返回一个新的列表。

列表乘(“*”)一个数字N,表示将列表里的元素重复N次,返回一个新的列表。

这些小技巧在创建列表的时候非常有用,比如要创建一个含有9个1的列表a,可以直接写 a = [1] * 9 。

len()函数

和列表配合使用的len()函数可以轻松得到列表的元素个数。

字符串的列表属性

值得注意的是,字符串也可以看成是一个由单个字符或汉字作为元素的列表。比如字符串“一帆风顺”,可以看成是由四个元素“一”、“帆”、“风”、“顺” 组成的一个特殊的“列表”,字符串"Hello"则可以看成是由五个元素"H"、“e”、“l”、“l”、“o” 组成的“列表”。所以字符串同样可以像列表那样,使用len(字符串)函数得到某个字符串里的字符个数、通过索引调用单个字符、使用切片操作调用某个范围的字符。

这在字符串的处理中经常被用到,请大家注意。比如本例中就使用了切片,将原本内容为"xxxx"的含有四个字符的字符串填空,按照 i 所代表的索引值,将对应的字符替换成电脑选词对应位置的汉字,从而达到“提示汉字”的效果。

    填空 = 填空[:i] + 电脑选词[i] + 填空[i+1:]

总结与思考

很抱歉,问哥又啰啰嗦嗦了一大堆,而且不得已,要把全部内容一分为二,剩下的部分下节课再讲。其实问哥原本只是想借着分析游戏代码的机会,把看到和用到的语法讲解一下,顺便介绍一些Python的基础知识。没想到要把基础知识讲清楚,并不是一件容易的事。如果有可能,问哥将来宁愿进行视频讲解,通过现场演示把知识点讲透,这可比码字容易多了,也清楚多了。

在刚开始接触一门新语言的时候,学习语法是必要的,但却不是最重要的。因为最重要的事情,永远都是练、练、练。大家一起加油!

通过游戏编程学Python(4)— 猜成语(上)相关推荐

  1. 通过游戏编程学Python(5)— 猜成语(下)

    通过游戏编程学Python 通过游戏编程学Python(4)- 猜成语(上) 通过游戏编程学Python(3)- 赌大小 通过游戏编程学Python(2)- 脑筋急转弯 通过游戏编程学Python(1 ...

  2. 通过游戏编程学Python(1)— 猜数字

    通过游戏编程学Python 通过游戏编程学Python(1)- 猜数字 文章目录 通过游戏编程学Python 前言 一.知识点 二.第一个游戏 -- 猜数字 1. 玩法简介 2. 游戏流程 三.程序代 ...

  3. 通过游戏编程学Python(6)— 英汉词典、背单词

    通过游戏编程学Python 通过游戏编程学Python(番外篇)- 乱序成语.猜单词 通过游戏编程学Python(5)- 猜成语(下) 通过游戏编程学Python(4)- 猜成语(上) 文章目录 通过 ...

  4. 通过游戏编程学Python(番外篇)— 单词小测验

    通过游戏编程学Python 通过游戏编程学Python(6)- 英汉词典.背单词 通过游戏编程学Python(番外篇)- 乱序成语.猜单词 通过游戏编程学Python(5)- 猜成语(下) 通过游戏编 ...

  5. 通过游戏编程学Python(3)— 赌大小

    通过游戏编程学Python 通过游戏编程学Python(2)- 脑筋急转弯 通过游戏编程学Python(1)- 猜数字 文章目录 通过游戏编程学Python 前言 一.知识点 二.第三个游戏 -- 赌 ...

  6. 通过游戏编程学Python(2)— 脑筋急转弯

    通过游戏编程学Python 通过游戏编程学Python(2)- 脑筋急转弯 通过游戏编程学Python(1)- 猜数字 文章目录 通过游戏编程学Python 前言 一.知识点 二.第二个游戏 -- 脑 ...

  7. 游戏编程学Python(8)— 扫雷(文字版)

    通过游戏编程学Python(7)- 井字棋(下) 通过游戏编程学Python(7)- 井字棋(上) 通过游戏编程学Python(番外篇)- 单词小测验 前言 前一段时间扫雷游戏挺火的,可惜问哥没有赶上 ...

  8. 通过游戏编程学Python(7)— 井字棋(下)

    通过游戏编程学Python 通过游戏编程学Python(7)- 井字棋(上) 通过游戏编程学Python(番外篇)- 单词小测验 通过游戏编程学Python(6)- 英汉词典.背单词 文章目录 通过游 ...

  9. 小学生python编程写游戏_教你如何像玩游戏一样学Python

    原标题:教你如何像玩游戏一样学Python 在编程世界,关于哪个语言是最好的争论从未停止,虽然道理谁也不服谁,但是关于编程的热度,我们可以从TIOBE 编程语言排行榜中得到结果. ▲用Python进行 ...

最新文章

  1. UBUNTU下SUBLIME TEXT3的安装+破解+汉化+中文输入
  2. TMG2010 之创建访问规则
  3. java中JList的setSelectionMode()详解
  4. OpenCV运行分类深度学习网络的实例(附完整代码)
  5. Linux下进程通信的八种方法
  6. asp.net 得到上一页地址
  7. createprocess重启程序_win32取CreateProcess启动程序的返回值
  8. apache Apache winnt_accept: Asynchronous AcceptEx failed 错误的解决
  9. 弱鸡儿长乐爆零旅Day5
  10. hadoop常见问题汇总
  11. 怎样在安卓中实现在锁屏状态下弹出对话框,并可以震动和铃声,就像闹钟似的?...
  12. 课堂对Complex类运算符重载的小练习
  13. 真羡慕那些能够过目不忘的人
  14. 2016年4月计算机网络原理,2015年4月04741计算机网络原理试题及答案
  15. 惠普打印机故障代码_惠普打印机故障代码
  16. fastboot usb 驱动相关
  17. 在微信公众平台做HTML5游戏经验谈
  18. matlab神经网络预测数据,Matlab神经网络预测复数
  19. 220kv变电站计算机监控系统网络结构图,变电站二次系统设计计算机监控系统组屏(柜)方案...
  20. 奥城大学计算机专业,2018年美国大学硕士双录取最全名单

热门文章

  1. 3G/4G路由器方案之外置硬件看门狗设计
  2. WEB 在线相册小系统
  3. K-hop消息传递图神经网络的表达能力有多强?
  4. Windows 12 UI界面抢先看
  5. 基于U-Net 的图像分割(使用Crack 500数据集)
  6. nginx一会儿正常,一会儿404,nginx一会儿访问网页1,一会儿访问网页2
  7. C6678板卡学习资料:202-基于TI DSP TMS320C6678、Xilinx K7 FPGA XC7K325T的高速数据处理核心板
  8. 灵活就业身份参加社保,怎样才能以工人身份退休?
  9. BZOJ 3165 Heoi2013 Segment 线段树
  10. 一键卸载cad,强力卸载cad,强力删除autodesk,完美卸载max,彻底卸载revit,彻底删除autodesk的任何软件