前回の経験から、まずは例を使って実際にやってみる
ということはわかったんで、とりあえずやってみました
プレーヤー1 (p1)
hp = 10
f1 = 1
a1 = 1
f2 = 2
a2 = 2
f3 = 3
a3 = 3
プレーヤー2 (p2)
hp = 10
f1 = 0 #強化
a1 = 0
f2 = 6
a2 = 1
f3 = 7
a3 = 2
プレーヤー3 (p3)
hp = 10
f1 = 0 #強化
a1 = 0
f2 = 7
a2 = 5
f3 = 8
a3 = 3
1回目: 1 1 2 2
プレーヤー1技1で攻撃(f=1,a=1)
プレーヤー2技2で攻撃 (f=6,a=1)
⇒P1.f1(1) < p2.f2(6) なので、プレイヤー2の hp が p1.f1(1) 減る
プレーヤー1:10
プレーヤー2:9
プレーヤー3:10
2回目: 1 2 3 2
プレーヤー1技2で攻撃(f=2,a=2)
プレーヤー3技2で攻撃(f=7,a=5)
⇒p1.f2(2) < p3.f2(7) なので、プレイヤー3の hp が p1.a1(2) 減る
プレーヤー1:10
プレーヤー2:9
プレーヤー3:8
3回目: 1 3 2 3
プレーヤー1技3で攻撃(f=3,a=3)
プレーヤー2技3で攻撃(f=7,a=2)
⇒p1.f3(3) < p2.f3(7) なので、プレイヤー2の hp が p1.a3(3) 減る
プレーヤー1:10
プレーヤー2:6
プレーヤー3:8
4回目: 2 2 3 1
プレーヤー2技2で攻撃(f=6,a=1)
プレーヤー3技1で強化 (f=0,a=0)
⇒プレイヤー3の hp が p2.a2(1) 減る
プレーヤー1:10
プレーヤー2:6
プレーヤー3:7
⇒プレイヤー3の全ての技の発生フレーム(最短 1 フレーム) を -3 , 攻撃力を +5 する。
f1 = 0 (0は0のまま)
a1 = 0 (0は0のまま)
f2 = 7-3=4
a2 = 5+5=10
f3 = 8-3=5
a3 = 3+5=8
5回目: 2 3 3 1
プレーヤー2技3で攻撃(f=7,a=2)
プレーヤー3技1で攻撃(f=0,a=0)
⇒プレイヤー3の hp が p2.a3(2) 減る
プレーヤー1:10
プレーヤー2:6
プレーヤー3:5
⇒プレイヤー3の全ての技の発生フレーム(最短 1 フレーム) を -3 , 攻撃力を +5 する。
f1 = 0 (0は0のまま)
a1 = 0 (0は0のまま)
f2 = 4-3=1
a2 = 10+5=15
f3 = 5-3=2
a3 = 8+5=13
6回目: 1 2 3 2
プレーヤー1技2で攻撃(f=2,a=2)
プレーヤー3技2で攻撃(f=1,a=15)
⇒p1.f2(2) > p3.f2(1) なので、プレイヤー1の hp が p3.a2(15) 減る
プレーヤー1:0->退場
プレーヤー2:6
プレーヤー3:5
終了
生き残ったのは
2人(p2,p3)
とりあえず理屈はわかったんですが、
ここから一般化するにはどうすればいいか全く見当がつきませんでした。。。
具体的には
・強化技と攻撃技の2つあって、それらをどうメソッドにするか
たぶんfが0、aが0だったら強化技とするみたいな?
・メソッドから各技のフレームや攻撃力をどうやって上下するか
・各プレーヤーの各技のフレームをどうやって比較するか
最初この3つが考えつかなかったです。。。
前回はただそのまま足したりひいたりするのが、if条件がついて難しくなった感じですね。
それと出口のない迷路では、2通りのルートをメソッドにしましたが
今回は3通りなのと数値をどうやって切り分けるかが見当つかないです。
今回はここでギブしました。
class Status():
def __init__(self,hp,f1,a1,f2,a2,f3,a3):
self.hp = hp
self.f1 = f1
self.a1 = a1
self.f2 = f2
self.a2 = a2
self.f3 = f3
self.a3 = a3
def skill_1(self,f1,a1):
def skill_2(self,f2,a2):
def skill_3(self,f3,a3):
N,K = map(int,input().split())
#戦う者たちのステータスを登録
braves = [Status(*input().split()) for _ in range(N)]
#バトル
for _ in range(K):
p1,t1,p2,t2 = map(int,input().split())
#各技のフレームを比較したい
if braves[int(p1)-1].??? < braves[int(p2)-1].???
ここで解答みると、、、全く考えつかないなという解答が出ました。。。
そりゃ無理だわ。
配列を使うという発想が全く出てこなかったです。
後でもう一回します。
max関数は一応自分の解釈で
フレームの計算はmax値が見つからない場合はデフォルト値として1を表示する?という
結論でした
理由としては「他の全ての技の発生フレーム(最短 1 フレーム) を -3」とかいてあるので
最短が1なんですよね。たとえば−1とかはだめなので1を表示するという。
でもmax関数ってイテラブルなものに対してmaxのものを出力するというのがあるのだけど
今回の場合って1つの要素だけなので、どういう意味なのか結局わかってないんですよね汗
一応参考にしたのはpythonのドキュメントですが。
=> そもそもドキュメントを読み間違えていたようで、イテラブルだけでなく、要素もいけました。
ここの部分ですね。
max(arg1, arg2, *args, key=None)
iterable の中で最大の要素、または2つ以上の引数の中で最大のものを返します。と書いてるのに。。。
ドキュメント嫌いなのを直さないとだめだなと思いました。
で、書き直しました。
class Player():
def __init__(self,hp,f1,a1,f2,a2,f3,a3):
self.hp = int(hp)
self.f =[int(f1),int(f2),int(f3)]
self.a =[int(a1),int(a2),int(a3)]
self.alive = True
def enhance(self):
#各技を強化
for i in range(3):
#自身が強化技ならスキップ
if self.f[i] == 0 and self.a[i] == 0:
continue
#−3した結果1より下なら1で固定
self.f[i] = max(self.f[i]-3,1)
self.a[i] += 5
def calc_hp(self, damage):
self.hp -= int(damage)
if self.hp <= 0:
self.alive = False
def get_status(self,i):
return(self.f[i],self.a[i])
def get_alive(self):
return(self.alive)
N,K = map(int,input().split())
#戦う者たちのステータスを登録
players = [Player(*input().split()) for _ in range(N)]
#バトル
for _ in range(K):
#各プレーヤーの出した技
p1,t1,p2,t2 = map(int,input().split())
p1 -= 1
t1 -= 1
p2 -= 1
t2 -= 1
#各技のフレーム・攻撃力を変数へ
f1,a1 = players[p1].get_status(t1)
f2,a2 = players[p2].get_status(t2)
#どっちかのHPが0ならバトルなしでスキップ
if players[p1].alive == False or players[p2].alive == False:
continue
#どっちもまたはどっちかが強化技、攻撃技かで分岐
if f1 == 0 and a1 == 0 and f2 == 0 and a2 == 0:
players[p1].enhance()
players[p2].enhance()
elif f1 == 0 and a1 == 0:
players[p1].enhance()
players[p1].calc_hp(a2)
elif f2 == 0 and a2 == 0:
players[p2].enhance()
players[p2].calc_hp(a1)
else:
if f1 > f2:
players[p1].calc_hp(a2)
elif f1 < f2:
players[p2].calc_hp(a1)
else:
pass
ans = 0
for player in players:
if player.alive == True:
ans += 1
print(ans)
細かい部分で正解とはちょっと異なってますが、大筋は同じです。
型変換とかしないといけない部分があってそこはクラスの方を変えてますね。
念の為コメントとかも入れましたが。