12. if文

このレッスンでは、条件によって処理を分けるif文について学びます。

if文

もし、「ゆうしゃ」の防御力が999だとダメージがマイナスになってしまいます。

<!-- battle.html hidden -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>バトル</title>
    <link rel="stylesheet" href="css/battle.css">
    <script src="js/battle.js" defer></script>
</head>
<body>
    <table id="status">
        <tr>
            <th>ゆうしゃ</th><th>せんし</th><th>そうりょ</th><th>まほうつかい</th>
        </tr>
        <tr><td>HP 153</td><td>HP 198</td><td>HP 101</td><td>HP 77</td></tr>
        <tr><td>MP 25</td><td>MP 0</td><td>MP 35</td><td>MP 58</td></tr>
    </table>
    <div id="monster">
        <img class="dark-knight" src="img/dark-knight.png">
        <img class="dark-lord" src="img/dark-lord.png">
        <img class="demon-priest" src="img/demon-priest.png">
    </div>
    <div id="message">
        まおうがあらわれた。
    </div>
</body>
</html>
/* battle.css hidden */
body {
    background-color: rgb(34, 34, 34);
    color: white;
    font-family: sans-serif;
}
table#status {
    border: solid 2px white;
    border-collapse: collapse;
    margin: 10px auto 0 auto;
    width: 640px;
}
table#status tr:first-child {
    border-bottom: solid 1px white;
}
table#status td {
    text-align: center;
}
#monster {
    text-align: center;
    margin-top: 40px;
}
#monster .dark-lord {
    width: 400px;
}
#monster .dark-knight {
    width: 150px;
}
#monster .demon-priest {
    width: 150px;
}
#message {
    border: solid 2px white;
    border-radius: 4px;
    padding: 10px;
    width: 720px;
    margin: 30px auto;
}
// battle.js highlight:5
const name1 = "ゆうしゃ";
const maxHp1 = 153;
let hp1 = maxHp1;
const attack1 = 162;
const defense1 = 999;

const name2 = "まおう";
const maxHp2 = 999;
let hp2 = maxHp2;
const attack2 = 186;
const defense2 = 58;

let damage = Math.floor((attack2 - defense1) / 2); // -407
hp1 = hp1 - damage;
document.getElementById("message").textContent = `${name1}${damage}のダメージ。`;
document.querySelector("#status tr:nth-child(2) td:nth-child(1)").textContent = `HP ${hp1}`;

ifを使えば、ダメージがマイナスになってしまった場合にダメージを0にできます。

// battle.js selection:13-17 highlight:14-16
const name1 = "ゆうしゃ";
const maxHp1 = 153;
let hp1 = maxHp1;
const attack1 = 162;
const defense1 = 999;

const name2 = "まおう";
const maxHp2 = 999;
let hp2 = maxHp2;
const attack2 = 186;
const defense2 = 58;

let damage = Math.floor((attack2 - defense1) / 2);
if (damage < 0) {
    damage = 0;
}
hp1 = hp1 - damage;
document.getElementById("message").textContent = `${name1}${damage}のダメージ。`;
document.querySelector("#status tr:nth-child(2) td:nth-child(1)").textContent = `HP ${hp1}`;

このように、ifを使えば、条件を満たした場合にだけ実行される処理を書くことができます。

else節

ダメージが0のとき、「ゆうしゃに0のダメージ。」ではなく「ゆうしゃにダメージをあたえられない。」と表示することを考えます。そうすると、「ダメージが0の場合」だけでなく「そうでない(ダメージが0でない)場合」も扱わなければいけません。それを実現するのがif文のelse節です。

else節を使えば、「そうでない場合」を次のように書くことができます。

// battle.js selection:13-23 highlight:18-22
const name1 = "ゆうしゃ";
const maxHp1 = 153;
let hp1 = maxHp1;
const attack1 = 162;
const defense1 = 999;

const name2 = "まおう";
const maxHp2 = 999;
let hp2 = maxHp2;
const attack2 = 186;
const defense2 = 58;

let damage = Math.floor((attack2 - defense1) / 2);
if (damage < 0) {
    damage = 0;
}
hp1 = hp1 - damage;
if (damage === 0) {
    document.getElementById("message").textContent = `${name1}にダメージをあたえられない。`;
} else {
    document.getElementById("message").textContent = `${name1}${damage}のダメージ。`;
}
document.querySelector("#status tr:nth-child(2) td:nth-child(1)").textContent = `HP ${hp1}`;

<>と同様に、等しいかどうかを比較するには===を使います。=は代入に使われているので、比較には===を使います。

HPがマイナスにならないようにする

もし「ゆうしゃ」のHPが10しか残ってなかったら、「まおう」の攻撃でHPがマイナスになってしまいます。

// battle.js selection:1-5 highlight:3
const name1 = "ゆうしゃ";
const maxHp1 = 153;
let hp1 = 10;
const attack1 = 162;
const defense1 = 97;

const name2 = "まおう";
const maxHp2 = 999;
let hp2 = maxHp2;
const attack2 = 186;
const defense2 = 58;

let damage = Math.floor((attack2 - defense1) / 2);
if (damage < 0) {
    damage = 0;
}
hp1 = hp1 - damage;
if (damage === 0) {
    document.getElementById("message").textContent = `${name1}にダメージをあたえられない。`;
} else {
    document.getElementById("message").textContent = `${name1}${damage}のダメージ。`;
}
document.querySelector("#status tr:nth-child(2) td:nth-child(1)").textContent = `HP ${hp1}`;

これではいけないので、ifを使ってHPがマイナスにならないようにします。

// battle.js selection:17-20 highlight:18-20
const name1 = "ゆうしゃ";
const maxHp1 = 153;
let hp1 = 10;
const attack1 = 162;
const defense1 = 97;

const name2 = "まおう";
const maxHp2 = 999;
let hp2 = maxHp2;
const attack2 = 186;
const defense2 = 58;

let damage = Math.floor((attack2 - defense1) / 2);
if (damage < 0) {
    damage = 0;
}
hp1 = hp1 - damage;
if (hp1 < 0) {
    hp1 = 0;
}
if (damage === 0) {
    document.getElementById("message").textContent = `${name1}にダメージをあたえられない。`;
} else {
    document.getElementById("message").textContent = `${name1}${damage}のダメージ。`;
}
document.querySelector("#status tr:nth-child(2) td:nth-child(1)").textContent = `HP ${hp1}`;

「ゆうしゃ」の攻撃

「ゆうしゃ」の攻撃も作ってみましょう。「ゆうしゃ」が先に攻撃して、「まおう」が後から攻撃するようにします。

// battle.js selection:13-40 highlight:13-25,27
const name1 = "ゆうしゃ";
const maxHp1 = 153;
let hp1 = maxHp1;
const attack1 = 162;
const defense1 = 97;

const name2 = "まおう";
const maxHp2 = 999;
let hp2 = maxHp2;
const attack2 = 186;
const defense2 = 58;

let damage = Math.floor((attack1 - defense2) / 2);
if (damage < 0) {
    damage = 0;
}
hp2 = hp2 - damage;
if (hp2 < 0) {
    hp2 = 0;
}
if (damage === 0) {
    document.getElementById("message").textContent = `${name2}にダメージをあたえられない。`;
} else {
    document.getElementById("message").textContent = `${name2}${damage}のダメージ。`;
}

damage = Math.floor((attack2 - defense1) / 2);
if (damage < 0) {
    damage = 0;
}
hp1 = hp1 - damage;
if (hp1 < 0) {
    hp1 = 0;
}
if (damage === 0) {
    document.getElementById("message").textContent = `${name1}にダメージをあたえられない。`;
} else {
    document.getElementById("message").textContent = `${name1}${damage}のダメージ。`;
}
document.querySelector("#status tr:nth-child(2) td:nth-child(1)").textContent = `HP ${hp1}`;

変数 damage は「ゆうしゃ」の攻撃で宣言しているので、「まおう」の攻撃では宣言しません。また、「まおう」のHPは表示されないので、「ゆうしゃ」の攻撃ではHP表示の更新もありません。

試してみよう

これまでの成果

<!-- battle.html folded -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>バトル</title>
    <link rel="stylesheet" href="css/battle.css">
    <script src="js/battle.js" defer></script>
</head>
<body>
    <table id="status">
        <tr>
            <th>ゆうしゃ</th><th>せんし</th><th>そうりょ</th><th>まほうつかい</th>
        </tr>
        <tr><td>HP 153</td><td>HP 198</td><td>HP 101</td><td>HP 77</td></tr>
        <tr><td>MP 25</td><td>MP 0</td><td>MP 35</td><td>MP 58</td></tr>
    </table>
    <div id="monster">
        <img class="dark-knight" src="img/dark-knight.png">
        <img class="dark-lord" src="img/dark-lord.png">
        <img class="demon-priest" src="img/demon-priest.png">
    </div>
    <div id="message">
        まおうがあらわれた。
    </div>
</body>
</html>
/* battle.css folded */
body {
    background-color: rgb(34, 34, 34);
    color: white;
    font-family: sans-serif;
}
table#status {
    border: solid 2px white;
    border-collapse: collapse;
    margin: 10px auto 0 auto;
    width: 640px;
}
table#status tr:first-child {
    border-bottom: solid 1px white;
}
table#status td {
    text-align: center;
}
#monster {
    text-align: center;
    margin-top: 40px;
}
#monster .dark-lord {
    width: 400px;
}
#monster .dark-knight {
    width: 150px;
}
#monster .demon-priest {
    width: 150px;
}
#message {
    border: solid 2px white;
    border-radius: 4px;
    padding: 10px;
    width: 720px;
    margin: 30px auto;
}
// battle.js
const name1 = "ゆうしゃ";
const maxHp1 = 153;
let hp1 = maxHp1;
const attack1 = 162;
const defense1 = 97;

const name2 = "まおう";
const maxHp2 = 999;
let hp2 = maxHp2;
const attack2 = 186;
const defense2 = 58;

let damage = Math.floor((attack1 - defense2) / 2);
if (damage < 0) {
    damage = 0;
}
hp2 = hp2 - damage;
if (hp2 < 0) {
    hp2 = 0;
}
if (damage === 0) {
    document.getElementById("message").textContent = `${name2}にダメージをあたえられない。`;
} else {
    document.getElementById("message").textContent = `${name2}${damage}のダメージ。`;
}

damage = Math.floor((attack2 - defense1) / 2);
if (damage < 0) {
    damage = 0;
}
hp1 = hp1 - damage;
if (hp1 < 0) {
    hp1 = 0;
}
if (damage === 0) {
    document.getElementById("message").textContent = `${name1}にダメージをあたえられない。`;
} else {
    document.getElementById("message").textContent = `${name1}${damage}のダメージ。`;
}
document.querySelector("#status tr:nth-child(2) td:nth-child(1)").textContent = `HP ${hp1}`;