예제 #1
0
        /// <summary>
        /// Returns the AIs choice of the next unit to move
        /// </summary>
        /// <returns>Reference to the next cpu unit which should move.</returns>
        public EnemyCharacter getNextUnitToMove()
        {
            if (cpuMoveOrder.Count == 0)
            {
                setupMoveOrder();
            }
            EnemyCharacter next = cpuMoveOrder[0];

            cpuMoveOrder.RemoveAt(0);
            return(next);
        }
예제 #2
0
        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);
        }
        public static void placePieces(Boolean is_loaded, String loaded_file)
        {
            if (!is_loaded)
            {
                //Logger.log(@"Placing enemy pieces in random positions.");
                Tuple<Int16, Int16> castleCoords = GameBoard.getCPUCastle();
                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);
                        EnemyCharacter character = new EnemyCharacter('A', coords.Item1, coords.Item2, 10, 1, 1);
                        FlameBadge.cpu_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);
                        EnemyCharacter character = new EnemyCharacter('B', coords.Item1, coords.Item2, 10, 1, 1);
                        FlameBadge.cpu_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));
                        EnemyCharacter character = new EnemyCharacter('C', coords.Item1, coords.Item2, 10, 1, 1);
                        FlameBadge.cpu_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));
                        EnemyCharacter character = new EnemyCharacter('D', coords.Item1, coords.Item2, 10, 1, 1);
                        FlameBadge.cpu_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));
                        EnemyCharacter character = new EnemyCharacter('E', coords.Item1, coords.Item2, 10, 1, 1);
                        FlameBadge.cpu_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));
                        EnemyCharacter character = new EnemyCharacter('F', coords.Item1, coords.Item2, 10, 1, 1);
                        FlameBadge.cpu_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));
                        EnemyCharacter character = new EnemyCharacter('G', coords.Item1, coords.Item2, 10, 1, 1);
                        FlameBadge.cpu_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));
                        EnemyCharacter character = new EnemyCharacter('H', coords.Item1, coords.Item2, 10, 1, 1);
                        FlameBadge.cpu_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 computer 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("Computer"))
                            {
                                for (int i = 0; i < Convert.ToInt16(line.Split()[1]); i++)
                                {
                                    String[] unit_info = sr.ReadLine().Split();
                                    EnemyCharacter character = new EnemyCharacter(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.cpu_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 computer pieces from save file. Quitting...", "error");
                    Environment.Exit(1);
                }
            }
        }
예제 #4
0
        public FlameBadge()
        {
            // Set up saves directory

            if (!Directory.Exists(save_dir))
            {
                Directory.CreateDirectory(save_dir);
            }

            // Check if any save files exist
            // If they don't we won't bother offering a load game option
            DirectoryInfo dir       = new DirectoryInfo(save_dir);
            Boolean       is_loaded = false;

            if (dir.GetFiles().Length != 0)
            {
                is_loaded = _offerContinue();
            }

            String loaded_file = "";

            if (is_loaded)
            {
                loaded_file = _getSavedGame(dir);
            }

            if (loaded_file == "")
            {
                is_loaded = false;
            }
            else
            {
                loaded_file = save_dir + loaded_file;
            }

            // if we loaded we need to know whose turn it was
            Char curr_turn = '0';

            if (is_loaded)
            {
                curr_turn = _getTurn(loaded_file);
            }

            // Draw the game board.
            GameBoard game_board = new GameBoard(is_loaded ? loaded_file : null);

            // Put the pieces on the board.
            PlayerCharacter.placePieces(is_loaded, loaded_file);
            EnemyCharacter.placePieces(is_loaded, loaded_file);

            // mainloop
            while (true)
            {
                for (int i = 0; i < player_units.Count; i++)
                {
                    // if we loaded a game, skip over everyone until the rightful
                    // unit goes
                    if (curr_turn != '0')
                    {
                        if (player_units[i].id != curr_turn)
                        {
                            continue;
                        }
                        else
                        {
                            curr_turn = '0';
                        }
                    }
                    player_units[i].takeTurn();
                    List <Character> victims = GameBoard.getAttackableUnits(player_units[i].xPos, player_units[i].yPos, cpu_units.Cast <Character>().ToList());
                    if (victims.Count > 0)
                    {
                        //pass in true to signify player
                        GameBoard.attack(player_units[i].id, victims[0].id, true);
                        GameBoard.redraw();
                        if (cpu_units.Count == 0)
                        {
                            FlameBadge.hasEnded = true;
                        }
                    }
                    Tuple <Int16, Int16> enemyCastle = GameBoard.getCPUCastle();
                    if ((int)enemyCastle.Item2 == (int)player_units[i].xPos && (int)enemyCastle.Item1 == (int)player_units[i].yPos)
                    {
                        FlameBadge.hasEnded = true;
                    }
                    if (FlameBadge.hasEnded)
                    {
                        _endGame();
                    }
                }

                for (int i = 0; i < cpu_units.Count; i++)
                {
                    cpu_units[i].takeTurn();
                    List <Character> victims = GameBoard.getAttackableUnits(cpu_units[i].xPos, cpu_units[i].yPos, player_units.Cast <Character>().ToList());
                    if (victims.Count > 0)
                    {
                        //pass in false to signify AI
                        GameBoard.attack(cpu_units[i].id, victims[0].id, false);
                        GameBoard.redraw();
                        if (player_units.Count == 0)
                        {
                            FlameBadge.hasEnded = true;
                        }
                    }
                    Tuple <Int16, Int16> enemyCastle = GameBoard.getPlayerCastle();
                    if ((int)enemyCastle.Item2 == (int)cpu_units[i].xPos && (int)enemyCastle.Item1 == (int)cpu_units[i].yPos)
                    {
                        FlameBadge.hasEnded   = true;
                        FlameBadge.cpuCapture = true;
                    }
                    if (FlameBadge.hasEnded)
                    {
                        _endGame();
                    }
                }
            }
        }
예제 #5
0
        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);
            }
        }
예제 #6
0
 /// <summary>
 /// Gets the determined best x,y coordinates for the given unit's next move
 /// </summary>
 /// <param name="unit">Unit for which to calculate the best move</param>
 /// <returns>Tuple x,y coordinates</returns>
 public Tuple <int, int> getNextMove(EnemyCharacter unit)
 {
     return(calculateNextMove(unit, level + 1));
 }
예제 #7
0
 /// <summary>
 /// Gets the determined best x,y coordinates for the given unit's next move
 /// </summary>
 /// <param name="unit">Unit for which to calculate the best move</param>
 /// <returns>Tuple x,y coordinates</returns>
 public Tuple<int, int> getNextMove(EnemyCharacter unit)
 {
     return calculateNextMove(unit, level + 1);
 }
예제 #8
0
        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;
            }
        }
예제 #9
0
        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;
        }
예제 #10
0
 /// <summary>
 /// Gets the unit which should be attacked by the given unit
 /// </summary>
 /// <param name="unit">Computer controlled unit for which to decide who to attack</param>
 /// <returns>Player unit to be attacked</returns>
 public PlayerCharacter getUnitToAttack(EnemyCharacter unit)
 {
     List<Character> enemies = GameBoard.getAttackableUnits(unit.xPos, unit.yPos, playerUnits.Cast<Character>().ToList());
     // TODO: Implement some kind of decision strategy
     // for now, just pick an attackable unit at random
     Random r = new Random();
     return (PlayerCharacter) enemies[r.Next(0, enemies.Count - 1)];
 }
        public static void placePieces(Boolean is_loaded, String loaded_file)
        {
            if (!is_loaded)
            {
                //Logger.log(@"Placing enemy pieces in random positions.");
                Tuple <Int16, Int16> castleCoords = GameBoard.getCPUCastle();
                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);
                        EnemyCharacter       character = new EnemyCharacter('A', coords.Item1, coords.Item2, 10, 1, 1);
                        FlameBadge.cpu_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);
                        EnemyCharacter       character = new EnemyCharacter('B', coords.Item1, coords.Item2, 10, 1, 1);
                        FlameBadge.cpu_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));
                        EnemyCharacter       character = new EnemyCharacter('C', coords.Item1, coords.Item2, 10, 1, 1);
                        FlameBadge.cpu_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));
                        EnemyCharacter       character = new EnemyCharacter('D', coords.Item1, coords.Item2, 10, 1, 1);
                        FlameBadge.cpu_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));
                        EnemyCharacter       character = new EnemyCharacter('E', coords.Item1, coords.Item2, 10, 1, 1);
                        FlameBadge.cpu_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));
                        EnemyCharacter       character = new EnemyCharacter('F', coords.Item1, coords.Item2, 10, 1, 1);
                        FlameBadge.cpu_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));
                        EnemyCharacter       character = new EnemyCharacter('G', coords.Item1, coords.Item2, 10, 1, 1);
                        FlameBadge.cpu_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));
                        EnemyCharacter       character = new EnemyCharacter('H', coords.Item1, coords.Item2, 10, 1, 1);
                        FlameBadge.cpu_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 computer 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("Computer"))
                            {
                                for (int i = 0; i < Convert.ToInt16(line.Split()[1]); i++)
                                {
                                    String[]       unit_info = sr.ReadLine().Split();
                                    EnemyCharacter character = new EnemyCharacter(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.cpu_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 computer pieces from save file. Quitting...", "error");
                    Environment.Exit(1);
                }
            }
        }