# 用Dictionary做文字RPG > Auther: 蘇柏丞 ## 文字RPG *情節介紹 1.輸入1繼續攻擊,輸入9逃跑。 2.輸入2使用第一個魔法攻擊,此回合不能普通攻擊。 3.輸入drink喝一罐藥水,增加血量,但此回合不能普通攻擊。 4.每回合顯示適當的資訊。 >也可以嘗試加入更多的情節,以下參考: 自訂 魔王血量、魔王攻擊 自訂 角色血量、角色攻擊 設定總回合數,並在到達規定回數後,依血量決定結果(或魔王存活就判定失敗) 設定藥水每次補充角色20%的總血量 設定至少一個魔法攻擊的招式及傷害(傷害值為魔王當前血量的10%) 設定魔法攻擊冷卻時間 ## 範例(初學者版) ```python= bossHp = 500 attack = 13 round = 0 choice = 0 while (bossHp > 0 and choice != 9): choice = int(input('輸入1普通攻擊,輸入2魔法攻擊。輸入9逃。')) round += 1 # level up per 3 rounds if ( round % 3 == 0): attack = attack*2+1 if ( choice == 1 ): bossHp = bossHp - attack if ( choice == 2 ): bossHp = bossHp - attack * 2 if ( choice == 9 ): break if ( bossHp < 0) : #避免出現負數 bossHp = 0 print(f'經過第{round:2d}回合的攻擊,Boss 剩下{bossHp}Hp') if ( bossHp > 0) : print(f'遊戲結束,因為Boss 剩下{bossHp}Hp,所以挑戰失敗') else : print('遊戲結束,因為Boss 剩下 0Hp ,所以挑戰成功!!!!') ``` * 試著用函數來化簡,讓整體結構更加簡潔易懂。 * 試著用字典來管理這麼多個變數。 * 或是使用類別(最佳)來實作這個文字RPG ## 函數化 範例使用: 將攻擊程式函數化 使用時,僅需修改數值 ```python= def boss_attack(bossHp , attack , ab): #attack bonus bossHp = bossHp - attack * ab return bossHp ``` ### 實際使用 ```python= bossHp = 500 attack = 13 round = 0 choice = 0 atk = 1 def boss_attack(bossHp , attack , ab): #attack bonus bossHp = bossHp - attack * ab return bossHp while (bossHp > 0 , choice != 9 ): print('輸入1普通攻擊,輸入2魔法攻擊。輸入9逃。') round += 1 choice = input('') magicAttack = bossHp * 0.1 if choice == "1" : bossHp = boss_attack(bossHp , attack , 1) elif choice == "2" : bossHp = boss_attack(bossHp , attack , 2) elif choice == "9" : break else: print("無效指令!!!!!! 這回合無法攻擊") if bossHp == 0: print("勇者戰勝了!!!") break else : print(f'經過第{round:2d}回合的攻擊,Boss 剩下{bossHp}Hp') ``` * 函數就是將一段會重複使用的程式碼模組化 ## Dictionary 用法 1 ### 範例: ```python= myDictionary = { 'boss' : '習大大' , 'attack' : 13, 'hp':100, 'magic_attack':15, } myDictionary['hp'] -= 10 print('%s血量剩下%d' % (myDictionary['boss'],myDictionary['hp'])) ``` > `attack`,`hp`,`magic_attack`為`Dictionary`中的索引 > > 代表叫到`attack`字元時,會傳喚出其賦值`13` ### 實作: >目標: > >1. 將之前的 bossHp , bossAttack 整合成用 Dictionary 來呈現;就是將“角色”的“屬性”寫在各角色的 Dictionary 內 > >註:可使用前面所提供的範例魔改 ## 中繼版 > 改動: > > 1. 加入了"是否重新開始"的選擇 > 2. 給予魔王攻擊力與勇士血量 > 3. 增加藥水回復技能("drink") > 4. 新增了"m1"密技(魔王損失10%血量) ```python= again = "Yes" while again != "No" : boss = { "hp" : eval(input('魔王血量')), "attack" : eval(input('魔王攻擊力')), } coolguy = { "hp" : eval(input('勇者血量')), "attack" : eval(input('勇者攻擊力')), } allHp = coolguy['hp'] drink = coolguy ['hp'] * 0.2 round = 0 chioce = '0' while (boss['hp'] > 0 , chioce != '9' ,coolguy['hp'] > 0): print('輸入1普通攻擊,輸入2魔法攻擊。輸入9逃。') round += 1 choice = input('') coolguy['hp'] = coolguy['hp'] - boss['attack'] magicAttack = boss['hp'] * 0.1 if choice == "1" : boss['hp'] = boss['hp'] - coolguy['attack'] elif choice == "2" : boss['hp'] = boss['hp']- coolguy['attack'] * 2 elif choice == "m1" : boss['hp'] = boss['hp']- magicAttack elif choice == "drink" : coolguy['hp'] = coolguy['hp'] + drink if coolguy['hp'] > allHp : coolguy['hp'] = allHp elif choice == "9" : break else : if round > 10 : if choice == "m2" : boss['hp'] = boss['hp'] - boss['hp'] * 0.5 else: print("無效指令!!!!!! 這回合無法攻擊") if boss['hp'] <= 0 : boss['hp'] = 0 if coolguy['hp'] <= 0 : coolguy['hp'] = 0 if coolguy['hp'] == 0 : if boss['hp'] == 0 : print("勇者選擇與習大大同歸於盡...") break else : print("勇者血量見底,撲街ㄌ") break elif choice == 'drink' : print("勇者選擇喝下藥水,目前血量%dhp"% coolguy['hp']) elif boss['hp'] == 0: print("勇者戰勝了習大大!!!") break else : print(f'經過第{round:2d}回合,Boss 剩下%dHp,勇者剩下%dhp' % (boss['hp'],coolguy['hp'])) again = input("輸入No結束 其餘繼續(請注意大小寫)") ``` ## Dictionary 用法 2 > 雖然上一個版本已經可以作為 文字 RPG手遊 來玩耍了,但 Dictionary 也可以拿來優化遊戲中關於招式的部分,讓其可以更好維護,也可以簡化程式碼 > > Dictionary 的索引也可用來代表一段數學算式,如以下範例: ## 範例: ``` python = boss = { "hp" : eval(input('Boss 生命值')), "attack" : eval(input('Boss 攻擊力')), } coolguy = { "hp" : eval(input('Cool Guy 生命值')), "attack" : eval(input('Cool Guy 攻擊力')), } choice = input('輸入1普通攻擊,輸入2魔法攻擊。輸入9逃。') def action(): global boss , coolguy, choice dictionary = { "1" : (boss['hp'] - coolguy['attack']) , "2" : (boss['hp'] - coolguy['attack'] * 2) , } boss['hp'] = dictionary[choice] return boss action() print(boss['hp']) ``` * 範例中,”索引“ 從角色的屬性,變成了招數的代號 當叫到 “1” 時,其代表``` boss['hp'] - coolguy['attack']```這段運算程式碼 所以只要再用```boss['hp'] = dictionary[choice]``` 就可以取代 ```中繼版``` 中的一堆 ``` if / else ... ```了 註:函數內的 ```global``` 代表引用 "全域變數" ; 函數 內/外 的 "變數引值" 相同 ## 實作: >目標: > >1. 將之前的 if / else 用 Dictionary 函數來取代;就是將招數寫在同個 Dictionary 內 > >註:可使用前面所提供的範例魔改 ## Ultra 版 ``` python = again = "Yes" def action(): global boss , coolguy, choice , allHp , bug dictionary = { '1' : (boss['hp'] - coolguy['attack']) , '2' : (boss['hp'] - coolguy['attack'] * 2) , 'm1' : (boss['hp'] - boss['hp'] * 0.1), 'drink': (coolguy['hp'] + allHp * 0.2 ), } if choice == '1' or choice == '2' or choice == 'm1': boss['hp'] = dictionary[choice] bug = 0 elif choice == 'drink' : coolguy['hp'] = dictionary[choice] bug = 0 if coolguy['hp'] > allHp : coolguy['hp'] = allHp else: bug = 1 # 確保血量不會小於 0 if boss['hp'] <= 0 : boss['hp'] = 0 while again != "No" : # set up bug = 0 boss = { "hp" : eval(input('魔王血量')), "attack" : eval(input('魔王攻擊力')), } coolguy = { "hp" : eval(input('勇者血量')), "attack" : eval(input('勇者攻擊力')), } allHp = coolguy['hp'] round = 0 while (boss['hp'] > 0 ,coolguy['hp'] > 0): round += 1 print('輸入1普通攻擊,輸入2魔法攻擊。輸入9逃。') choice = input() if choice == '9' : break coolguy['hp'] = coolguy['hp'] - boss['attack'] action() if bug == 1 : while bug == 1 : print("錯誤指令,請重新輸入") choice = input('輸入1普通攻擊,輸入2魔法攻擊。輸入9逃。') if choice == '9': break action() if coolguy['hp'] <= 0 : coolguy['hp'] = 0 elif choice == 'drink' : print(f'在第{round:2d}回合,勇者選擇喝下藥水,此時 Boss剩下%dHp,勇者回復到%dhp' % (boss['hp'],coolguy['hp'])) elif coolguy['hp'] == 0 : if boss['hp'] == 0 : print("勇者選擇與習大大同歸於盡...") break else : print("勇者血量見底,撲街ㄌ") break elif boss['hp'] == 0: print("勇者戰勝了習大大!!!") break else : print(f'經過第{round:2d}回合,Boss 剩下%dHp,勇者剩下%dhp' % (boss['hp'],coolguy['hp'])) again = input("輸入No結束 其餘繼續(請注意大小寫)") ```