1您机、明確項目目標
類與對象的兩用用法
1.1穿肄、類作為函數(shù)包
使用類把函數(shù)打包封裝在一起年局。
1.2、類作為對象的模板
使用類生成實例對象咸产。
游戲中的“屬性克制”:
在游戲中定義三種類型的角色:圣光騎士矢否、暗影刺客、精靈弩手脑溢,他們三者之間也會互相克制僵朗。
2、分析過程屑彻,拆解項目
首先验庙,回顧之前我們做過的這個游戲的功能:
版本1.0:將項目1的部分代碼,調整后用函數(shù)封裝并調用
社牲。
版本2.0:從角色池里為雙方隨機選出3個角色
粪薛,并隨機生成血量和攻擊值。
版本3.0:詢問玩家角色出場順序
搏恤,并打印出來
版本4.0:根據(jù)出場順序和對方進行三輪PK
违寿,并輸出戰(zhàn)果
。
現(xiàn)在我們要升級以前的版本了挑社,咱們怎么搞陨界?當然是先拆版本啦:
版本1.0:類的封裝
,將類作為函數(shù)包痛阻,把各種函數(shù)打包起來菌瘪。
版本2.0:類的繼承和實例化,讓三種不同的角色的屬性不同
阱当。
版本1.0:為三個角色的類添加一個讓角色之間可以相互克制
的類方法俏扩。
拆分邏輯可以繼續(xù)細拆為:
版本1.0:我們知道類能夠作為函數(shù)包來使用,而上次的程序中有特別多函數(shù)弊添,所以我們可以先用類把他們打包到一起录淡,做成一個“游戲運行”類。打包完畢后油坝,我們再微調一些代碼嫉戚,為實現(xiàn)新功能做好預先準備。
版本2.0:接下來我們需要為游戲創(chuàng)建3種角色澈圈。因為類是實例對象的模版彬檀,所以我們可以把三種角色封裝成三個屬性不同的類(騎士、刺客瞬女、弩手)窍帝。封裝完畢后,我們還需要這三種角色能在“游戲運行”類中被調用诽偷。
版本3.0:最后一步就是要讓角色之間可以相互克制坤学。想做到這件事疯坤,最簡單的方式是在剛才寫的三個角色的類中,每個類添加一個“屬性克制”的類方法深浮。
3压怠、逐步執(zhí)行,代碼實現(xiàn)
先回顧老版本的代碼:
import time,random
# 需要的數(shù)據(jù)和變量放在開頭
player_list = ['【狂血戰(zhàn)士】','【森林箭手】','【光明騎士】','【獨行劍客】','【格斗大師】','【槍彈專家】']
enemy_list = ['【暗黑戰(zhàn)士】','【黑暗弩手】','【暗夜騎士】','【嗜血刀客】','【首席刺客】','【陷阱之王】']
players = random.sample(player_list,3)
enemies = random.sample(enemy_list,3)
player_info = {}
enemy_info = {}
# 隨機生成角色的屬性
def born_role():
life = random.randint(100,180)
attack = random.randint(30,50)
return life,attack
# 生成和展示角色信息
def show_role():
for i in range(3):
player_info[players[i]] = born_role()
enemy_info[enemies[i]] = born_role()
# 展示我方的3個角色
print('----------------- 角色信息 -----------------')
print('你的人物:')
for i in range(3):
print('%s 血量:%s 攻擊:%s'
%(players[i],player_info[players[i]][0],player_info[players[i]][1]))
print('--------------------------------------------')
print('電腦敵人:')
# 展示敵方的3個角色
for i in range(3):
print('%s 血量:%s 攻擊:%s'
%(enemies[i],enemy_info[enemies[i]][0],enemy_info[enemies[i]][1]))
print('--------------------------------------------')
input('請按回車鍵繼續(xù)飞苇。\n') # 為了讓玩家更有控制感刑峡,可以插入類似的代碼來切分游戲進程。
# 角色排序玄柠,選擇出場順序。
def order_role():
global players
order_dict = {}
for i in range(3):
order = int(input('你想將 %s 放在第幾個上場诫舅?(輸入數(shù)字1~3)'% players[i]))
order_dict[order] = players[i]
players = []
for i in range(1,4):
players.append(order_dict[i])
print('\n我方角色的出場順序是:%s羽利、%s、%s' %(players[0],players[1],players[2]))
print('敵方角色的出場順序是:%s刊懈、%s这弧、%s' %(enemies[0],enemies[1],enemies[2]))
# 角色PK
def pk_role():
round = 1
score = 0
for i in range(3): # 一共要打三局
player_name = players[i]
enemy_name = enemies[i]
player_life = player_info[players[i]][0]
player_attack = player_info[players[i]][1]
enemy_life = enemy_info[enemies[i]][0]
enemy_attack = enemy_info[enemies[i]][1]
# 每一局開戰(zhàn)前展示戰(zhàn)斗信息
print('\n----------------- 【第%s局】 -----------------' % round)
print('玩家角色:%s vs 敵方角色:%s ' %(player_name,enemy_name))
print('%s 血量:%s 攻擊:%s' %(player_name,player_life,player_attack))
print('%s 血量:%s 攻擊:%s' %(enemy_name,enemy_life,enemy_attack))
print('--------------------------------------------')
input('請按回車鍵繼續(xù)。\n')
# 開始判斷血量是否都大于零虚汛,然后互扣血量匾浪。
while player_life > 0 and enemy_life > 0:
enemy_life = enemy_life - player_attack
player_life = player_life - enemy_attack
print('%s發(fā)起了攻擊,%s剩余血量%s' % (player_name,enemy_name,enemy_life))
print('%s發(fā)起了攻擊卷哩,%s剩余血量%s' % (enemy_name,player_name,player_life))
print('--------------------------------------------')
time.sleep(1)
else: # 每局的戰(zhàn)果展示蛋辈,以及分數(shù)score和局數(shù)的變化。
# 調用show_result()函數(shù)将谊,打印返回元組中的result冷溶。
print(show_result(player_life,enemy_life)[1])
# 調用show_result()函數(shù),完成計分變動尊浓。
score += int(show_result(player_life,enemy_life)[0])
round += 1
input('\n點擊回車逞频,查看比賽的最終結果\n')
if score > 0:
print('【最終結果:你贏了!】\n')
elif score < 0:
print('【最終結果:你輸了栋齿!】\n')
else:
print('【最終結果:平局苗胀!】\n')
# 返回單局戰(zhàn)果和計分法所加分數(shù)。
def show_result(player_life,enemy_life): # 注意:該函數(shù)要設定參數(shù)瓦堵,才能判斷單局戰(zhàn)果基协。
if player_life > 0 and enemy_life <= 0:
result = '\n敵人死翹翹了,你贏了谷丸!'
return 1,result # 返回元組(1,'\n敵人死翹翹了堡掏,你贏了!')刨疼,類似角色屬性的傳遞泉唁。
elif player_life <= 0 and enemy_life > 0:
result = '\n悲催鹅龄,敵人把你干掉了!'
return -1,result
else :
result = '\n哎呀亭畜,你和敵人同歸于盡了扮休!'
return 0,result
# (主函數(shù))展開戰(zhàn)斗流程
def main():
show_role() # 生成和展示角色信息
order_role() # 角色排序,選擇出場順序
pk_role() # 完成角色PK拴鸵,并展示PK結果
# 啟動程序(即調用主函數(shù))
main()
然后用類的形式玷坠,把函數(shù)整理好,實例化類劲藐,轉化為新版本
在新版本中八堡,加入了克制系統(tǒng)。
實現(xiàn)方法是通過增加一段BUFF的判斷聘芜,就是當A的對手為B時兄渺,把A的攻擊力提高50%。
import random
import time
# 創(chuàng)建一個類汰现,可實例化成具體的游戲角色
class Role:
def __init__(self, name='【角色】'): # 把角色名作為默認參數(shù)
self.name = name
self.life = random.randint(100,150)
self.attack = random.randint(30,50)
# 創(chuàng)建3個子類挂谍,可實例化為3個不同的職業(yè)
class Knight(Role):
def __init__(self, name='【圣光騎士】'): # 把子類角色名作為默認參數(shù)
Role.__init__(self,name) # 利用了父類的初始化函數(shù)
self.life = self.life*5 # 騎士有5份血量
self.attack = self.attack*3 # 騎士有3份攻擊力
# 職業(yè)克制關系
def fight_buff(self, opponent,str1,str2):
if opponent.name == '【暗影刺客】':
self.attack = int(self.attack * 1.5)
print('『%s』【圣光騎士】對 『%s』【暗影刺客】說:“讓無盡光芒制裁你的墮落!”'%(str1, str2))
class Assassin(Role):
def __init__(self, name='【暗影刺客】'):
Role.__init__(self,name)
self.life = self.life*3
self.attack = self.attack*5
# 職業(yè)克制關系
def fight_buff(self, opponent,str1,str2):
if opponent.name == '【精靈弩手】':
self.attack = int(self.attack * 1.5)
print('『%s』【暗影刺客】對 『%s』【精靈弩手】說:“主動找死瞎饲,就別怪我心狠手辣口叙。”'%(str1, str2))
class Bowman(Role):
def __init__(self, name='【精靈弩手】'):
Role.__init__(self,name)
self.life = self.life*4
self.attack = self.attack*4
# 職業(yè)克制關系
def fight_buff(self, opponent,str1,str2):
if opponent.name == '【圣光騎士】':
self.attack = int(self.attack * 1.5)
print('『%s』【精靈弩手】對 『%s』【圣光騎士】說:“騎著倔驢又如何嗅战?你都碰不到我衣服妄田。”'%(str1, str2))
# 創(chuàng)建一個類驮捍,可生成3V3并展示:可分為:歡迎語→隨機生成→展示角色
class Game():
def __init__(self):
self.players = [] # 存玩家順序
self.enemies = [] # 存敵人順序
self.score = 0 # 比賽積分
self.i = 0 # 記輪次
# 依次執(zhí)行以下函數(shù)
self.game_start() # 歡迎語
self.born_role() # 隨機生成6個角色
self.show_role() # 展示角色
self.order_role() # 排序并展示
self.pk_role() # 讓雙方 Pk 并展示結果
self.show_result() # 展示最終結局
# 歡迎語
def game_start(self):
print('------------ 歡迎來到“煉獄角斗場” ------------')
print('在昔日的黃昏山脈形庭,奧盧帝國的北境邊界上,有傳說中的“煉獄角斗場”厌漂。')
print('鮮血與戰(zhàn)斗是角斗士的歸宿萨醒,金錢與榮耀是角斗士的信仰!')
print('今日苇倡,只要你【你的隊伍】能取得勝利富纸,你將獲得一筆夠花500年的財富。')
time.sleep(2)
print('將隨機生成【你的隊伍】和【敵人隊伍】旨椒!')
input('\n狹路相逢勇者勝晓褪,請按任意鍵繼續(xù)。\n')
# 隨機生成6個角色
def born_role(self):
for i in range(3):
self.players.append(random.choice([Knight(),Assassin(),Bowman()]))
self.enemies.append(random.choice([Knight(),Assassin(),Bowman()]))
# 展示角色
def show_role(self):
print('----------------- 角色信息 -----------------')
print('你的隊伍:')
for i in range(3):
print( '『我方』%s 血量:%s 攻擊:%s'%
(self.players[i].name,self.players[i].life,self.players[i].attack))
print('--------------------------------------------')
print('敵人隊伍:')
for i in range(3):
print('『敵方』%s 血量:%s 攻擊:%s'%
(self.enemies[i].name,self.enemies[i].life,self.enemies[i].attack))
print('--------------------------------------------')
input('請按回車鍵繼續(xù)综慎。\n')
# 排序并展示
def order_role(self):
order_dict = {}
for i in range(3):
order = int(input('你想將 %s 放在第幾個上場涣仿?(輸入數(shù)字1~3)'% self.players[i].name))
order_dict[order] = self.players[i]
self.players = []
for i in range(1,4):
self.players.append(order_dict[i])
print('\n你的隊伍出場順序是:%s、%s、%s'
%(self.players[0].name,self.players[1].name,self.players[2].name))
print('敵人隊伍出場順序是:%s好港、%s榔袋、%s'
%(self.enemies[0].name,self.enemies[1].name,self.enemies[2].name))
# 讓雙方 Pk 并展示結果
def pk_role(self):
for i in range(3):
print('\n----------------- 【第%s輪】 -----------------' % (i+1))
# 每一局開戰(zhàn)前加buff
self.players[i].fight_buff(self.enemies[i],'我方','敵方')
self.enemies[i].fight_buff(self.players[i],'敵方','我方')
input('\n戰(zhàn)斗雙方準備完畢婆芦,請按回車鍵繼續(xù)。')
print('--------------------------------------------')
while self.players[i].life >0 and self.enemies[i].life>0:
self.enemies[i].life -= self.players[i].attack
self.players[i].life -= self.enemies[i].attack
print('我方%s 發(fā)起了攻擊,敵方%s 剩余血量 %s'%
(self.players[i].name,self.enemies[i].name,self.enemies[i].life))
print('敵方%s 發(fā)起了攻擊播急,我方%s 剩余血量 %s'%
(self.enemies[i].name,self.players[i].name,self.players[i].life))
print('--------------------------------------------')
time.sleep(1)
if self.players[i].life <= 0 and self.enemies[i].life> 0:
print('\n很遺憾勺阐,我方%s 掛掉了鳖敷!'% (self.players[i].name))
self.score -= 1
elif self.players[i].life >0 and self.enemies[i].life<= 0:
print('\n恭喜匿又,我方%s 活下來了。'% (self.players[i].name))
self.score += 1
else:
print('\n我的天塘秦,他們倆都死了八显ā!')
# 展示最終結局
def show_result(self):
input('\n請按回車查看最終結果尊剔。\n')
if self.score >0:
print('【最終結果】\n你贏了精偿,最終的財寶都歸你了!')
elif self.score == 0:
print('【最終結果】\n你沒有勝利赋兵,但也沒有失敗,在夜色中灰溜溜離開了奧盧帝國搔预。')
else:
print('【最終結果】\n你輸了霹期。煉獄角斗場又多了幾具枯骨。')
game = Game()
4拯田、練習題历造、那個人來了
練習目標:
這個練習,會訓練運用“子類的繼承和定制”相關知識船庇。
練習要求:
在練習中吭产,需要通過代碼的運行結果和所學知識,補全代碼鸭轮。
在補全代碼的過程中臣淤,需要對子類的繼承和定制有清晰的認知。
# 實現(xiàn)效果
大家注意了窃爷!
一個叫“吉多”的人來了邑蒋。
大家注意了!
一個叫“范羅蘇姆”的男人來了按厘。
大家注意了医吊!
那個叫“范羅蘇姆”的男人留下了他的背影。
# 補全代碼:
class Person:
def __init__(self, name):
self.Person = name
print('大家注意了 !')
def show(self):
print('一個叫“%s”的人來了逮京。' % (self.Person))
# 子類的繼承和定制
class Man(Person):
def __init__(self):
self.Person = '范羅蘇姆'
print('大家注意了 !')
def show(self):
print('一個叫“%s”的男人來了卿堂。' % (self.Person))
def leave(self):
print('那個叫“%s”的男人留下了他的背影。' % (self.Person))
author1 = Person('吉多')
author1.show()
# author1.leave() # 補全代碼后懒棉,運行該行會報錯:AttributeError:'Person' object has no attribute 'leave'.
author2 = Man()
author2.show()
author3 = Man()
author3.leave()