第124回【Python】RPG

現在取り組んでいるのは、paiza ラーニング問題集「クラス・構造体メニュー」になります。

はじめに

猫とキャンプと野球観戦と AWS が大好きな旦那、LeoSaki です。モフモフしたい。

Python をゼロから勉強してみよう、のコーナー 124 回目です。

最近、Python よりも VBA の方で新しい発見が多く、ちょっと面白くなってしまっています。Python を勉強する趣旨だったはずなのに。VBA でもこんなこと出来るんだ、ってパターンが多い。VBA では難しいだろう、と勝手な思い込みだったことを反省しています。

それでは、今日も頑張ってみようと思います。

RPG

paiza 村にたびたび魔物が訪れるため、 1 〜 N 番の番号が割り当てられた N 人の勇者を雇うことにしました。
勇者には次のようなステータスを持ちます。

レベル l_i
体力 h_i
攻撃力 a_i
防御力 d_i
素早さ s_i
賢さ c_i
運 f_i

また、各勇者には次のようなイベントが発生します。

levelup h a d s c f
レベルが 1 上昇
体力が h 上昇
攻撃力が a 上昇
防御力が d 上昇
素早さが s 上昇
賢さが c 上昇
運が f 上昇

muscle_training h a
体力が h 上昇
攻撃力が a 上昇

running d s
防御力が d 上昇
素早さが s 上昇

study c
賢さが c 上昇

pray f
運が f 上昇

各勇者の初期ステータスと起こるイベントの回数、
また、起こるイベントとその対象の勇者の番号が与えられるので、
全てのイベントが終わった後の各勇者のステータスを出力してください。

N K
l_1 h_1 a_1 d_1 s_1 c_1 f_1
...
l_N h_N a_N d_N s_N c_N f_N
to_1 event_1
...
to_K event_K

・ 1 行目では、勇者の人数 N と起こるイベントの回数 K が与えられます。
・ 続く N 行のうち i 行目(1 ≦ i ≦ N)では、問題文の通り、番号 i の勇者のステータスが与えられます。
・ 続く K 行では、イベントの対象の勇者の番号 to と、イベントの内容 event が問題文の通り与えられます。


すべてのテストケースにおいて、以下の条件をみたします。

・ 与えられる値は全て整数
・ 1 ≦ N , K ≦ 10^5
・ 1 ≦ l_i , h_i , a_i , d_i , s_i , c_i , f_i ≦ 1000(1 ≦ i ≦ N)
・ 1 ≦ to_i ≦ N (1 ≦ i ≦ K)

event_i (1 ≦ i ≦ K) は以下のいずれかの形式で与えられる。

・levelup h a d s c f (1 ≦ h , a , d , s , c , f ≦ 1000)
・muscle_training h a (1 ≦ h , a ≦ 1000)
・running d s (1 ≦ d , s ≦ 1000)
・study c (1 ≦ c ≦ 1000)
・pray f (1 ≦ f ≦ 1000)


入力例

1 3
23 128 533 552 44 69 420
1 muscle_training 565 241
1 study 132
1 levelup 379 585 4 145 276 8

出力例

24 1072 1359 556 189 477 428

村に最大 1 万人の勇者がやってきて、みんながレベル上げするとか、村の財政大丈夫だろうか。明らかに村人よりも勇者の方が多くなっている予感。そこまでして守りたいものがある村とは!?

Python
class Status:
    def __init__(self,l,h,a,d,s,c,f):
        self.l = l
        self.h = h
        self.a = a
        self.d = d
        self.s = s
        self.c = c
        self.f = f
        
    def levelup(self,h,a,d,s,c,f):
        self.l += 1
        self.h += h
        self.a += a
        self.d += d
        self.s += s
        self.c += c
        self.f += f
    
    def muscle_training(self,h,a):
        self.h += h
        self.a += a
        
    def runnning(self,d,s):
        self.d += d
        self.s += s
    
    def study(self,c):
        self.c += c
        
    def pray(self,f):
        self.f += f
        
    def get_status(self):
        print(self.l,self.h,self.a,self.d,self.s,self.c,self.f)

N,K = map(int,input().split())
braves = [None] * N

for i in range(N):
    l,h,a,d,s,c,f = map(int,input().split())
    braves[i] = Status(l,h,a,d,s,c,f)

for _ in range(K):
    S = input().split()
    to = int(S.pop(0)) -1
    event = S.pop(0)
    if event == 'levelup':
        h,a,d,s,c,f = [int(x) for x in S]
        braves[to].levelup(h,a,d,s,c,f)
    elif event == 'muscle_training':
        h,a = [int(x) for x in S]
        braves[to].muscle_training(h,a)
    elif event == 'runnning':
        d,s = [int(x) for x in S]
        braves[to].runnning(d,s)
    elif event == 'study':
        c = int(S[0])
        braves[to].study(c)
    elif event == 'pray':
        f = int(S[0])
        braves[to].pray(f)

for brave in braves:
    brave.get_status()
VBA
## class_status
Private lv As Long
Private hp As Long
Private at As Long
Private df As Long
Private sp As Long
Private cl As Long
Private ft As Long

Property Let set_status(l, h, a, d, s, c, f)

    lv = l
    hp = h
    at = a
    df = d
    sp = s
    cl = c
    ft = f
        
End Property

Property Let levelup(h, a, d, s, c, f)

    lv = lv + 1
    hp = hp + h
    at = at + a
    df = df + d
    sp = sp + s
    cl = cl + c
    ft = ft + f
    
End Property

Property Let muscle_training(h, a)

    hp = hp + h
    at = at + a
    
End Property

Property Let running(d, s)

    df = df + d
    sp = sp + s
    
End Property

Property Let study(c)

    cl = cl + c
    
End Property

Property Let pray(f)

    ft = ft + f
    
End Property

Function get_status()

    Debug.Print lv & " " & hp & " " & at & " " & df & " " & sp & " " & cl & " " & ft
    
End Function
## 標準モジュール
Sub class_primer__heros()

    NK = Split(Cells(1, 1), " ")
    N = Val(NK(0))
    K = Val(NK(1))
    
    Dim braves() As New class_status
    ReDim braves(N - 1)
    
    For i = 0 To N - 1
        s = Split(Cells(i + 2, 1), " ")
        braves(i).set_status(Val(s(0)), Val(s(1)), Val(s(2)), Val(s(3)), Val(s(4)), Val(s(5))) = Val(s(6))
    Next
    
    For i = 1 To K
        s = Split(Cells(i + N + 1, 1), " ")
        idx = Val(s(0)) - 1
        eve = s(1)
        If eve = "levelup" Then
            braves(idx).levelup(Val(s(2)), Val(s(3)), Val(s(4)), Val(s(5)), Val(s(6))) = Val(s(7))
        ElseIf eve = "muscle_training" Then
            braves(idx).muscle_training(Val(s(2))) = Val(s(3))
        ElseIf eve = "running" Then
            braves(idx).running(Val(s(2))) = Val(s(3))
        ElseIf eve = "study" Then
            braves(idx).study = Val(s(2))
        ElseIf eve = "pray" Then
            braves(idx).pray = Val(s(2))
        End If
    Next
    
    For i = LBound(braves) To UBound(braves)
        braves(i).get_status
    Next


End Sub

最後に

Python のアンパックがとても便利。それに、pop で要素を削除しながらその要素の値を取得できるというのも気が利いている。VBA では、一つずつ手打ちで処理したのだけれど、何か良い方法があるのだろうか。

本章は「クラス・構造体メニュー」なので、VBA では構造体を利用した方が良かったかもしれないが、ちょっと手を抜いてそのまま書いてしまった。あと、VBA だと、配列のままクラスに渡してしまってクラスの方で配列を処理した方がスマートに見える気がする。そのあたり、正解はどうなんだろうか・・・。

引き続き、よろしくお願いいたします!

Python学習,Python,paiza

Posted by LeoSaki