首页 > 解决方案 > javascript function seems correct, yet

问题描述

I am trying to solve the Pokemon Damage Calculator kata, but I can not find the problem with my code

This is my code:

function calculateDamage(yourType, opponentType, attack, defense) {
  let damage = 0;
  const effArr = [
    ["fire", "grass", 2],
    ["grass", "fire", 0.5],
    ["fire", "water", 0.5],
    ["water", "fire", 2],
    ["fire", "electric", 1],
    ["water", "grass", 0.5],
    ["grass", "water", 2],
    ["water", "electric", 0.5],
    ["electric", "water", 2]
    ["grass", "electric", 1]
  ];

  for (i = 0; damage == 0 && i < effArr.length; i++) {
    // console.log(effArr[i].indexOf(yourType) == 0, effArr[i].indexOf(opponentType) === 1, damage)
    if (effArr[i].indexOf(yourType) == 0 && effArr[i].indexOf(opponentType) == 1) {
      damage = (50 * effArr[i][2] * attack / defense)
    }
  }

  return damage;
}

This is the expected result:

calculateDamage("fire", "water", 100, 100)    => 25  
calculateDamage("grass", "water", 100, 100)   => 100
calculateDamage("electric", "fire", 100, 100) => 50
calculateDamage("grass", "electric", 57, 19)  => 150

but instead I get:

calculateDamage("fire", "water", 100, 100)    => true false 0
calculateDamage("grass", "water", 100, 100)   => false false 0
calculateDamage("electric", "fire", 100, 100) => true true 0
calculateDamage("grass", "electric", 57, 19)  => false false 0

标签: javascriptarraysindexof

解决方案


我认为如果您使用对象而不是数组,您可以更有效地解决这个问题 - 这样,您不必使用循环来搜索您的值,而只需使用yourTypeandopponentType作为属性访问器来获取类型有效性

此外,您原来的 Array 方法缺少一些类型对,我认为您错过了 kata 描述的部分内容,其中说“任何类型对自身的影响都不是很有效” - 所以我稍微修改了这些数据

function calculateDamage(yourType, opponentType, attack, defense) {
  const matchups = {
    fire:     {fire: 0.5, water: 0.5, grass: 2.0, electric: 1.0},
    water:    {fire: 2.0, water: 0.5, grass: 0.5, electric: 0.5},
    grass:    {fire: 0.5, water: 2.0, grass: 0.5, electric: 1.0},
    electric: {fire: 1.0, water: 2.0, grass: 1.0, electric: 0.5}
  };

  let effectiveness = matchups[yourType][opponentType];

  return 50 * (attack / defense) * effectiveness;
}

console.log(`("fire", "water", 100, 100)     => ${calculateDamage("fire", "water", 100, 100)}`)
console.log(`("grass", "water", 100, 100)    => ${calculateDamage("grass", "water", 100, 100)}`)
console.log(`("electric", "fire", 100, 100)  => ${calculateDamage("electric", "fire", 100, 100)}`)
console.log(`("grass", "electric", 57, 19)   => ${calculateDamage("grass", "electric", 57, 19)}`)


但是,如果您希望您的方法起作用,则需要填写 的缺失条目electric,并处理,数组倒数第二个条目的缺失。

然后,您只需要添加一个默认effectiveness值即可在您拥有相同类型的比赛时使用;因为这些不会被捕获在您当前的循环中,因为.indexOf()将返回找到的第一个匹配项。为了使这个回退起作用,你的 for 循环中的匹配现在立即返回,最终返回是默认的回退effectiveness

function calculateDamage(yourType, opponentType, attack, defense) {
  let damage = 0;
  let effectiveness = 0.5; // Default value, used for same type matchups

  const effArr = [
    ["fire", "fire", 0.5],
    ["fire", "water", 0.5],
    ["fire", "grass", 2],
    ["fire", "electric", 1],

    ["water", "fire", 2],
    ["water", "water", 0.5],
    ["water", "grass", 0.5],
    ["water", "electric", 0.5],

    ["grass", "fire", 0.5],
    ["grass", "water", 2],
    ["grass", "grass", 0.5],
    ["grass", "electric", 1],

    ["electric", "fire", 1],
    ["electric", "water", 2],
    ["electric", "grass", 1],
    ["electric", "electric", 0.5]
  ];

  for (i = 0; damage == 0 && i < effArr.length; i++) {
    if (effArr[i].indexOf(yourType) == 0 && effArr[i].indexOf(opponentType) == 1) {
     return (50 * effArr[i][2] * attack / defense)
    }
  }

  return (50 * effectiveness  * attack / defense);
}

console.log(`("fire", "water", 100, 100)     => ${calculateDamage("fire", "water", 100, 100)}`)
console.log(`("grass", "water", 100, 100)    => ${calculateDamage("grass", "water", 100, 100)}`)
console.log(`("electric", "fire", 100, 100)  => ${calculateDamage("electric", "fire", 100, 100)}`)
console.log(`("grass", "electric", 57, 19)   => ${calculateDamage("grass", "electric", 57, 19)}`)


推荐阅读