@Nivaech

Как более грамотно переписать подобный код?

Простая игра.
У игрока и у оппонента есть уровень здоровья и шанс на удар. Шанс определяется случайным числом, и если оно больше, чем у оппонента, идет удар, сила которого зависит от того, насколько число шанса было ближе к максимальному значению, то есть к десяти. С каждым ходом здоровье уменьшается, и игра заканчивается тогда, когда здоровье одной из сторон меньше либо равно нулю.
При все простоте код выглядит довольно громоздко. Есть ли какие-нибудь варианты, как переписать его более грамотно и чисто?

const simpleFight= () => {
    let player_hp = 100;
    let enemy_hp = 100;
    console.log(`Welcome! Yor health is - ${player_hp}%, your enemy health - ${enemy_hp}%`);
    
    while (player_hp || enemy_hp > 0) {
        let player_chance = Math.floor(Math.random() * 11);
        let enemy_chance = Math.floor(Math.random() * 11);
        console.log(`your chance - ${player_chance}, your opponent chance - ${enemy_chance}`);
        if (player_chance > enemy_chance) {
            console.log("Your turn...");
            if (player_chance <= 10 && player_chance > 7) {
                console.log("You did a critical hit!");
                enemy_hp -= 40;
                console.log(`enemy hp - ${enemy_hp}`);
            } else if (player_chance <= 7 && player_chance > 5) {
                console.log("You did a big hit!");
                enemy_hp -= 20;
                console.log(`enemy hp - ${enemy_hp}`);
            } else if (player_chance <= 5 && player_chance > 0) {
                console.log("You did a weak hit");
                enemy_hp -= 10;
                console.log(`enemy hp - ${enemy_hp}`);
            }
        } else if (enemy_chance > player_chance) {
            console.log("Your opponents turn...")
            if (enemy_chance <= 10 && enemy_chance > 7) {
                console.log("Opponent did a critical hit!");
                player_hp -=  40;
                console.log(`your hp - ${player_hp}`);
            } else if (enemy_chance <= 7 && enemy_chance > 5){
                console.log("Opponent did a big hit!");
                player_hp -= 20;
                console.log(`your hp - ${player_hp}`);
            } else if (enemy_chance <= 5 && enemy_chance > 0) {
                console.log("Opponent did a weak hit");
                player_hp -= 10;
                console.log(`your hp - ${player_hp}`);
            }
        }
        if (enemy_hp <= 0) {
            console.log(`You win! Your hp level - ${player_hp}, opponents hp level - ${enemy_hp}`);
            break;
        } else if (player_hp <= 0) {
            console.log(`You lost! Your hp level - ${player_hp}, opponents hp level - ${enemy_hp}`);
            break;
        }
    }
}
  • Вопрос задан
  • 162 просмотра
Решения вопроса 2
0xD34F
@0xD34F Куратор тега JavaScript
const attacks = [
  { minChance: 7, damage: 40, name: 'critical' },
  { minChance: 5, damage: 20, name: 'big' },
  { minChance: 0, damage: 10, name: 'weak' },
];

const messages = {
  start: (player, enemy) => `Welcome! Yor health is - ${player}%, your enemy health - ${enemy}%`,
  end: (player, enemy) => `You ${enemy <= 0 ? 'win' : 'lost'}! Your hp level - ${player}, opponents hp level - ${enemy}`,
  chance: (player, enemy) => `your chance - ${player}, your opponent chance - ${enemy}`,
  turn: (player, enemy, hit, isEnemy) =>
`${isEnemy ? 'Enemy' : 'Your'} turn...
${isEnemy ? 'Enemy' : 'You'} did a ${hit} hit
${isEnemy ? 'Your' : 'Enemy'} hp - ${isEnemy ? player : enemy}`,
};


const simpleFight = () => {
  const hp = [ 100, 100 ];

  console.log(messages.start(...hp));

  while (hp.every(n => n > 0)) {
    const chances = hp.map(() => Math.random() * 11 | 0);

    console.log(messages.chance(...chances));

    if (chances[0] !== chances[1]) {
      const chance = Math.max(...chances);
      const attack = attacks.find(n => n.minChance < chance);
      const isEnemyAttacks = chance === chances[1];
      hp[+!isEnemyAttacks] -= attack.damage;

      console.log(messages.turn(...hp, attack.name, isEnemyAttacks));
    }
  }

  console.log(messages.end(...hp));
};
Ответ написан
sergiks
@sergiks Куратор тега JavaScript
♬♬
Дублируется логика вычисления урона здоровью от случайного балла, надо её в функцию:
const hpDelta = chance => 10 + (chance > 5 ? 10 : 0) + (chance > 7 ? 20 : 0);


spoiler
const simpleFight = () => {
    let player_hp = 100;
    let enemy_hp = 100;
    let player_chance;
    let enemy_chance;

    const hpDelta = chance => 10 + (chance > 5 ? 10 : 0) + (chance > 7 ? 20 : 0);
    const randomChance = () => Math.floor(Math.random() * 11);
    const healthReport = hello => console.log(`${hello||''} Your health: ${player_hp}%, enemy health: ${enemy_hp}%`);
    const chanceReport = hello => console.log(`${hello||''} Your chance: ${player_chance}, enemy chance: ${enemy_chance}`);

    healthReport("Welcome!");

    while (player_hp || enemy_hp > 0) {
        player_chance = randomChance();
        enemy_chance = randomChance();
        chanceReport();
        if (player_chance > enemy_chance) {
            enemy_hp -= hpDelta(player_chance);
            console.log(`Your turn. Enemy health updated to: ${enemy_hp}%`);
        } else if (enemy_chance > player_chance) {
            player_hp = hpDelta(enemy_chance);
            console.log(`Enemy's turn. Your health updated to: ${player_hp}%`);
        } else {
            chanceReport('Equal chances!');
        }

        if (enemy_hp <= 0) {
            healthReport('You win!');
            break;
        } else if (player_hp <= 0) {
            healthReport('You lost!');
            break;
        }
    }
}


simpleFight();
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
ms-dred
@ms-dred
Вечно что то не то и что то не так...
Мне кажется эта конструкция лишняя на данном этапе по крайней мере
if (player_chance > enemy_chance) {
else if (enemy_chance > player_chance)

Там разные переменные фигурируют, почему бы их последовательно не определить.
И лишнее когда переменную переопределяете постоянно
player_hp -= **
Можно сделать что то вроде того (Примерно!)
enemy_hp -= (p <= 10 && p > 7) && 40 || (p <= 7 && p > 5) && 20 || (p <= 5 && p > 0) && 10
player_hp -= (e <= 10 && e > 7) && 40 || (e <= 7 && e > 5) && 20 || (e <= 5 && e > 0) && 10

Ну и тут придется создать функции с цепочками действий, будет и понятно, и гибко

Пока писал заметил что так будет даже лучше
enemy_hp = hp(player_chance)
player_hp = hp(enemy_chance)

function hp(e) {
    return (e <= 10 && e > 7) && 40 || (e <= 7 && e > 5) && 20 || (e <= 5 && e > 0) && 10
}

Но и это еще улучшить можно
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы