“笨办法”学Python 3 ——练习43 面向对象的分析和设计基础

编程入门 行业动态 更新时间:2024-10-10 00:28:48

“笨办法”学Python 3 ——练习43 <a href=https://www.elefans.com/category/jswz/34/1769334.html style=面向对象的分析和设计基础"/>

“笨办法”学Python 3 ——练习43 面向对象的分析和设计基础

练习43 面向对象的分析和设计基础

面向对象编程(OOP)方式构建的基本流程

这是一种“自上而下”(top down))的方式,它从非常抽象、松散的想法开始,然后慢慢提炼,直到想法变得具体。
1、把要解决的问题写下来,或者画出来(问题描述、结构关系图等)
2、将第一条中的关键概念提取出来并加以研究(问题名词、动词提取到代码命名中)
3、创建一个类层次结构和对象图(结构关系图、父类子类、函数方法的关系)
4、用代码实现各个类,并写一个测试来运行它们(骨架代码逐步细化)
5、重复上述步骤并细化代码

一个简单的游戏引擎分析

**游戏名:**来自25号行星的哥顿人

一、写或者画出这个问题

游戏描述:“外星人入侵了一艘宇宙飞船,我们的英雄必须穿过迷宫般的房间打败他们,这样他才能逃到逃生舱去到下面的星球。游戏更像是 Zork 之类的文字冒险游戏,并且有着很有意思的死亡方式。这款游戏的引擎会运行一张满是房间或场景的地图。当玩家进入游戏时,每个房间都会打印自己的描述,然后告诉引擎下一步该运行地图中的哪个房间。”
场景描述:
死亡(Death):玩家死的时候,会非常有意思。
中央走廊(Central Corridor):这是起点,已经有一个哥顿人站在那里,在继续之前,玩家必须用一个笑话来击败他。
激光武器军械库(Laser Weapon Armory):这是英雄在到达逃生舱之前用中子弹炸毁飞船的地方。这里有一个键盘,英雄必须猜出数字。
桥(The Bridge):另一个和哥顿人战斗的场景,英雄在这里放置了炸弹。
逃生舱(Escape Pod):英雄逃脱的地方,前提是他猜出正确的逃生舱。

二、抽取关键概念并予以研究

提取名词列表:
Alien(外星人)
Player(玩家)
Ship(飞船)
Maze(迷宫)
Room(房间)
Scene(场景)
Gothon(哥特人)
Escape Pod(逃生舱)
Planet(行星)
Map(地图)
Engine(引擎)
Death(死亡)
Central Corridor(中央走廊)
Laser Weapon Armory(激光武器军械库)
The Bridge(桥)

三、为这些概念创建类的层级结构和对象地图

可以发现“场景”和“房间”基本上是一个东西,所以可以使用“场景”来代替“房间”,而“死亡”适合“死亡场景”,就将其归为“场景”,“迷宫”和“地图”大致一样,就用“地图”。
创建类的层级结构:
Map
Engine
Scene
-Death
-Central Corridor
-Laser Weapon Armory
-The Bridge
-Escape Pod
添加动词结构:
Map
– next_scene
– opening_scene
Engine
– play
Scene
– enter
-Death
-Central Corridor
-Laser Weapon Armory
-The Bridge
-Escape Pod

四、编写类代码并通过测试来运行

根据类和函数的树状图,把它们编辑成类。(类和函数树状图从下到上写类)

#场景-类,enter-函数
class Scene(object):def enter(self):pass#引擎-类,play-函数
class Engine(object):def __init__(self, scene_map):passdef play(self):pass#Scene的子类
class Death(Scene):def enter(self):passclass CentralCorridor(Scene):def enter(self):passclass LaserWeaponArmory(Scene):def enter(self):passclass TheBridge(Scene):def enter(self):passclass EscapePod(Scene):def enter(self):pass# 地图-类。next_scene-函数,opening_scene-函数
class Map(object):def __init__(self, start_scene):passdef next_scene(self, Scene_name):passdef opening_scene(self):passa_map = Map('central_corridor') #地图初始场景
a_game = Engine(a_map) #游戏引擎
a_game.play() #游戏启动

五、重复和改进

不断的循环上面的步骤,逐步细化。
它不仅仅是一个单一层面上做的事,而是遇到一个特定的问题时,可以在每个层面上做的事情。例如不知道怎么写 Engine.play 这个方法。可以停下来,把整个过程专注在这一个函数上来弄明白代码应该怎么写。

自上而下 vs 自下而上

从写代码开始,然后逐渐“上升”到抽象的概念,这种方式被称为“自下而上”。它的步骤大致如下:
1.从问题中拿出一小部分,开始写简单的能运行的代码。
2.然后用类和自动化测试来把代码改进地更正式一些。
3.抽象出你所使用的关键概念,试着探究一下它们。
4.针对正在发生的事情写一段描述。
5.回过头去继续改进代码,也可能把之前写的删掉重新开始。
6.转到这个问题的其他部分,然后重复以上步骤。
这个过程只有在你对编程已经比较熟练并且面对问题能够自然使用编程思维的情况下才会更好,同时,当你知道整个工程的一小部分、却对全局概念的信息掌握不全的时候,这个方法也很好用。

“来自25号行星的哥顿人”游戏代码

1.导入游戏代码所需要的库(包)

from sys import exit  #退出程序。退出python程序首选方法
from random import randint #随机数取整
from textwrap import dedent #删除字符串中的前导空格

2.在代码框架中,细化第一个父类,具有所有场景都具有的公共功能。

class Scene(object):def enter(self):print("This scene is not yet configured.") #这个场景还没有被设置print("Subclass it and implemet enter().") #设置其子类并且执行enter()函数exit(1) #出现程序异常退出程序

3.Engine类,其中Map.opening_sceneMap.next_scene已经使用,在这里已经提前计划好了,后面在Map类中会将这些方法写出来。

class Engine(object):def __init__(self, scene_map):#scene_map是Map类的对象self.scene_map = scene_mapdef play(self):current_scene = self.scene_map.opening_scene() #目前所在场景,通过Map对象调用Map类中的函数opening_scenelast_scene = self.scene_map.next_scene('finished') #最后一个场景,同上,通过Map对象调用Map类中函数next_scenewhile current_scene != last_scene: #while循环,当前场景不是最后一个场景的情况下next_scene_name = current_scene.enter()current_scene = self.scene_map.next_scene(next_scene_name)#be sure to print out the last scenecurrent_scene.enter()

4.创建第一个也是最简单的一个场景Death场景。

class Death(Scene):quips = ["You died. You kinda suck at this.","Your Mom would be proud...if she were smarter.","Such a luser.","I have a small puppy that's better at this.","You're worse than your Dad's jokes."] #字符串列表,各种不同情况def enter(self):print(Death.quips[randint(0,len(self.quips)-1)]) #打印,quips列表中的值,该索引为0到列表长度-1中的随机数值。exit(1)#程序异常退出

5.创建了中央走廊场景,这是游戏的开始。把游戏的场景放在 Map 之前,是因为需要在随后引用它们。

#中央走廊场景
class CentralCorridor(Scene):def enter(self):print(dedent("""The Gothons of Planet Percal #25 have invaded your ship anddestroyed your entire crew. You are the last survivingmember and your last mission is to get the neutron destructbomb from the Weapons Armory, put it in the bridge,andblow the ship up after getting into an escape pod.You're running down the central corridor to the WeaponsArmory when a Gothon jumps out, red scaly skin, drak grimyteeth, and evil clown costume flowing around his hatefilled body, He's blocking the door to the Armory and about to pull a weapon to blast you.""")) #进入游戏的前景介绍action = input("> ") #输入行为if action == "shoot!": #如果行动是shootprint(dedent("""Quick on the draw you yank out your blaster and fireit at the Gothon. His clown costume is flowing andmoving around his body, which throws off your aim.Your laser hits his costume but misses him entirely.This completely ruins his brand new costume his motherbought him, which makes him fly into an insane rageand blast you repeatedly in the face until you are dead. Then he eats you."""))return 'death' #返回值elif action == "dodge!": #行动是dodge时print(dedent("""Like a world class boxer you dodge, weave,slip and slide right as the Gothon's blaster cranks a laserpast your head. In the middle of your artful dodgeyour foot slips and you bang your head on the metalwall and pass out. You wake up shortly after only todie as the Gothon stomps on your head and eats you. """)) return 'death' #返回值elif action == "tell a joke": #如果行动是tell a jokeprint(dedent("""Lucky for you they made you learn Gothon insults inthe academy. You tell the one Gothon joke you know:Lbhe Zbgure vf fb sng, jura fur fvgf nebhaq gur ubhfr,fur fvgf nebhaq gur ubhfr. The Gothon stops, triesnot to laugh, then busts out laughing and can't move.While he's laughing you run up and shoot him square inWeapon Armory door."""))return 'laser_weapon_armory' #返回值else:print("DOES NOT COMPUTE")return 'central_corridor' #返回值

6.创建游戏的剩余场景,并思考它们之间如何流转。激光武器军械库、行星、桥、逃生仓和结束场景。

#激光武器库场景
class LaserWeaponArmory(Scene):def enter(self):print(dedent("""You do a dive roll into the Weapon Armory, crouch and scanthe room for more Gothons that might be hidding. It's deadquiet, too quiet. You stand up and run to the far side ofthe room and find the neutron bomb in its container.There's a keypad lock on the box and you need the code to get the bomb out. If you get the wrong 10 times then the lock closes forever and you can't get the bomb. Thecode is 3 digits."""))  #场景提示code = f"{randint(1,9)}{randint(1,9)}{randint(1,9)}" #变量字符串格式化,密码为三个1-9之间的随机整数,包括1和9guess = input("[keypad]> ") #猜测密码guesses = 0 #猜测次数初始值while guess != code and guesses < 10: #while循环,无法确定循环次数时使用while而不是for循环。猜想密码与密码不一致且猜测次数小于10.print("BZZZZEDDDD!")guesses += 1 #猜测次数不断累加guess = input("[keypad]> ") #重新猜测密码if guess == code: #如果密码正确print(dedent("""The container clicks open and the seal breaks, lettinggas out. You grab the neutron bomb and run as fast asyou can to the bridge where you must place it in the right spot.""")) #打印结果return 'the_bridge' #返回值else:print(dedent("""The lock buzzes one last time and then you hear a sickening melting sound as the mechanism is fusedtogether. You decide to sit there, and finally the Gothons blow up the ship from their ship and you die.""")) return 'death'#桥场景
class TheBridge(Scene):def enter(self):print(dedent("""You burst onto the Bridge with the netron destruct bombunder your arm and surprise 5 Gothons who are trying totake control of the ship. Each of them has an even uglierclown costume than the last. They haven't pulled theirweapons out yet, as they see the active bomb under yourarm and don't want to set it off.""")) #进入时场景action = input("> ") #输入行动if action == "throw the bomb": #如果行动是throw the bomb时print(dedent("""In a panic you throw the bomb at the group of Gothonsand make a leap for the door. Right as you drop it a Gothons shoots you right in the back killing you. Asyou die you see another Gothon frantically try todisarm the bomb. You die knowing they will probablyblow up when it goes off."""))return 'death' #返回值elif action == "slowly place the bomb": #如果行动为slowly place the bomb时print(dedent("""You point your blaster at the bomb under your arm andthe Gothons put their hands up and start to sweat.You inch backward to the door, open it, and thencarefully place the bomb on the floor, pointing yourblaster at it. You then jump back through the door,punch the close button and blast the lock so theGothons can't get out. Now that the bomb is placed you run to the escape pod to get off this tin can.""")) #发生的事情return 'escape_pod' #返回值else:print("DOES NOT COMPUTE!")return 'the_bridge' #返回值#逃生舱场景
class EscapePod(Scene):def enter(self):print(dedent("""You rush through the ship desperately trying to make itthe escape pod before the whole ship explodes. It seemslike hardly any Gothons are on the ship, so your run isclear of interference. You get to the chamber with theescape pods, and now need to pick one to take. Some ofthem could be damaged but you don't have time to look.There's 5 pods, which one do you take?""")) #进入场景good_pod = randint(1,5) #1-5之间的随机整数guess = input("[pod]> ") #输入猜想if int(guess) != good_pod: #猜想与好用的逃生舱不一致时print(dedent(f"""You jump into pod {guess} and hit the eject button.The pod escapes out into the void of space, thenimplodes as the hull ruptures, crushing your body intojam jelly."""))  #字符串格式化guess变量return 'death' #返回值else:print(dedent(f"""You jump into pod {guess} and hit the eject button.The pod easily slides out into space heading to theplanet below. As it flies to the planet, you lookback and see your ship implode then explode like a bright star, taking out the Gothon ship at the sametime. You won!""")) #字符串格式化guess变量return 'finished' #返回值#结束场景
class Finished(Scene):def enter(self):print("You won! Good job.")return 'finished' #返回值

7.创建Map 类,其中把每个场景的名字存储在一个字典里,然后用 Map.scenes 引用那个字典。这也是为什么地图出现在场景之后的原因,因为字典必须引用场景,所以场景必须先存在。

# 地图-类。next_scene-函数,opening_scene-函数
class Map(object):scenes = {'central_corridor':CentralCorridor(),'laser_weapon_armory':LaserWeaponArmory(),'the_bridge': TheBridge(),'escape_pod':EscapePod(),'death':Death,'finished':Finished()} #字典,字符串键对应-子类值#初始化函数def __init__(self, start_scene):self.start_scene =start_scene #定义start_scenedef next_scene(self, scene_name): #定义next_scene函数,作用:通过获取的场景字符串,得到对应的的字典的值,即子类场景val = Map.scenes.get(scene_name) #get()获取字典的值,若值不存在不报错return val #返回值def opening_scene(self): #定义函数return self.next_scene(self.start_scene) #返回值,返回next_scene函数,参数scene_name = start_scene.

8.运行游戏,调用play是游戏工作。

a_map = Map('central_corridor') #地图初始场景
a_game = Engine(a_map) #游戏引擎
a_game.play() #游戏启动

运行结果:

The Gothons of Planet Percal #25 have invaded your ship and
destroyed your entire crew. You are the last surviving
member and your last mission is to get the neutron destruct
bomb from the Weapons Armory, put it in the bridge,and
blow the ship up after getting into an escape pod.You're running down the central corridor to the Weapons
Armory when a Gothon jumps out, red scaly skin, drak grimy
teeth, and evil clown costume flowing around his hate
filled body, He's blocking the door to the Armory and
about to pull a weapon to blast you.> tell a jokeLucky for you they made you learn Gothon insults in       
the academy. You tell the one Gothon joke you know:       
Lbhe Zbgure vf fb sng, jura fur fvgf nebhaq gur ubhfr,    
fur fvgf nebhaq gur ubhfr. The Gothon stops, tries        
not to laugh, then busts out laughing and can't move.     
While he's laughing you run up and shoot him square in    
Weapon Armory door.You do a dive roll into the Weapon Armory, crouch and scan
the room for more Gothons that might be hidding. It's dead
quiet, too quiet. You stand up and run to the far side of 
the room and find the neutron bomb in its container.      
There's a keypad lock on the box and you need the code to 
get the bomb out. If you get the wrong 10 times then
the lock closes forever and you can't get the bomb. The
code is 3 digits.[keypad]> 123
BZZZZEDDDD!
[keypad]> 345
BZZZZEDDDD!
[keypad]> 234
BZZZZEDDDD!
[keypad]> 456
BZZZZEDDDD!
[keypad]> 347
BZZZZEDDDD!
[keypad]> 784
BZZZZEDDDD!
[keypad]> 345
BZZZZEDDDD!
[keypad]> 987
BZZZZEDDDD!
[keypad]> 675
BZZZZEDDDD!
[keypad]> 456
BZZZZEDDDD!
[keypad]> 789The lock buzzes one last time and then you hear a
sickening melting sound as the mechanism is fused
together. You decide to sit there, and finally the
Gothons blow up the ship from their ship and you die.Your Mom would be proud...if she were smarter.

知识点:

1. textwrap模块的dedent函数
python中,可以使用textwrap模块的dedent函数删除字符串中的前导空格,它解决了python代码缩进与书写多行字符串的冲突问题,避免在全局定义多行字符串。
代码示例:
(1)不使用dedent函数:

#不使用dedent函数
text = """How are you?I'm fine, thank you."""
print(text)#不符合python的缩进原则
text = """
How are you?
I'm fine, thank you."""
print(text)

输出:

    How are you?I'm fine, thank you.How are you?
I'm fine, thank you.

符合python缩进格式的字符串,打印时,存在缩进空格。
(2)使用dedent函数

#使用dedent函数,删除三引号中的前导空格
text = """How are you?I'm fine, thank you."""
print(dedent(text))

输出结果:

How are you?
I'm fine, thank you.

2. 类的函数调用?
类的调用需要先实例化为对象,实例化时不能忘记类本身设定的属性__init__()函数内的参数也是类实例化需要的参数。
类的函数使用,通过**.函数名(参数名),具体操作可见练习41面向对象编程术语**。
类函数的内部调用,需要确保函数内参数数量一致,且使用**self.函数名(参数名)**调用。

报错类型:TypeError: water() missing 1 required positional argument: 'food' 这里的’food’,也可以是别的参数例如’self’等。
原因:类的实例化失败,调用该函数时,类没有实例化为对象。需要先保证类已经实例化。具体可参加代码注释。
具体调用方法如下:

class Animal():def __init__(self, name,age): #类初始化属性self.name = nameself.age = agedef feed(self,num,food): #feed()函数,参数为num和foodnum += 1print(f"It needs {num}g {food}.")def water(self, n, food): #water()函数,参数为n和food,因为要调用内部函数,该函数的参数需要与调用函数一致#内部调用函数feed(),使用self.函数名(参数)调用,注意参数数量与之前一致water_num = self.feed(n,food) return water_numAM = Animal("Lily",2) #实例化类时,需要定义类的属性,若无,则不需要
AM.water(2,'apple') #类的函数外部调用,将类实例化后使用.调用
Animal.water(1,"meat") #会报错,Animal类未实例化

输出:

It needs 3g apple.
Traceback (most recent call last):File "c:\Users\limin\Desktop\Python3_exercises\text43_1.py", line 43, in <module>Animal.water(1,"meat")
TypeError: water() missing 1 required positional argument: 'food'

3. 类相互调用函数?
类相互调用的方式见下面示例,以及代码中的注释说明。

(1)第一种同文件内类之间的函数调用:

#类相互之间调用函数
class Car():def __init__(self,make,model): #初始化函数,属性make和modelself.make = makeself.model =modeldef engine(self,num): #定义Car()函数print(f"The car has {num} engine.")class Dealership():def __init__(self,name): #初始化函数,属性为name,调用实例需要填写name属性self.name = nameself.cars = [] #定义新变量,列表def add_car(self, make, model): #定义函数,其参数数量由于调用Car()类属性而与其对应参数相同new_car = Car(make,model) #调用Car()类属性,即初始化函数self.cars.append(new_car)def show_inventory(self,make,model,num): #定义函数,参数数量由调用Car()类的engine()函数确定,因此参数为3个for car in self.cars:print(car.make,car.model)Car(make,model).engine(num) #调用Car()类中的函数engine(),调用函数依旧需要实例化类dealership = Dealership("ABC Motors")
dealership.add_car("Toyota","Camry")
dealership.add_car("Honda","Civic")
dealership.show_inventory("ABC","BIG",3)

输出结果:

Toyota Camry
Honda Civic
The car has 3 engine.

(2)跨文件类函数的相互调用
跨文件类的相互调用是指在不同的.py文件中定义的两个或多个类之间的相互调用。
要实现跨文件类的相互调用,需要遵循如下步骤:
·将需要被调用的类定义在一个单独的.py文件中,这个文件称为模块。
·在另一个文件中,使用import语句导入该模块。
·在当前文件中使用该模块中定义的类时,需要使用模块名加点号进行引用。例如,如果在module.py文件中定义了一个类MyClass,那么在另一个文件中使用该类时可以这样写:module.MyClass()。
具体操作如下代码:
(1)创建第一个类ClassA
text43_3.py

class ClassA():def __init__(self):self.name = 'ClassA'  def greet(self): # 定义函数return 'Hello from ' + self.name  # 返回字符串

(2)创建第二个类Class B,并调用第一个文件中的ClassA类
text43_4.py

from text43_3 import ClassA  #调用模块class ClassB():  #定义类def __init__(self):  #定义属性self.name = 'ClassB'  def greet(self): #定义函数return 'Hello from ' + self.name #返回值def call_class_a(self): #定义函数,返回class_a类a = ClassA() #调用class_a实例return a.greet() #返回值

(3) 运行主代码
text_5.py

from text43_4 import ClassB #调用ClassB模块b = ClassB() #实例化ClassB()
print(b.greet())  #打印实例ClassB()的函数greet()
print(b.call_class_a()) #打印实例ClassB()的函数call_class_a()

附加练习

1. 这段代码有一个bug。为什么门锁猜了11次?
原代码:

code = f"{randint(1,9)}{randint(1,9)}{randint(1,9)}" #变量字符串格式化,密码为三个1-9之间的随机整数,包括1和9guess = input("[keypad]> ") #猜测密码guesses = 0 #猜测次数初始值while guess != code and guesses < 10: #while循环,无法确定循环次数时使用while而不是for循环。猜想密码与密码不一致且猜测次数小于10.print("BZZZZEDDDD!")guesses += 1 #猜测次数不断累加guess = input("[keypad]> ") #重新猜测密码

主要原因为:guesses = 0 且while guesses < 10时,while循环将发生10次,0~9。
修改bug为,将guesses =0改为guesses=1。
结果如下:

code = f"{randint(1,9)}{randint(1,9)}{randint(1,9)}" #变量字符串格式化,密码为三个1-9之间的随机整数,包括1和9guess = input("[keypad]> ") #猜测密码guesses = 1 #猜测次数初始值while guess != code and guesses < 10: #while循环,无法确定循环次数时使用while而不是for循环。猜想密码与密码不一致且猜测次数小于10.print("BZZZZEDDDD!")guesses += 1 #猜测次数不断累加guess = input("[keypad]> ") #重新猜测密码

2. 解释一下如何返回next_scene下一个场景。
在每个场景的最后都会通过函数return返回一个字符串,在Map类中有一个字典,存储了场景的键值对,其中字符串为键,对应的对象(类实例化)为值。next_scene()函数通过获取每个场景最后的返回值,即字符串,再调用函数get()获取字典scenes中的对应的值,从而进入该场景(调用该类)。

class Map(object):scenes = {'central_corridor':CentralCorridor(),'laser_weapon_armory':LaserWeaponArmory(),'the_bridge': TheBridge(),'escape_pod':EscapePod(),'death':Death(),'finished':Finished()} #字典,字符串键对应-子类值#初始化函数def __init__(self, start_scene):self.start_scene =start_scene #定义start_scenedef next_scene(self, scene_name): #定义next_scene函数,作用:通过获取的场景字符串,得到对应的的字典的值,即子类场景val = Map.scenes.get(scene_name) #get()获取字典的值,若值不存在不报错return val #返回值

3. 在游戏中添加作弊代码,这样你就可以通过比较难的房间。我可以通过在一行写两个字来实现这一点。
个人是否通过游戏主要和最后renturn的结果有关,可以通过更改return 的值,直接进入下一个场景。
例如,将else后面的return ‘death’ 改为return ‘the_bridge’。

#激光武器库场景
class LaserWeaponArmory(Scene):def enter(self):print(dedent("""You do a dive roll into the Weapon Armory, crouch and scanthe room for more Gothons that might be hidding. It's deadquiet, too quiet. You stand up and run to the far side ofthe room and find the neutron bomb in its container.There's a keypad lock on the box and you need the code to get the bomb out. If you get the wrong 10 times then the lock closes forever and you can't get the bomb. Thecode is 3 digits."""))  #场景提示code = f"{randint(1,9)}{randint(1,9)}{randint(1,9)}" #变量字符串格式化,密码为三个1-9之间的随机整数,包括1和9guess = input("[keypad]> ") #猜测密码# guesses = 0 #猜测次数初始值guesses = 1 #修改初始值while guess != code and guesses < 10: #while循环,无法确定循环次数时使用while而不是for循环。猜想密码与密码不一致且猜测次数小于10.print("BZZZZEDDDD!")guesses += 1 #猜测次数不断累加guess = input("[keypad]> ") #重新猜测密码if guess == code: #如果密码正确print(dedent("""The container clicks open and the seal breaks, lettinggas out. You grab the neutron bomb and run as fast asyou can to the bridge where you must place it in the right spot.""")) #打印结果return 'the_bridge' #返回值else:print(dedent("""The lock buzzes one last time and then you hear a sickening melting sound as the mechanism is fusedtogether. You decide to sit there, and finally the Gothons blow up the ship from their ship and you die.""")) return 'the_bridge' #即使输出的结果错误,依旧可以跳到下一个场景,而不是death场景

4. 回到我的描述和分析,然后尝试为这个英雄和他遇到的各种哥特人建立一个小的战斗系统。
暂时不会写,稍微有点难度,可通过更多的练习后完成。

5. 这实际上是“有限状态机”(finite state machine)的一个小版本。读读相关的内容,你可能看不懂,但无论如何都要试一试。
可以参考:
基本概念如下:
有限状态机(Finite State Machine) 缩写为 FSM。以下简称为状态机。
状态机有 3 个组成部分:状态、事件、动作。
状态:所有可能存在的状态。包括当前状态和条件满足后要迁移的状态。
事件:也称为转移条件,当一个条件被满足,将会触发一个动作,或者执行一次状态的迁移。
动作:条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是* 必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态。

更多推荐

“笨办法”学Python 3 ——练习43 面向对象的分析和设计基础

本文发布于:2024-03-08 19:46:52,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1722104.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:面向对象   办法   基础   Python

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!