---
# System prepended metadata

title: 用Dictionary做文字RPG

---

# 用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 用法 ２
> 雖然上一個版本已經可以作為 文字 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結束 其餘繼續（請注意大小寫）")
    
```

