private Tuple <int, int> calculateNextMove(EnemyCharacter c, int numLevels) { List <Tuple <int, int> > moves = c.getPossibleMoves(); int bestMoveHeuristic = -999999; Tuple <int, int> bestMove = null; List <Character> enemyUnits = playerUnits.Cast <Character>().ToList(); List <Character> units = cpuUnits.Cast <Character>().ToList(); Logger.log(String.Format(@"AI is calculating moves for EnemyCharacter {0} with depth of {1}.", c.id, numLevels), "debug"); foreach (Tuple <int, int> move in moves) { int heuristic = 0; Character potentialUnit = null; // create a new character so that we don't override the original potentialUnit = new EnemyCharacter(c.id, (short)move.Item1, (short)move.Item2, c.health, c.level, c.dpsMod); heuristic += canAttackBaseAttacker(potentialUnit, enemyUnits, cpuBasePos); heuristic += canDamageOpponentBase(potentialUnit, playerBasePos); heuristic += isGuardingBase(potentialUnit, cpuBasePos); heuristic += isTravellingToBase(potentialUnit, c.xPos, c.yPos, playerBasePos, true); heuristic += isTravellingToBase(potentialUnit, c.xPos, c.yPos, cpuBasePos, false); heuristic += isFleeingFromOverwhelmingForce(potentialUnit, enemyUnits, units, c.xPos, c.yPos); heuristic += canAttackOpponent(potentialUnit, enemyUnits); heuristic += isMovingToInterceptOpponent(potentialUnit, enemyUnits, c.xPos, c.yPos); int negHeuristic = calculateNextMoveHeuristic(c, enemyUnits, units, numLevels - 1, false); // subtract the heuristic points gained by the enemy heuristic -= negHeuristic; // get the best move for that unit if (heuristic > bestMoveHeuristic) { bestMoveHeuristic = heuristic; bestMove = move; } else if (heuristic == bestMoveHeuristic) { // if the values are equal, flip a coin to see which to choose Random r = new Random(); if (r.Next(0, 2) == 0) { bestMove = move; } } } Logger.log(String.Format(@"AI has completed calculating moves for EnemyCharacter {0}.", c.id), "debug"); return(bestMove); }
private int calculateNextMoveHeuristic(EnemyCharacter c, List <Character> units, List <Character> enemyUnits, int numLevels, Boolean cpuTurn) { if (numLevels == 0) { return(0); } List <Character> futureUnits = new List <Character>(); int averageHeuristic = 0; // move each of the units tentatively foreach (Character unit in units) { if (unit == c) { continue; } // get all possible moves for the cpu unit List <Tuple <int, int> > moves = unit.getPossibleMoves(); int bestMoveHeuristic = -999999; Character best = null; foreach (Tuple <int, int> move in moves) { int heuristic = 0; Character potentialUnit = null; if (cpuTurn) { // create a new character so that we don't override the original potentialUnit = new EnemyCharacter(unit.id, (short)move.Item1, (short)move.Item2, unit.health, unit.level, unit.dpsMod); heuristic += canAttackBaseAttacker(potentialUnit, enemyUnits, cpuBasePos); heuristic += canDamageOpponentBase(potentialUnit, playerBasePos); heuristic += isGuardingBase(potentialUnit, cpuBasePos); heuristic += isTravellingToBase(potentialUnit, unit.xPos, unit.yPos, playerBasePos, true); heuristic += isTravellingToBase(potentialUnit, unit.xPos, unit.yPos, cpuBasePos, false); } else { // create a new character so that we don't override the original potentialUnit = new PlayerCharacter(unit.id, (short)move.Item1, (short)move.Item2, unit.health, unit.level, unit.dpsMod); heuristic += canAttackBaseAttacker(potentialUnit, enemyUnits, playerBasePos); heuristic += canDamageOpponentBase(potentialUnit, cpuBasePos); heuristic += isGuardingBase(potentialUnit, playerBasePos); heuristic += isTravellingToBase(potentialUnit, unit.xPos, unit.yPos, cpuBasePos, true); heuristic += isTravellingToBase(potentialUnit, unit.xPos, unit.yPos, playerBasePos, false); } heuristic += isFleeingFromOverwhelmingForce(potentialUnit, enemyUnits, units, unit.xPos, unit.yPos); heuristic += canAttackOpponent(potentialUnit, enemyUnits); heuristic += isMovingToInterceptOpponent(potentialUnit, enemyUnits, unit.xPos, unit.yPos); // get the best move for that unit if (heuristic > bestMoveHeuristic) { bestMoveHeuristic = heuristic; best = potentialUnit; } else if (heuristic == bestMoveHeuristic) { // if the values are equal, flip a coin to see which to choose Random r = new Random(); if (r.Next(0, 2) == 0) { best = potentialUnit; } } } averageHeuristic += bestMoveHeuristic; futureUnits.Add(best); } averageHeuristic = averageHeuristic / units.Count(); if (cpuTurn) { List <Tuple <int, int> > moves = c.getPossibleMoves(); int bestMoveHeuristic = -999999; foreach (Tuple <int, int> move in moves) { int heuristic = 0; Character potentialUnit = null; // create a new character so that we don't override the original potentialUnit = new EnemyCharacter(c.id, (short)move.Item1, (short)move.Item2, c.health, c.level, c.dpsMod); heuristic += canAttackBaseAttacker(potentialUnit, enemyUnits, cpuBasePos); heuristic += canDamageOpponentBase(potentialUnit, playerBasePos); heuristic += isGuardingBase(potentialUnit, cpuBasePos); heuristic += isTravellingToBase(potentialUnit, c.xPos, c.yPos, playerBasePos, true); heuristic += isTravellingToBase(potentialUnit, c.xPos, c.yPos, cpuBasePos, false); heuristic += isFleeingFromOverwhelmingForce(potentialUnit, enemyUnits, units, c.xPos, c.yPos); heuristic += canAttackOpponent(potentialUnit, enemyUnits); heuristic += isMovingToInterceptOpponent(potentialUnit, enemyUnits, c.xPos, c.yPos); int negHeuristic = calculateNextMoveHeuristic(c, enemyUnits, futureUnits, numLevels - 1, !cpuTurn); // subtract the heuristic points gained by the enemy heuristic -= negHeuristic; // get the best move for that unit if (heuristic > bestMoveHeuristic) { bestMoveHeuristic = heuristic; } } return(bestMoveHeuristic); } else { // if this was the tentative player turn, go down the next level and return the heuristic int negHeuristic = calculateNextMoveHeuristic(c, enemyUnits, futureUnits, numLevels - 1, !cpuTurn); averageHeuristic -= negHeuristic; return(averageHeuristic); } }
private int calculateNextMoveHeuristic(EnemyCharacter c, List<Character> units, List<Character> enemyUnits, int numLevels, Boolean cpuTurn) { if (numLevels == 0) return 0; List<Character> futureUnits = new List<Character>(); int averageHeuristic = 0; // move each of the units tentatively foreach (Character unit in units) { if (unit == c) continue; // get all possible moves for the cpu unit List<Tuple<int, int>> moves = unit.getPossibleMoves(); int bestMoveHeuristic = -999999; Character best = null; foreach (Tuple<int, int> move in moves) { int heuristic = 0; Character potentialUnit = null; if (cpuTurn) { // create a new character so that we don't override the original potentialUnit = new EnemyCharacter(unit.id, (short)move.Item1, (short)move.Item2, unit.health, unit.level, unit.dpsMod); heuristic += canAttackBaseAttacker(potentialUnit, enemyUnits, cpuBasePos); heuristic += canDamageOpponentBase(potentialUnit, playerBasePos); heuristic += isGuardingBase(potentialUnit, cpuBasePos); heuristic += isTravellingToBase(potentialUnit, unit.xPos, unit.yPos, playerBasePos, true); heuristic += isTravellingToBase(potentialUnit, unit.xPos, unit.yPos, cpuBasePos, false); } else { // create a new character so that we don't override the original potentialUnit = new PlayerCharacter(unit.id, (short)move.Item1, (short)move.Item2, unit.health, unit.level, unit.dpsMod); heuristic += canAttackBaseAttacker(potentialUnit, enemyUnits, playerBasePos); heuristic += canDamageOpponentBase(potentialUnit, cpuBasePos); heuristic += isGuardingBase(potentialUnit, playerBasePos); heuristic += isTravellingToBase(potentialUnit, unit.xPos, unit.yPos, cpuBasePos, true); heuristic += isTravellingToBase(potentialUnit, unit.xPos, unit.yPos, playerBasePos, false); } heuristic += isFleeingFromOverwhelmingForce(potentialUnit, enemyUnits, units, unit.xPos, unit.yPos); heuristic += canAttackOpponent(potentialUnit, enemyUnits); heuristic += isMovingToInterceptOpponent(potentialUnit, enemyUnits, unit.xPos, unit.yPos); // get the best move for that unit if (heuristic > bestMoveHeuristic) { bestMoveHeuristic = heuristic; best = potentialUnit; } else if (heuristic == bestMoveHeuristic) { // if the values are equal, flip a coin to see which to choose Random r = new Random(); if (r.Next(0, 2) == 0) best = potentialUnit; } } averageHeuristic += bestMoveHeuristic; futureUnits.Add(best); } averageHeuristic = averageHeuristic / units.Count(); if (cpuTurn) { List<Tuple<int, int>> moves = c.getPossibleMoves(); int bestMoveHeuristic = -999999; foreach (Tuple<int, int> move in moves) { int heuristic = 0; Character potentialUnit = null; // create a new character so that we don't override the original potentialUnit = new EnemyCharacter(c.id, (short)move.Item1, (short)move.Item2, c.health, c.level, c.dpsMod); heuristic += canAttackBaseAttacker(potentialUnit, enemyUnits, cpuBasePos); heuristic += canDamageOpponentBase(potentialUnit, playerBasePos); heuristic += isGuardingBase(potentialUnit, cpuBasePos); heuristic += isTravellingToBase(potentialUnit, c.xPos, c.yPos, playerBasePos, true); heuristic += isTravellingToBase(potentialUnit, c.xPos, c.yPos, cpuBasePos, false); heuristic += isFleeingFromOverwhelmingForce(potentialUnit, enemyUnits, units, c.xPos, c.yPos); heuristic += canAttackOpponent(potentialUnit, enemyUnits); heuristic += isMovingToInterceptOpponent(potentialUnit, enemyUnits, c.xPos, c.yPos); int negHeuristic = calculateNextMoveHeuristic(c, enemyUnits, futureUnits, numLevels - 1, !cpuTurn); // subtract the heuristic points gained by the enemy heuristic -= negHeuristic; // get the best move for that unit if (heuristic > bestMoveHeuristic) { bestMoveHeuristic = heuristic; } } return bestMoveHeuristic; } else { // if this was the tentative player turn, go down the next level and return the heuristic int negHeuristic = calculateNextMoveHeuristic(c, enemyUnits, futureUnits, numLevels - 1, !cpuTurn); averageHeuristic -= negHeuristic; return averageHeuristic; } }
private Tuple<int, int> calculateNextMove(EnemyCharacter c, int numLevels) { List<Tuple<int, int>> moves = c.getPossibleMoves(); int bestMoveHeuristic = -999999; Tuple<int, int> bestMove = null; List<Character> enemyUnits = playerUnits.Cast<Character>().ToList(); List<Character> units = cpuUnits.Cast<Character>().ToList(); Logger.log(String.Format(@"AI is calculating moves for EnemyCharacter {0} with depth of {1}.",c.id, numLevels), "debug"); foreach (Tuple<int, int> move in moves) { int heuristic = 0; Character potentialUnit = null; // create a new character so that we don't override the original potentialUnit = new EnemyCharacter(c.id, (short)move.Item1, (short)move.Item2, c.health, c.level, c.dpsMod); heuristic += canAttackBaseAttacker(potentialUnit, enemyUnits, cpuBasePos); heuristic += canDamageOpponentBase(potentialUnit, playerBasePos); heuristic += isGuardingBase(potentialUnit, cpuBasePos); heuristic += isTravellingToBase(potentialUnit, c.xPos, c.yPos, playerBasePos, true); heuristic += isTravellingToBase(potentialUnit, c.xPos, c.yPos, cpuBasePos, false); heuristic += isFleeingFromOverwhelmingForce(potentialUnit, enemyUnits, units, c.xPos, c.yPos); heuristic += canAttackOpponent(potentialUnit, enemyUnits); heuristic += isMovingToInterceptOpponent(potentialUnit, enemyUnits, c.xPos, c.yPos); int negHeuristic = calculateNextMoveHeuristic(c, enemyUnits, units, numLevels - 1, false); // subtract the heuristic points gained by the enemy heuristic -= negHeuristic; // get the best move for that unit if (heuristic > bestMoveHeuristic) { bestMoveHeuristic = heuristic; bestMove = move; } else if (heuristic == bestMoveHeuristic) { // if the values are equal, flip a coin to see which to choose Random r = new Random(); if (r.Next(0, 2) == 0) bestMove = move; } } Logger.log(String.Format(@"AI has completed calculating moves for EnemyCharacter {0}.", c.id), "debug"); return bestMove; }