//计算某星球的重要程度 private float StarImportance(StarEntity star) { //Debug.LogFormat ("StarImportance"); //f(g(双方总容量比)*星球容量+g(双方总活力比)*星球活力+星球防御力) return(StarImportanceFormula(AttributeImportanceFormula((float)_aiTotalCapacity / _playerTotalCapacity) * star.Capacity / 2 + AttributeImportanceFormula((float)_aiTotalVigour / _playerTotalVigour) * star.Vigour + star.DEF)); }
//计算某星球过剩兵力 private int CaculateExcessForceCoefficient(int starIndex) { //Debug.LogFormat ("CaculateExcessForceCoefficient"); //获取星球最后情况 StarEntity finalStar = CalculateFuture(starIndex, -1); return((int)(Math.Floor(finalStar.EnemyTroops - finalStar.PlayerTroops) //剩下的兵力 * ExcessForceCoefficientFormula(StarImportance(starIndex)))); //过剩兵力系数 }
//获取星球下标 int FindStarIndex(StarEntity star) { int index = 0; for (; index < _starCopys.Count; index++) { if (_starCopys [index] == star) { break; } } return(index == _starCopys.Count ? -1 : index); }
/** * 接口设定 * 在GameWorld里Planets获取所有星球 * 在Planet类里GetProperty返回star star里面有双方兵力以及各属性 * star里面PlayerTroops和EnemyTroops表示双方兵力 * 每个Solidier里面TimeToDestination是他到目的地所需时间,如果他的状态是在路上的话 */ public void runAI() { //Debug.LogFormat ("runAI"); //获取目标星球下标 int desIndex = getDestination(); if (desIndex == -1) { return; //若没有符合条件的星球 什么也不做 } //获取起点星球和派兵数量 从最近的有己方兵力的星球 过剩兵力为正数的星球 过剩兵力全派过来 int minDistance = int.MaxValue; int sourceIndex = desIndex; //起点星球 int troops = 0; //派遣兵力 float sumExcess = 0; //总过剩兵力 for (int index = 0; index < _starCopys.Count; ++index) { float excess = CaculateExcessForceCoefficient(index); //过剩兵力 if (getDistance(_starCopys [desIndex].Location, _starCopys [index].Location) < minDistance && //距离最小 _starCopys [index].EnemyTroops > 0 && //有AI兵力 excess > 0) { sourceIndex = index; troops = int.Parse(Math.Floor(excess).ToString()); } if (_starCopys [index].EnemyTroops > 0 && //有AI兵力 excess > 0) { sumExcess += excess; } } StarEntity star = CalculateFuture(desIndex, -1); if (sourceIndex != desIndex && sumExcess * 0.8 > star.PlayerTroops - star.EnemyTroops) { GameWorld.Instance.Planets [sourceIndex].SendAISoldiers(GameWorld.Instance.Planets [desIndex], troops); } }
private float getAttackDifficulty(StarEntity star) { //Debug.LogFormat ("getAttackDifficulty"); //复制一份 StarEntity theStar = new StarEntity(star); //获取离这个星球最远的上有AI士兵的星球 float maxDistance = 0; int starIndex = FindStarIndex(star); for (int index = 0; index < _starCopys.Count; ++index) { if (getDistance(theStar.Location, _starCopys [index].Location) > maxDistance && _starCopys[index].EnemyTroops >= 1) { maxDistance = getDistance(theStar.Location, _starCopys [index].Location); } } StarEntity finalStar = CalculateFuture(starIndex, (int)Math.Floor(maxDistance / 5)); return(finalStar.PlayerTroops - finalStar.EnemyTroops); }
public StarEntity(StarEntity star) { SetProperty(star.SelectedState, star.DEF, star.Vigour, star.Capacity, star.Location, star.EnemyTroops, star.PlayerTroops, star.Schedule); }
float getAttackValue(StarEntity star) { return(getAttackDifficulty(star) / StarImportance(star)); }
/* * 模拟双方都不派兵的情况下某个星球t秒后状态 t=-1时为无穷时间 * 公式都放在Formula里面 * */ private StarEntity CalculateFuture(int planetId, int t) { //Debug.LogFormat ("CalculateFuture"); StarEntity star = new StarEntity(_starCopys [planetId]); //复制一份 因为会变 int nowTime = 0; //复制一份 因为会变 List <SoldierOnTheWay> playerOnTheWay = new List <SoldierOnTheWay>(_playerOnTheWay); List <SoldierOnTheWay> aiOnTheWay = new List <SoldierOnTheWay> (_aiOnTheWay); //统计现在双方各有多少兵力是派往这个星球的 //int playerTroopCountToPlanet = TroopCountToPlanet(planetId,playerOnTheWay); //int aiTroopCountToPlanet = TroopCountToPlanet(planetId,aiOnTheWay); while (true) { //函数出口 if (t != -1 && nowTime >= t) { break; } //当这个星球上只有AI的兵力且路上木有到这里来的玩家兵力 或 只有玩家兵力且路上木有到这里来的AI兵力 时结束 =。= if (t == -1 && ((Math.Floor(star.PlayerTroops) < 1 && playerOnTheWay.Count < 1) || (Math.Floor(star.EnemyTroops) < 1 && aiOnTheWay.Count < 1))) { break; } //中立星球的转换 if (star.SelectedState == Star.e_State.AI) { if (star.EnemyTroops < 1 && star.PlayerTroops >= 1) { star.SelectedState = Star.e_State.NeutralityToPlayer; star.Schedule = 0; } } else if (star.SelectedState == Star.e_State.Player) { if (star.EnemyTroops >= 1 && star.PlayerTroops < 1) { star.SelectedState = Star.e_State.NeutralityToAI; star.Schedule = 0; } } else if (star.SelectedState == Star.e_State.NeutralityPeace) //中立星球转换 { if (star.EnemyTroops >= 1 && star.PlayerTroops < 1) { star.SelectedState = Star.e_State.NeutralityToAI; star.Schedule = 0; } if (star.EnemyTroops < 1 && star.PlayerTroops >= 1) { star.SelectedState = Star.e_State.NeutralityToPlayer; star.Schedule = 0; } } else if (star.SelectedState == Star.e_State.NeutralityToAI) { if (star.EnemyTroops < 1) { star.SelectedState = Star.e_State.NeutralityPeace; star.Schedule = 0; } else if (star.Schedule >= 1) { star.SelectedState = Star.e_State.AI; } } else if (star.SelectedState == Star.e_State.NeutralityToPlayer) { if (star.PlayerTroops < 1) { star.SelectedState = Star.e_State.NeutralityPeace; star.Schedule = 0; } else if (star.Schedule >= 1) { star.SelectedState = Star.e_State.Player; } } //占领进度 if (star.SelectedState == Star.e_State.NeutralityToAI) { star.Schedule += Formula.CalculateCaptureProgress(star.EnemyTroops); } else if (star.SelectedState == Star.e_State.NeutralityToPlayer) { star.Schedule += Formula.CalculateCaptureProgress(star.PlayerTroops); } //星球上增加兵力 if (star.SelectedState == Star.e_State.AI) { star.EnemyTroops += Formula.CalculateSoldierIncreasePerTime(star.Vigour); } else if (star.SelectedState == Star.e_State.Player) { star.PlayerTroops += Formula.CalculateSoldierIncreasePerTime(star.Vigour); } //若双方在上面都有兵力 战斗过程 if ((Math.Floor(star.PlayerTroops) > 0) && (Math.Floor(star.EnemyTroops) > 0)) { if (star.SelectedState == Star.e_State.AI) { //这个星球是AI的 float damageForAttackOnePerTime = Formula.CalculateDamageForAttackOnePerTime(star.EnemyTroops, star.PlayerTroops, (float)star.DEF, (float)1); float damageForDefOnePerTime = Formula.CalculateDamageForDefOnePerTime(star.EnemyTroops, star.PlayerTroops, star.DEF, (float)1); star.PlayerTroops += damageForAttackOnePerTime; star.EnemyTroops += damageForDefOnePerTime; } else if (star.SelectedState == Star.e_State.Player) { //这个星球是玩家的 float damageForAttackOnePerTime = Formula.CalculateDamageForAttackOnePerTime(star.PlayerTroops, star.EnemyTroops, star.DEF, (float)1); float damageForDefOnePerTime = Formula.CalculateDamageForDefOnePerTime(star.PlayerTroops, star.EnemyTroops, star.DEF, (float)1); star.PlayerTroops += damageForDefOnePerTime; star.EnemyTroops += damageForAttackOnePerTime; } else { //这个星球是中立的 float damageForPlayerOnePerTime = Formula.CalculateDamageForNeutralOnePerTime(star.PlayerTroops, star.EnemyTroops, (float)1); float damageForEnemyOnePerTime = Formula.CalculateDamageForNeutralOnePerTime(star.EnemyTroops, star.PlayerTroops, (float)1); star.PlayerTroops += damageForPlayerOnePerTime; star.EnemyTroops += damageForEnemyOnePerTime; } } //更新时间 ++nowTime; //更新各自的onTheWay for (int i = playerOnTheWay.Count - 1; i >= 0; --i) { SoldierOnTheWay soldior; soldior.m_needTime = playerOnTheWay[i].m_needTime - 1; soldior.m_origin = playerOnTheWay [i].m_origin; soldior.m_terminal = playerOnTheWay [i].m_terminal; playerOnTheWay [i] = soldior; if (playerOnTheWay[i].m_needTime < 0) { if (playerOnTheWay[i].m_terminal == planetId) { ++star.PlayerTroops; } playerOnTheWay.Remove(playerOnTheWay[i]); } } for (int i = aiOnTheWay.Count - 1; i >= 0; --i) { SoldierOnTheWay soldior; soldior.m_needTime = aiOnTheWay[i].m_needTime - 1; soldior.m_origin = aiOnTheWay [i].m_origin; soldior.m_terminal = aiOnTheWay [i].m_terminal; aiOnTheWay [i] = soldior; if (aiOnTheWay[i].m_needTime < 0) { if (aiOnTheWay[i].m_terminal == planetId) { ++star.EnemyTroops; } aiOnTheWay.Remove(aiOnTheWay[i]); } } //Debug.LogFormat ("第{0}秒 玩家:{1} 电脑:{2}",nowTime,star.PlayerTroops,star.EnemyTroops); } return(star); }