public Unit ChooseTarget(Unit unit, ref Vector2 attackPosition) { Vector2 startingPosition = unit.xy; Unit chosenTarget = null; float bestAttackValue = -100000; UnitPather pather = new UnitPather(unit); foreach (Vector2 position in pather.BehaviorMovePositions(attacking: true)) { GridManager.MoveUnit(startingPosition, position, () => {}); foreach (Vector2 targetPosition in GridManager.GetCoordsToAttackHighlight(unit.xy, unit.range)) { Unit target = GridManager.GetUnit(targetPosition); if (target) { if (target.owner != unit.owner) { int attackerStartingHealth = unit.health; int defenderStartingHealth = target.health; Unit[] outCome = Combat.CalculateCombatForUnits(unit, target); int damageDone = defenderStartingHealth - outCome[1].health; int damageTaken = attackerStartingHealth - outCome[0].health; bool enoughDamageDone = (damageTaken > 0) ? (damageDone > 10 || damageDone / damageTaken > 2f) : true; bool notTooMuchDamageTaken = damageTaken < 70; if (enoughDamageDone && notTooMuchDamageTaken) { float attackValue = damageDone * target.cost * target.powerConstant - damageTaken * unit.cost * unit.powerConstant; if ((attackValue > bestAttackValue) || (attackValue == bestAttackValue && UnityEngine.Random.Range(0f, 1f) > .5f)) { bestAttackValue = attackValue; chosenTarget = target; attackPosition = position; } } unit.ChangeHealth(damageTaken); target.ChangeHealth(damageDone); } } } GridManager.MoveUnit(position, startingPosition, () => {}); } return(chosenTarget); }
public IEnumerator CheckMoves() { InfluenceTwo.SetUpMaps(); //Debug.Log("enemyOneTurnInfluenceMap:"); //InfluenceTwo.LogMap(InfluenceTwo.enemyOneTurnInfluenceMap); for (int i = 0; i < units.Count; i++) { Unit unit = units[i]; if (unit.Equals(null)) { break; } Vector2 moveGoal = ChooseMoveGoal(unit); Pather.GetCoordsToMoveHighlight(unit); int[,,] distanceMap = Pather.GetDistanceMap(unit, moveGoal); int[] bestDistance = new int[2] { 1000, 1000 }; List <Vector2> candidateMoves = new List <Vector2>(); UnitPather pather = new UnitPather(unit); foreach (Vector2 movePosition in pather.BehaviorMovePositions(attacking: false)) { if (movePosition != GridManager.GetCastleLocationForOwner(BattleManager.GetNextPlayerIndex()) || unit.behaviour == Behaviour.capture) { // if (InfluenceTwo.oneTurnInfluenceMap[(int)movePosition.x,(int)movePosition.y] <= safeInfluence) // { if (distanceMap[(int)movePosition.x, (int)movePosition.y, 0] < bestDistance[0]) { bestDistance[0] = distanceMap[(int)movePosition.x, (int)movePosition.y, 0]; bestDistance[1] = distanceMap[(int)movePosition.x, (int)movePosition.y, 1]; candidateMoves.Clear(); candidateMoves.Add(movePosition); } else if (distanceMap[(int)movePosition.x, (int)movePosition.y, 0] == bestDistance[0]) { if (distanceMap[(int)movePosition.x, (int)movePosition.y, 1] < bestDistance[1]) { bestDistance[0] = distanceMap[(int)movePosition.x, (int)movePosition.y, 0]; bestDistance[1] = distanceMap[(int)movePosition.x, (int)movePosition.y, 1]; candidateMoves.Clear(); candidateMoves.Add(movePosition); } else if (distanceMap[(int)movePosition.x, (int)movePosition.y, 1] == bestDistance[1]) { candidateMoves.Add(movePosition); } } // } } } if (candidateMoves.Count == 0) { candidateMoves.Add(unit.xy); } int r = UnityEngine.Random.Range(0, candidateMoves.Count); Vector2 finalMove = candidateMoves[r]; // Debug.LogFormat("{0} {1} moving from ({2},{3}) to ({4},{5}) en route to ({6},{7})", unit.type.ToString(), unit.owner.ToString(), // unit.x.ToString(), unit.y.ToString(), // finalMove.x.ToString(), finalMove.y.ToString(), moveGoal.x.ToString(), moveGoal.y.ToString()); // Pather.LogDistanceMap(distanceMap); moving = true; Pather.GetCoordsToMoveHighlight(unit); GridManager.MoveUnitAlongPath(unit, finalMove, Pather.GetPathToPoint(finalMove), () => { moving = false; }); while (moving) { yield return(new WaitForSeconds(.1f)); } if ((Vector2)unit.xy == moveGoal && GridManager.CanUnitCapture(unit)) { CaptureBuilding(unit); } unit.Deactivate(); } inSubCoroutine = false; }
public static float[,] GetUnitInfluence(Unit unit, ref float[,] oneTurnUnitInfluence) { float[,] unitInfluenceMap = new float[GridManager.Width(), GridManager.Height()]; int turnsAway = 1; // bool isArtillery = unit.grouping == UnitGroup.artillery; // if (isArtillery) // { // List<Vector2> attackPositions = GridManager.GetCoordsToAttackHighlight(unit.xy, unit.range); // foreach (Vector2 attackPosition in attackPositions) // { // float influence = (float)unit.GetPower() / (float)Math.Pow(2 , Math.Pow(turnsAway, 2)); // if (influence > unitInfluenceMap[(int)attackPosition.x,(int)attackPosition.y]) // { // unitInfluenceMap[(int)attackPosition.x,(int)attackPosition.y] = influence; // if (turnsAway == 1) // { // oneTurnUnitInfluence[(int)attackPosition.x,(int)attackPosition.y] = influence; // } // } // } // turnsAway++; // } List <Vector2> positionsToCheck = new List <Vector2>(); UnitPather pather = new UnitPather(unit); positionsToCheck = pather.BehaviorMovePositions(attacking: true); while (positionsToCheck.Count > 0) { List <Vector2> addList = new List <Vector2>(); foreach (Vector2 positionToCheck in positionsToCheck) { Pather.SetUpNodes(positionToCheck, unit.owner, unit.grouping, true); List <Vector2> movePositions = Pather.GetMoveCoordsForFloodFill(positionToCheck, unit.movePoints); foreach (Vector2 movePosition in movePositions) { List <Vector2> attackPositions = GridManager.GetCoordsToAttackHighlight(movePosition, unit.range); foreach (Vector2 attackPosition in attackPositions) { float influence = (float)unit.GetPower() / (float)Math.Pow(2, Math.Pow(turnsAway, 2)); if (influence > unitInfluenceMap[(int)attackPosition.x, (int)attackPosition.y]) { unitInfluenceMap[(int)attackPosition.x, (int)attackPosition.y] = influence; if (turnsAway == 1) { oneTurnUnitInfluence[(int)attackPosition.x, (int)attackPosition.y] = influence; } addList.Add(movePosition); } } } } positionsToCheck.Clear(); if (unit.behaviour != Behaviour.defend) { foreach (Vector2 addVector in addList) { positionsToCheck.Add(addVector); } } //Debug.LogFormat("There are {0} movePositions at {1} turnsAway", positionsToCheck.Count, turnsAway); turnsAway++; } return(unitInfluenceMap); }