1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

きょうは、くらすで大乱闘した。



問題概要

Paizaの格ゲー問題は、プレイヤーが強化技 or 攻撃技を選んで殴り合うだけ!そして、最後まで生き残ってる人数を出力!

ポイントは、

  • 技は3種類:発生フレームと攻撃力を持つ
  • どちらかが強化技なら相手の攻撃を食らって自分はバフ
  • どっちも攻撃技ならフレーム勝負で速い方が当たる
  • HP0で退場

N K
hp_1 F1_1 A1_1 F2_1 A2_1 F3_1 A3_1
...
hp_N F1_N A1_N F2_N A2_N F3_N A3_N
P1_1 T1_1 P2_1 T2_1
...
P1_K T1_K P2_K T2_K
  • プレイヤー数 N と攻撃回数 K
  • F → フレーム、 A → 攻撃力
  • 0 0 は強化技

入力例:

3 6
10 1 1 2 2 3 3
10 0 0 6 1 7 2
10 0 0 7 5 8 3
1 1 2 2
1 2 3 2
1 3 2 3
2 2 3 1
2 3 3 1
1 2 3 2

出力例:

2






✅ OKコード例:

// ------------------------------
// Player クラス定義
// ------------------------------
class Player {
  constructor(hp, f1, a1, f2, a2, f3, a3) {
    this.hp = hp;
    // f: 技の発生フレーム、a: 攻撃力 を配列で管理
    this.f = [f1, f2, f3];
    this.a = [a1, a2, a3];
  }

  // 強化技の処理: 他の全技を強化する
  enhance() {
    for (let i = 0; i < 3; i++) {
      // これは強化技自身(f=0, a=0)なら無視
      if (this.f[i] === 0 && this.a[i] === 0) continue;

      // 発生フレーム -3 (最短 1) & 攻撃力 +5
      this.a[i] += 5;
      this.f[i] = Math.max(1, this.f[i] - 3);
    }
  }

  // HPが正の値なら生存
  isAlive() {
    return this.hp > 0;
  }

  // ダメージを受ける
  takeDamage(damage) {
    this.hp -= damage;
  }
}

// ------------------------------
// 標準入力 & メイン処理
// ------------------------------
const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

const lines = [];
rl.on('line', (line) => lines.push(line));
rl.on('close', () => {
  // プレイヤー数 n & 攻撃回数 k
  const [n, k] = lines[0].split(' ').map(Number);

  // プレイヤー情報を読み込んでクラス生成
  const players = [];
  for (let i = 1; i <= n; i++) {
    const [hp, f1, a1, f2, a2, f3, a3] = lines[i].split(' ').map(Number);
    players.push(new Player(hp, f1, a1, f2, a2, f3, a3));
  }

  // K 回の攻撃処理
  for (let i = n + 1; i < n + 1 + k; i++) {
    // 各攻撃のプレイヤー番号 & 技番号(1-index なので -1)
    const [p1Index, t1, p2Index, t2] = lines[i].split(' ').map(Number);
    const p1 = players[p1Index - 1];
    const p2 = players[p2Index - 1];

    // 既にどちらかが退場していたら何も起きない
    if (!p1.isAlive() || !p2.isAlive()) continue;

    // 技の発生フレームと攻撃力を取り出す
    const f1 = p1.f[t1 - 1];
    const a1 = p1.a[t1 - 1];
    const f2 = p2.f[t2 - 1];
    const a2 = p2.a[t2 - 1];

    // 強化技かどうかを判定(f=0,a=0 の場合だけ)
    const p1Enhance = (f1 === 0 && a1 === 0);
    const p2Enhance = (f2 === 0 && a2 === 0);

    // ------------------------------
    // 条件分岐
    // ------------------------------

    if (p1Enhance && p2Enhance) {
      // 両方強化技: 互いに強化だけして終了
      p1.enhance();
      p2.enhance();
    } 
    else if (p1Enhance) {
      // p1 が強化技のみ: p1 は強化し、相手の攻撃を受ける
      p1.enhance();
      p1.takeDamage(a2);
    } 
    else if (p2Enhance) {
      // p2 が強化技のみ: p2 は強化し、相手の攻撃を受ける
      p2.enhance();
      p2.takeDamage(a1);
    } 
    else {
      // 両方攻撃技: 発生フレームを比較して速い方が攻撃を通す
      if (f1 < f2) {
        p2.takeDamage(a1); // p1 の攻撃が命中
      } 
      else if (f1 > f2) {
        p1.takeDamage(a2); // p2 の攻撃が命中
      }
      // f1 === f2 の場合は何も起こらない
    }
  }

  // 生存者の数を数えて出力
  const aliveCount = players.filter(p => p.isAlive()).length;
  console.log(aliveCount);
});

✅ ポイント

  • クラス内メソッドの意図
    enhance() は「他の全技にバフをかける」
    isAlive()takeDamage() は自己管理。

  • 攻撃条件の分岐でどう処理が分かれるか
    → 両方バフ → お互いバフだけ
    → 片方バフ → 相手の攻撃を食らう
    → 両方攻撃 → フレーム比較で速い方がヒット。

  • インデックス調整
    → 入力値が 1-index だから -1 を必ず入れる。

※ 補足 Math.max(a, b)

Math.max(a, b)ab のうち大きい方を返す JavaScript の組み込み関数。


🔍Math.max(1, f - 3) の意味

  • f - 3 を計算する。
  • その結果と 1 を比べる。
  • 2つのうち 大きい方 を返す。

つまり、フレームが 1 より小さくなったら 1 を返すので、最短フレーム 1 が担保される。






🗒️ まとめ:ロジックの流れ

1️⃣ プレイヤーの初期状態を読み込む

  • 各プレイヤーは HP と 3 つの技(発生フレーム F と攻撃力 A)を持つ
  • 技の F と A が両方 0 の場合は「強化技」

2️⃣ 攻撃の順に処理する

  • 攻撃回数 K 回分の戦闘が順に与えられる

3️⃣ 戦闘ごとに以下を判定する

  • 先に どちらかのプレイヤーがすでに退場 (HP <= 0) なら何もしない
  • 選んだ技が強化技かを判定
    • F == 0 && A == 0 なら強化技

4️⃣ どちらも強化技の場合

  • 両方のプレイヤーが同時に強化する(他の技を -3 フレーム& +5 ダメージ)

5️⃣ 片方だけ強化技の場合

  • 強化技を使ったプレイヤーは自分の技を強化する
  • 相手が攻撃技なら、その攻撃力分のダメージを受ける

6️⃣ 両方が攻撃技の場合

  • 技の発生フレーム F を比較
    • F1 < F2 → 相手(P2)が攻撃を受ける
    • F1 > F2 → 自分(P1)が攻撃を受ける
    • F1 == F2 → 何も起こらない

7️⃣ 強化効果の適用時

  • 技のフレームを -3(ただし最短 1)
  • 技のダメージを +5

8️⃣ すべての戦闘後

  • HP > 0 のプレイヤーだけカウントして出力



🔑 ポイント

  • 強化は何度も重複して使える(何回でも積み重ねOK)
  • 技を出した直後に強化が即時反映される
  • フレームは必ず 1 以上で止まる
  • 攻撃は必ず片方だけが受ける(同時には受けない)





僕の失敗談(´;ω;`)と解決法🐈

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?