public static CharacterSoldierTypeData Append(this CharacterSoldierTypeData self, IEnumerable<CharacterSoldierTypeData> d)
 {
   foreach (var dd in d)
   {
     self.Append(dd);
   }
   return self;
 }
   public static CharacterSoldierTypeData Append(this CharacterSoldierTypeData self, CharacterSoldierTypeData d)
 {
   self.PowerStrong += d.PowerStrong;
   self.PowerIntellect += d.PowerIntellect;
   self.PowerPopularity += d.PowerPopularity;
   self.BaseAttack += d.BaseAttack;
   self.BaseDefend += d.BaseDefend;
   self.StrongAttack += d.StrongAttack;
   self.StrongDefend += d.StrongDefend;
   self.IntellectAttack += d.IntellectAttack;
   self.IntellectDefend += d.IntellectDefend;
   self.WallAttack += d.WallAttack;
   self.WallDefend += d.WallDefend;
   self.InfantryAttack += d.InfantryAttack;
   self.InfantryDefend += d.InfantryDefend;
   self.CavalryAttack += d.CavalryAttack;
   self.CavalryDefend += d.CavalryDefend;
   self.CrossbowAttack += d.CrossbowAttack;
   self.CrossbowDefend += d.CrossbowDefend;
   self.WeaponAttack += d.WeaponAttack;
   self.WeaponDefend += d.WeaponDefend;
   self.ContinuousProbability += d.ContinuousProbability;
   self.ContinuousProbabilityOnSingleTurn += d.ContinuousProbabilityOnSingleTurn;
   self.RushProbability += d.RushProbability;
   self.RushAttack += d.RushAttack;
   self.RushDefend += d.RushDefend;
   self.DisorderProbability += d.DisorderProbability;
   self.TypeWallDisorderProbability += d.TypeWallDisorderProbability;
   self.FriendlyFireProbability += d.FriendlyFireProbability;
   self.StrongEx += d.StrongEx;
   self.IntellectEx += d.IntellectEx;
   self.LeadershipEx += d.LeadershipEx;
   self.PopularityEx += d.PopularityEx;
   self.TypeCavalry += d.TypeCavalry;
   self.TypeCrossbow += d.TypeCrossbow;
   self.TypeInfantry += d.TypeInfantry;
   self.TypeWall += d.TypeWall;
   self.TypeWeapon += d.TypeWeapon;
   self.TypeGuard += d.TypeGuard;
   self.TypeInfantryAttack += d.TypeInfantryAttack;
   self.TypeInfantryDefend += d.TypeInfantryDefend;
   self.TypeCavalryAttack += d.TypeCavalryAttack;
   self.TypeGuardAttack += d.TypeGuardAttack;
   self.TypeGuardDefend += d.TypeGuardDefend;
   self.GogyoFire += d.GogyoFire;
   self.GogyoMetal += d.GogyoMetal;
   self.GogyoSoil += d.GogyoSoil;
   self.GogyoTree += d.GogyoTree;
   self.GogyoWater += d.GogyoWater;
   self.GogyoAttack += d.GogyoAttack;
   self.GogyoDefend += d.GogyoDefend;
   return self;
 }
 public static CharacterSoldierTypeData ToData(this IEnumerable<CharacterSoldierTypePart> parts)
 {
   var d = new CharacterSoldierTypeData
   {
     Money = (short)parts.Sum(p => p.Money),
     FakeMoney = (short)parts.Sum(p => p.FakeMoney),
     Technology = (short)parts.Max(p => p.Technology),
   };
   foreach (var p in parts)
   {
     d.Append(p.Data);
   }
   return d;
 }
    private float CalcGogyoPower(CharacterSoldierTypeData target)
    {
      float GetSize(short stronger, short weaker)
      {
        // 0 <= size <= 1
        if (stronger == 0 || weaker == 0)
        {
          return 0;
        }
        var size = (stronger + weaker) / (float)stronger / 2 * (stronger + weaker) / 200.0f;
        return size;
      }

      // 基準値: 1
      return GetSize(this.GogyoTree, target.GogyoWater) + GetSize(this.GogyoTree, target.GogyoSoil) +
        GetSize(this.GogyoFire, target.GogyoTree) + GetSize(this.GogyoFire, target.GogyoMetal) +
        GetSize(this.GogyoSoil, target.GogyoFire) + GetSize(this.GogyoSoil, target.GogyoWater) +
        GetSize(this.GogyoMetal, target.GogyoSoil) + GetSize(this.GogyoMetal, target.GogyoTree) +
        GetSize(this.GogyoWater, target.GogyoMetal) + GetSize(this.GogyoWater, target.GogyoFire);
    }
 public float CalcRushAttack(CharacterSoldierTypeData enemyType, Character enemy)
 {
   return Math.Max(this.RushAttack - (enemyType.RushDefend + enemy.Proficiency * 0.2f), 0) / 8.0f;
 }
    public (int AttackCorrection, int DefendCorrection) CalcCorrections(Character chara, IEnumerable<CharacterSkill> skills, CharacterSoldierTypeData enemyType)
    {
      // 相手が城壁のとき、特殊な戦闘補正がつく
      var typeWall = enemyType.TypeWall / 100.0f;

      var a = (float)this.BaseAttack * (1 - typeWall / 2);
      var d = (float)this.BaseDefend * (1 - typeWall / 2);

      a += this.StrongAttack / 1000.0f * chara.Strong;
      d += this.StrongDefend / 1000.0f * chara.Strong;

      a += this.IntellectAttack / 1000.0f * chara.Intellect;
      d += this.IntellectDefend / 1000.0f * chara.Intellect;

      a += this.WallAttack * typeWall;
      d += this.WallDefend * typeWall;
      a += this.InfantryAttack * enemyType.TypeInfantry / 100.0f;
      d += this.InfantryDefend * enemyType.TypeInfantry / 100.0f;
      a += this.CavalryAttack * enemyType.TypeCavalry / 100.0f;
      d += this.CavalryDefend * enemyType.TypeCavalry / 100.0f;
      a += this.CrossbowAttack * enemyType.TypeCrossbow / 100.0f;
      d += this.CrossbowDefend * enemyType.TypeCrossbow / 100.0f;
      a += this.WeaponAttack * enemyType.TypeWeapon / 100.0f;
      d += this.WeaponDefend * enemyType.TypeWeapon / 100.0f;

      a += this.TypeInfantryAttack * (this.TypeInfantry / 100.0f) * (1 - typeWall);
      d += this.TypeInfantryDefend * (this.TypeInfantry / 100.0f) * (1 - typeWall);
      a += this.TypeCavalryAttack * (this.TypeCavalry / 100.0f) * (1 - typeWall);
      a += this.TypeGuardAttack * (this.TypeGuard / 100.0f) * (1 - typeWall);
      d += this.TypeGuardDefend * (this.TypeGuard / 100.0f) * (1 - typeWall);

      var g = this.CalcGogyoPower(enemyType);
      a += this.GogyoAttack * g * (1 - typeWall);
      d += this.GogyoDefend * g * (1 - typeWall);

      return ((int)a, (int)d);
    }