public static void placePieces(Boolean is_loaded, String loaded_file) { if (!is_loaded) { Tuple<Int16,Int16> castleCoords = GameBoard.getPlayerCastle(); Int16 j = castleCoords.Item1; Int16 i = castleCoords.Item2; //Logger.log(@"Placing player pieces in random positions."); if (i - 1 >= 0) { if (GameBoard.overlay[i - 1, j] != '@') { Tuple<Int16, Int16> coords = Tuple.Create((short)(i-1),(short)j); PlayerCharacter character = new PlayerCharacter('1', coords.Item1, coords.Item2, 10, 1, 1); FlameBadge.player_units.Add(character); GameBoard.update(character, coords.Item1, coords.Item2); Logger.log(String.Format(@"Placed {0} at {1}, {2} with health {3}, level {4}, and dpsMod {5}", character.id.ToString(), coords.Item1, coords.Item2, 10, 1, 1)); } } if (i + 1 < GameBoard.overlay.GetLength(0)) { if (GameBoard.overlay[i + 1, j] != '@') { Tuple<Int16, Int16> coords = Tuple.Create((short)(i+1),(short)j); PlayerCharacter character = new PlayerCharacter('2', coords.Item1, coords.Item2, 10, 1, 1); FlameBadge.player_units.Add(character); GameBoard.update(character, coords.Item1, coords.Item2); Logger.log(String.Format(@"Placed {0} at {1}, {2} with health {3}, level {4}, and dpsMod {5}", character.id.ToString(), coords.Item1, coords.Item2, 10, 1, 1)); } } if (j - 1 >= 0) { if (GameBoard.overlay[i, j - 1] != '@') { Tuple<Int16, Int16> coords = Tuple.Create((short)(i),(short)(j-1)); PlayerCharacter character = new PlayerCharacter('3', coords.Item1, coords.Item2, 10, 1, 1); FlameBadge.player_units.Add(character); GameBoard.update(character, coords.Item1, coords.Item2); Logger.log(String.Format(@"Placed {0} at {1}, {2} with health {3}, level {4}, and dpsMod {5}", character.id.ToString(), coords.Item1, coords.Item2, 10, 1, 1)); } } if (j + 1 < GameBoard.overlay.GetLength(1)) { if (GameBoard.overlay[i, j + 1] != '@') { Tuple<Int16, Int16> coords = Tuple.Create((short)(i),(short)(j+1)); PlayerCharacter character = new PlayerCharacter('4', coords.Item1, coords.Item2, 10, 1, 1); FlameBadge.player_units.Add(character); GameBoard.update(character, coords.Item1, coords.Item2); Logger.log(String.Format(@"Placed {0} at {1}, {2} with health {3}, level {4}, and dpsMod {5}", character.id.ToString(), coords.Item1, coords.Item2, 10, 1, 1)); } } //diagonals if (i - 1 >= 0 && j + 1 < GameBoard.overlay.GetLength(1)) { if (GameBoard.overlay[i - 1, j + 1] != '@') { Tuple<Int16, Int16> coords = Tuple.Create((short)(i-1),(short)(j+1)); PlayerCharacter character = new PlayerCharacter('5', coords.Item1, coords.Item2, 10, 1, 1); FlameBadge.player_units.Add(character); GameBoard.update(character, coords.Item1, coords.Item2); Logger.log(String.Format(@"Placed {0} at {1}, {2} with health {3}, level {4}, and dpsMod {5}", character.id.ToString(), coords.Item1, coords.Item2, 10, 1, 1)); } } if (i + 1 < GameBoard.overlay.GetLength(0) && j - 1 >= 0) { if (GameBoard.overlay[i + 1, j - 1] != '@') { Tuple<Int16, Int16> coords = Tuple.Create((short)(i+1),(short)(j-1)); PlayerCharacter character = new PlayerCharacter('6', coords.Item1, coords.Item2, 10, 1, 1); FlameBadge.player_units.Add(character); GameBoard.update(character, coords.Item1, coords.Item2); Logger.log(String.Format(@"Placed {0} at {1}, {2} with health {3}, level {4}, and dpsMod {5}", character.id.ToString(), coords.Item1, coords.Item2, 10, 1, 1)); } } if (i - 1 >= 0 && j - 1 >= 0) { if (GameBoard.overlay[i - 1, j - 1] != '@') { Tuple<Int16, Int16> coords = Tuple.Create((short)(i-1),(short)(j-1)); PlayerCharacter character = new PlayerCharacter('7', coords.Item1, coords.Item2, 10, 1, 1); FlameBadge.player_units.Add(character); GameBoard.update(character, coords.Item1, coords.Item2); Logger.log(String.Format(@"Placed {0} at {1}, {2} with health {3}, level {4}, and dpsMod {5}", character.id.ToString(), coords.Item1, coords.Item2, 10, 1, 1)); } } if (i + 1 < GameBoard.overlay.GetLength(0) && j + 1 < GameBoard.overlay.GetLength(1)) { if (GameBoard.overlay[i + 1, j + 1] != '@') { Tuple<Int16, Int16> coords = Tuple.Create((short)(i + 1), (short)(j+1)); PlayerCharacter character = new PlayerCharacter('8', coords.Item1, coords.Item2, 10, 1, 1); FlameBadge.player_units.Add(character); GameBoard.update(character, coords.Item1, coords.Item2); Logger.log(String.Format(@"Placed {0} at {1}, {2} with health {3}, level {4}, and dpsMod {5}", character.id.ToString(), coords.Item1, coords.Item2, 10, 1, 1)); } } } else { Logger.log(@"Placing player pieces according to loaded save file."); try { using (StreamReader sr = new StreamReader(loaded_file)) { while (sr.Peek() > -1) { String line = sr.ReadLine(); if (line.StartsWith("Player")) { for (int i = 0; i < Convert.ToInt16(line.Split()[1]); i++) { String[] unit_info = sr.ReadLine().Split(); PlayerCharacter character = new PlayerCharacter(Convert.ToChar(unit_info[0]), Convert.ToInt16(unit_info[1]), Convert.ToInt16(unit_info[2]), Convert.ToInt32(unit_info[3]), Convert.ToInt32(unit_info[4]), Convert.ToInt32(unit_info[5])); FlameBadge.player_units.Add(character); GameBoard.update(character, Convert.ToInt16(unit_info[1]), Convert.ToInt16(unit_info[2])); Logger.log(String.Format(@"Placed {0} at {1}, {2} with health {3}, level {4}, and dpsMod {5}", character.id.ToString(), Convert.ToInt16(unit_info[1]), Convert.ToInt16(unit_info[2]), Convert.ToInt32(unit_info[3]), Convert.ToInt32(unit_info[4]), Convert.ToInt32(unit_info[5]))); } } } } } catch (Exception) { Logger.log("Could not load player pieces from save file. Quitting...", "error"); Environment.Exit(1); } } }
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; } }