19. for...of文
このレッスンでは、Arrayの要素をより直感的に扱えるfor…of文について学びます。
for文の煩わしさ
前回のレッスンで、for文を使ってArrayの要素を処理しました。
<!-- 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 selection:52-54
function sleep() {
return new Promise(resolve => setTimeout(resolve, 1000));
}
function calculateDamage(attack, defense) {
let damage = Math.floor((attack - defense) / 2);
if (damage < 0) {
damage = 0;
}
return damage;
}
function calculateHp(hp, damage) {
hp = hp - damage;
if (hp < 0) {
hp = 0;
}
return hp;
}
function displayMessage(message) {
document.getElementById("message").textContent = message;
}
function displayDamageMessage(name, damage) {
if (damage === 0) {
displayMessage(`${name}にダメージをあたえられない。`);
} else {
displayMessage(`${name}に${damage}のダメージ。`);
}
}
function isAlive(character) {
return character.hp > 0;
}
function displayDeadMessage(name, isFriend) {
if (isFriend) {
displayMessage(`${name}はしんでしまった。`);
} else {
displayMessage(`${name}をやっつけた。`);
}
}
async function main() {
const friendParty = [
{ name: "ゆうしゃ", maxHp: 153, attack: 162, defense: 97 },
{ name: "せんし", maxHp: 198, attack: 178, defense: 111 },
{ name: "そうりょ", maxHp: 101, attack: 76, defense: 55 },
{ name: "まほうつかい", maxHp: 77, attack: 60, defense: 57 }
];
for (let i = 0; i < friendParty.length; i++) {
friendParty[i].hp = friendParty[i].maxHp;
}
const enemyParty = [
{ name: "あんこくきし", maxHp: 250, attack: 181, defense: 93 },
{ name: "まおう", maxHp: 999, attack: 186, defense: 58 },
{ name: "デモンプリースト", maxHp: 180, attack: 121, defense: 55 }
];
for (let i = 0; i < enemyParty.length; i++) {
enemyParty[i].hp = enemyParty[i].maxHp;
}
while (true) {
for (let i = 0; i < friendParty.length; i++) {
if (!isAlive(friendParty[i])) {
continue;
}
displayMessage(`${friendParty[i].name}のこうげき。`);
await sleep();
if (!isAlive(enemyParty[0])) {
displayMessage(`${enemyParty[0].name}はすでにしんでいる。`);
await sleep();
continue;
}
let damage = calculateDamage(friendParty[i].attack, enemyParty[0].defense);
enemyParty[0].hp = calculateHp(enemyParty[0].hp, damage);
displayDamageMessage(enemyParty[0].name, damage);
await sleep();
if (!isAlive(enemyParty[0])) {
document.querySelector("#monster img:nth-child(1)").style.visibility = "hidden";
displayDeadMessage(enemyParty[0].name, false);
await sleep();
}
}
for (let i = 0; i < enemyParty.length; i++) {
if (!isAlive(enemyParty[i])) {
continue;
}
displayMessage(`${enemyParty[i].name}のこうげき。`);
await sleep();
if (!isAlive(friendParty[0])) {
displayMessage(`${friendParty[0].name}はすでにしんでいる。`);
await sleep();
continue;
}
let damage = calculateDamage(enemyParty[i].attack, friendParty[0].defense);
friendParty[0].hp = calculateHp(friendParty[0].hp, damage);
displayDamageMessage(friendParty[0].name, damage);
await sleep();
document.querySelector("#status tr:nth-child(2) td:nth-child(1)").textContent = `HP ${friendParty[0].hp}`;
if (!isAlive(friendParty[0])) {
displayDeadMessage(friendParty[0].name, true);
await sleep();
}
}
}
}
main();
このコードは動作しますが、少し煩わしい点があります。
- インデックス
iをインクリメントしながらループする friendParty[i]と書くたびにArrayから要素を取り出す
単に「Arrayの要素を1つずつ取り出して処理をしたい」だけなのに、インデックスをインクリメントしながらループして間接的に要素にアクセスするのは複雑です。
for…of文
JavaScriptには、Arrayの要素を1つずつ取り出せるfor…of文があります。
for (const character of friendParty) {
character.hp = character.maxHp;
}
for…of文は次の構文で書きます。
for (const 要素を受け取る変数 of Array) {
// 繰り返す処理
}
ofの後にArrayを書くと、そのArrayの各要素が変数に順番に代入され、処理が繰り返されます。
for文と比較してみましょう。
// for
for (let i = 0; i < friendParty.length; i++) {
friendParty[i].hp = friendParty[i].maxHp;
}
// for...of
for (const character of friendParty) {
character.hp = character.maxHp;
}
for…of文では、インデックス変数iやfriendParty[i]が不要になり、characterという名前で要素を直接参照できます。コードの意図がより明確になりました。
for…of文の動作
for…of文がどのように動作するか、詳しく見てみましょう。
const friendParty = [
{ name: "ゆうしゃ", maxHp: 153 },
{ name: "せんし", maxHp: 198 },
{ name: "そうりょ", maxHp: 101 },
{ name: "まほうつかい", maxHp: 77 }
];
for (const character of friendParty) {
console.log(character.name);
}
ゆうしゃ
せんし
そうりょ
まほうつかい
ループが実行されるたびに:
- Arrayの次の要素が
characterに代入される - ループ本体が実行される
- Arrayの最後に達したらループを終了
characterにはオブジェクト全体({ name: "ゆうしゃ", maxHp: 153 }など)が代入されるので、character.nameやcharacter.maxHpでプロパティにアクセスできます。
HP初期化をfor…ofで書き換える
それでは、味方パーティのHP初期化をfor…of文で書き換えてみましょう。
// battle.js selection:46-54 highlight:52-54
function sleep() {
return new Promise(resolve => setTimeout(resolve, 1000));
}
function calculateDamage(attack, defense) {
let damage = Math.floor((attack - defense) / 2);
if (damage < 0) {
damage = 0;
}
return damage;
}
function calculateHp(hp, damage) {
hp = hp - damage;
if (hp < 0) {
hp = 0;
}
return hp;
}
function displayMessage(message) {
document.getElementById("message").textContent = message;
}
function displayDamageMessage(name, damage) {
if (damage === 0) {
displayMessage(`${name}にダメージをあたえられない。`);
} else {
displayMessage(`${name}に${damage}のダメージ。`);
}
}
function isAlive(character) {
return character.hp > 0;
}
function displayDeadMessage(name, isFriend) {
if (isFriend) {
displayMessage(`${name}はしんでしまった。`);
} else {
displayMessage(`${name}をやっつけた。`);
}
}
async function main() {
const friendParty = [
{ name: "ゆうしゃ", maxHp: 153, attack: 162, defense: 97 },
{ name: "せんし", maxHp: 198, attack: 178, defense: 111 },
{ name: "そうりょ", maxHp: 101, attack: 76, defense: 55 },
{ name: "まほうつかい", maxHp: 77, attack: 60, defense: 57 }
];
for (const character of friendParty) {
character.hp = character.maxHp;
}
const enemyParty = [
{ name: "あんこくきし", maxHp: 250, attack: 181, defense: 93 },
{ name: "まおう", maxHp: 999, attack: 186, defense: 58 },
{ name: "デモンプリースト", maxHp: 180, attack: 121, defense: 55 }
];
for (let i = 0; i < enemyParty.length; i++) {
enemyParty[i].hp = enemyParty[i].maxHp;
}
while (true) {
for (let i = 0; i < friendParty.length; i++) {
if (!isAlive(friendParty[i])) {
continue;
}
displayMessage(`${friendParty[i].name}のこうげき。`);
await sleep();
if (!isAlive(enemyParty[0])) {
displayMessage(`${enemyParty[0].name}はすでにしんでいる。`);
await sleep();
continue;
}
let damage = calculateDamage(friendParty[i].attack, enemyParty[0].defense);
enemyParty[0].hp = calculateHp(enemyParty[0].hp, damage);
displayDamageMessage(enemyParty[0].name, damage);
await sleep();
if (!isAlive(enemyParty[0])) {
document.querySelector("#monster img:nth-child(1)").style.visibility = "hidden";
displayDeadMessage(enemyParty[0].name, false);
await sleep();
}
}
for (let i = 0; i < enemyParty.length; i++) {
if (!isAlive(enemyParty[i])) {
continue;
}
displayMessage(`${enemyParty[i].name}のこうげき。`);
await sleep();
if (!isAlive(friendParty[0])) {
displayMessage(`${friendParty[0].name}はすでにしんでいる。`);
await sleep();
continue;
}
let damage = calculateDamage(enemyParty[i].attack, friendParty[0].defense);
friendParty[0].hp = calculateHp(friendParty[0].hp, damage);
displayDamageMessage(friendParty[0].name, damage);
await sleep();
document.querySelector("#status tr:nth-child(2) td:nth-child(1)").textContent = `HP ${friendParty[0].hp}`;
if (!isAlive(friendParty[0])) {
displayDeadMessage(friendParty[0].name, true);
await sleep();
}
}
}
}
main();
friendParty[i].hpがcharacter.hpになり、コードがシンプルになりました。
敵パーティのHP初期化も同様にfor…of文で書き換えてみてください。
// battle.js highlight:61-63 folded
function sleep() {
return new Promise(resolve => setTimeout(resolve, 1000));
}
function calculateDamage(attack, defense) {
let damage = Math.floor((attack - defense) / 2);
if (damage < 0) {
damage = 0;
}
return damage;
}
function calculateHp(hp, damage) {
hp = hp - damage;
if (hp < 0) {
hp = 0;
}
return hp;
}
function displayMessage(message) {
document.getElementById("message").textContent = message;
}
function displayDamageMessage(name, damage) {
if (damage === 0) {
displayMessage(`${name}にダメージをあたえられない。`);
} else {
displayMessage(`${name}に${damage}のダメージ。`);
}
}
function isAlive(character) {
return character.hp > 0;
}
function displayDeadMessage(name, isFriend) {
if (isFriend) {
displayMessage(`${name}はしんでしまった。`);
} else {
displayMessage(`${name}をやっつけた。`);
}
}
async function main() {
const friendParty = [
{ name: "ゆうしゃ", maxHp: 153, attack: 162, defense: 97 },
{ name: "せんし", maxHp: 198, attack: 178, defense: 111 },
{ name: "そうりょ", maxHp: 101, attack: 76, defense: 55 },
{ name: "まほうつかい", maxHp: 77, attack: 60, defense: 57 }
];
for (const character of friendParty) {
character.hp = character.maxHp;
}
const enemyParty = [
{ name: "あんこくきし", maxHp: 250, attack: 181, defense: 93 },
{ name: "まおう", maxHp: 999, attack: 186, defense: 58 },
{ name: "デモンプリースト", maxHp: 180, attack: 121, defense: 55 }
];
for (const character of enemyParty) {
character.hp = character.maxHp;
}
while (true) {
for (let i = 0; i < friendParty.length; i++) {
if (!isAlive(friendParty[i])) {
continue;
}
displayMessage(`${friendParty[i].name}のこうげき。`);
await sleep();
if (!isAlive(enemyParty[0])) {
displayMessage(`${enemyParty[0].name}はすでにしんでいる。`);
await sleep();
continue;
}
let damage = calculateDamage(friendParty[i].attack, enemyParty[0].defense);
enemyParty[0].hp = calculateHp(enemyParty[0].hp, damage);
displayDamageMessage(enemyParty[0].name, damage);
await sleep();
if (!isAlive(enemyParty[0])) {
document.querySelector("#monster img:nth-child(1)").style.visibility = "hidden";
displayDeadMessage(enemyParty[0].name, false);
await sleep();
}
}
for (let i = 0; i < enemyParty.length; i++) {
if (!isAlive(enemyParty[i])) {
continue;
}
displayMessage(`${enemyParty[i].name}のこうげき。`);
await sleep();
if (!isAlive(friendParty[0])) {
displayMessage(`${friendParty[0].name}はすでにしんでいる。`);
await sleep();
continue;
}
let damage = calculateDamage(enemyParty[i].attack, friendParty[0].defense);
friendParty[0].hp = calculateHp(friendParty[0].hp, damage);
displayDamageMessage(friendParty[0].name, damage);
await sleep();
document.querySelector("#status tr:nth-child(2) td:nth-child(1)").textContent = `HP ${friendParty[0].hp}`;
if (!isAlive(friendParty[0])) {
displayDeadMessage(friendParty[0].name, true);
await sleep();
}
}
}
}
main();
攻撃ループをfor…ofで書き換える
攻撃ループもfor…of文で書き換えてみましょう。
// battle.js selection:66-87 highlight:66,67,70,77
function sleep() {
return new Promise(resolve => setTimeout(resolve, 1000));
}
function calculateDamage(attack, defense) {
let damage = Math.floor((attack - defense) / 2);
if (damage < 0) {
damage = 0;
}
return damage;
}
function calculateHp(hp, damage) {
hp = hp - damage;
if (hp < 0) {
hp = 0;
}
return hp;
}
function displayMessage(message) {
document.getElementById("message").textContent = message;
}
function displayDamageMessage(name, damage) {
if (damage === 0) {
displayMessage(`${name}にダメージをあたえられない。`);
} else {
displayMessage(`${name}に${damage}のダメージ。`);
}
}
function isAlive(character) {
return character.hp > 0;
}
function displayDeadMessage(name, isFriend) {
if (isFriend) {
displayMessage(`${name}はしんでしまった。`);
} else {
displayMessage(`${name}をやっつけた。`);
}
}
async function main() {
const friendParty = [
{ name: "ゆうしゃ", maxHp: 153, attack: 162, defense: 97 },
{ name: "せんし", maxHp: 198, attack: 178, defense: 111 },
{ name: "そうりょ", maxHp: 101, attack: 76, defense: 55 },
{ name: "まほうつかい", maxHp: 77, attack: 60, defense: 57 }
];
for (const character of friendParty) {
character.hp = character.maxHp;
}
const enemyParty = [
{ name: "あんこくきし", maxHp: 250, attack: 181, defense: 93 },
{ name: "まおう", maxHp: 999, attack: 186, defense: 58 },
{ name: "デモンプリースト", maxHp: 180, attack: 121, defense: 55 }
];
for (const character of enemyParty) {
character.hp = character.maxHp;
}
while (true) {
for (const character of friendParty) {
if (!isAlive(character)) {
continue;
}
displayMessage(`${character.name}のこうげき。`);
await sleep();
if (!isAlive(enemyParty[0])) {
displayMessage(`${enemyParty[0].name}はすでにしんでいる。`);
await sleep();
continue;
}
let damage = calculateDamage(character.attack, enemyParty[0].defense);
enemyParty[0].hp = calculateHp(enemyParty[0].hp, damage);
displayDamageMessage(enemyParty[0].name, damage);
await sleep();
if (!isAlive(enemyParty[0])) {
document.querySelector("#monster img:nth-child(1)").style.visibility = "hidden";
displayDeadMessage(enemyParty[0].name, false);
await sleep();
}
}
for (let i = 0; i < enemyParty.length; i++) {
if (!isAlive(enemyParty[i])) {
continue;
}
displayMessage(`${enemyParty[i].name}のこうげき。`);
await sleep();
if (!isAlive(friendParty[0])) {
displayMessage(`${friendParty[0].name}はすでにしんでいる。`);
await sleep();
continue;
}
let damage = calculateDamage(enemyParty[i].attack, friendParty[0].defense);
friendParty[0].hp = calculateHp(friendParty[0].hp, damage);
displayDamageMessage(friendParty[0].name, damage);
await sleep();
document.querySelector("#status tr:nth-child(2) td:nth-child(1)").textContent = `HP ${friendParty[0].hp}`;
if (!isAlive(friendParty[0])) {
displayDeadMessage(friendParty[0].name, true);
await sleep();
}
}
}
}
main();
friendParty[i].nameがcharacter.nameに、friendParty[i].attackがcharacter.attackになり、コードが読みやすくなりました。
なお、攻撃対象のenemyParty[0]はfor…ofで置き換えていません。これは、ループで順番に処理しているのは味方パーティのメンバーであり、攻撃対象は常にenemyPartyの先頭(インデックス0)の敵で固定だからです。
敵の攻撃ループも同様にfor…of文で書き換えてみてください。
// battle.js highlight:89,90,93,100 folded
function sleep() {
return new Promise(resolve => setTimeout(resolve, 1000));
}
function calculateDamage(attack, defense) {
let damage = Math.floor((attack - defense) / 2);
if (damage < 0) {
damage = 0;
}
return damage;
}
function calculateHp(hp, damage) {
hp = hp - damage;
if (hp < 0) {
hp = 0;
}
return hp;
}
function displayMessage(message) {
document.getElementById("message").textContent = message;
}
function displayDamageMessage(name, damage) {
if (damage === 0) {
displayMessage(`${name}にダメージをあたえられない。`);
} else {
displayMessage(`${name}に${damage}のダメージ。`);
}
}
function isAlive(character) {
return character.hp > 0;
}
function displayDeadMessage(name, isFriend) {
if (isFriend) {
displayMessage(`${name}はしんでしまった。`);
} else {
displayMessage(`${name}をやっつけた。`);
}
}
async function main() {
const friendParty = [
{ name: "ゆうしゃ", maxHp: 153, attack: 162, defense: 97 },
{ name: "せんし", maxHp: 198, attack: 178, defense: 111 },
{ name: "そうりょ", maxHp: 101, attack: 76, defense: 55 },
{ name: "まほうつかい", maxHp: 77, attack: 60, defense: 57 }
];
for (const character of friendParty) {
character.hp = character.maxHp;
}
const enemyParty = [
{ name: "あんこくきし", maxHp: 250, attack: 181, defense: 93 },
{ name: "まおう", maxHp: 999, attack: 186, defense: 58 },
{ name: "デモンプリースト", maxHp: 180, attack: 121, defense: 55 }
];
for (const character of enemyParty) {
character.hp = character.maxHp;
}
while (true) {
for (const character of friendParty) {
if (!isAlive(character)) {
continue;
}
displayMessage(`${character.name}のこうげき。`);
await sleep();
if (!isAlive(enemyParty[0])) {
displayMessage(`${enemyParty[0].name}はすでにしんでいる。`);
await sleep();
continue;
}
let damage = calculateDamage(character.attack, enemyParty[0].defense);
enemyParty[0].hp = calculateHp(enemyParty[0].hp, damage);
displayDamageMessage(enemyParty[0].name, damage);
await sleep();
if (!isAlive(enemyParty[0])) {
document.querySelector("#monster img:nth-child(1)").style.visibility = "hidden";
displayDeadMessage(enemyParty[0].name, false);
await sleep();
}
}
for (const character of enemyParty) {
if (!isAlive(character)) {
continue;
}
displayMessage(`${character.name}のこうげき。`);
await sleep();
if (!isAlive(friendParty[0])) {
displayMessage(`${friendParty[0].name}はすでにしんでいる。`);
await sleep();
continue;
}
let damage = calculateDamage(character.attack, friendParty[0].defense);
friendParty[0].hp = calculateHp(friendParty[0].hp, damage);
displayDamageMessage(friendParty[0].name, damage);
await sleep();
document.querySelector("#status tr:nth-child(2) td:nth-child(1)").textContent = `HP ${friendParty[0].hp}`;
if (!isAlive(friendParty[0])) {
displayDeadMessage(friendParty[0].name, true);
await sleep();
}
}
}
}
main();
試してみよう
- 数値のArrayを作ってfor…of文で合計を求めてみましょう
これまでの成果
<!-- 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
function sleep() {
return new Promise(resolve => setTimeout(resolve, 1000));
}
function calculateDamage(attack, defense) {
let damage = Math.floor((attack - defense) / 2);
if (damage < 0) {
damage = 0;
}
return damage;
}
function calculateHp(hp, damage) {
hp = hp - damage;
if (hp < 0) {
hp = 0;
}
return hp;
}
function displayMessage(message) {
document.getElementById("message").textContent = message;
}
function displayDamageMessage(name, damage) {
if (damage === 0) {
displayMessage(`${name}にダメージをあたえられない。`);
} else {
displayMessage(`${name}に${damage}のダメージ。`);
}
}
function isAlive(character) {
return character.hp > 0;
}
function displayDeadMessage(name, isFriend) {
if (isFriend) {
displayMessage(`${name}はしんでしまった。`);
} else {
displayMessage(`${name}をやっつけた。`);
}
}
async function main() {
const friendParty = [
{ name: "ゆうしゃ", maxHp: 153, attack: 162, defense: 97 },
{ name: "せんし", maxHp: 198, attack: 178, defense: 111 },
{ name: "そうりょ", maxHp: 101, attack: 76, defense: 55 },
{ name: "まほうつかい", maxHp: 77, attack: 60, defense: 57 }
];
for (const character of friendParty) {
character.hp = character.maxHp;
}
const enemyParty = [
{ name: "あんこくきし", maxHp: 250, attack: 181, defense: 93 },
{ name: "まおう", maxHp: 999, attack: 186, defense: 58 },
{ name: "デモンプリースト", maxHp: 180, attack: 121, defense: 55 }
];
for (const character of enemyParty) {
character.hp = character.maxHp;
}
while (true) {
for (const character of friendParty) {
if (!isAlive(character)) {
continue;
}
displayMessage(`${character.name}のこうげき。`);
await sleep();
if (!isAlive(enemyParty[0])) {
displayMessage(`${enemyParty[0].name}はすでにしんでいる。`);
await sleep();
continue;
}
let damage = calculateDamage(character.attack, enemyParty[0].defense);
enemyParty[0].hp = calculateHp(enemyParty[0].hp, damage);
displayDamageMessage(enemyParty[0].name, damage);
await sleep();
if (!isAlive(enemyParty[0])) {
document.querySelector("#monster img:nth-child(1)").style.visibility = "hidden";
displayDeadMessage(enemyParty[0].name, false);
await sleep();
}
}
for (const character of enemyParty) {
if (!isAlive(character)) {
continue;
}
displayMessage(`${character.name}のこうげき。`);
await sleep();
if (!isAlive(friendParty[0])) {
displayMessage(`${friendParty[0].name}はすでにしんでいる。`);
await sleep();
continue;
}
let damage = calculateDamage(character.attack, friendParty[0].defense);
friendParty[0].hp = calculateHp(friendParty[0].hp, damage);
displayDamageMessage(friendParty[0].name, damage);
await sleep();
document.querySelector("#status tr:nth-child(2) td:nth-child(1)").textContent = `HP ${friendParty[0].hp}`;
if (!isAlive(friendParty[0])) {
displayDeadMessage(friendParty[0].name, true);
await sleep();
}
}
}
}
main();