Пример #1
0
        /// <summary>
        /// Make all possible moves and chooses the once which guarantees the max profit
        /// </summary>
        private Tuple <double, MoveInformation> MakeAnalyzingMoves(MoveInformation moveInformation, int depth,
                                                                   PlayerType playerType, List <Cell> currentPlayerArmyCells,
                                                                   List <Cell> otherPlayerArmyCells)
        {
            var memorizedFrom = new ItemAndPosition(GetItemByPosition(moveInformation.From), moveInformation.From); // memorizing position
            var memorizedTo   = new ItemAndPosition(GetItemByPosition(moveInformation.To), moveInformation.To);

            MakeMove(moveInformation.From, moveInformation.To);
            ChangeArmyListAfterMoving(currentPlayerArmyCells, playerType, moveInformation); // changing list of armies after move
            ChangeArmyListAfterMoving(otherPlayerArmyCells, GetOppositePlayerType(playerType), moveInformation);

            Tuple <double, MoveInformation> result;

            if (PlayerArmiesWereKilled(currentPlayerArmyCells) || PlayerArmiesWereKilled(otherPlayerArmyCells)) // If game ends because of armies of one player were killed
            {
                result = OnOnceArmiesKilled(currentPlayerArmyCells, otherPlayerArmyCells, playerType);
            }
            else
            {
                result = AnalyzeStrategy(GetOppositePlayerType(playerType), false, // Just analyzing the move profit
                                         depth - 1, otherPlayerArmyCells,
                                         currentPlayerArmyCells);
            }

            CancelMove(memorizedFrom, memorizedTo);
            ChangeArmyListAfterCancellingMove(currentPlayerArmyCells, otherPlayerArmyCells, // Changing list of armies after cancelling move
                                              playerType, moveInformation, memorizedFrom, memorizedTo);

            return(result);
        }
Пример #2
0
        /// <summary>
        /// Among possible moves method chooses the one, which guarantees max position profit
        /// </summary>
        private Tuple <double, MoveInformation> AnalyzeMoves(PlayerType playerType, List <MoveInformation> possibleMoves,
                                                             int depth, List <Cell> currentPlayerArmyCells, List <Cell> otherPlayerArmyCells)
        {
            var             resultBenefit       = InfinityByPlayerType(playerType); // The best guaranteed profit
            MoveInformation bestMoveInformation = null;                             // The best move, null means that it is better not to move

            foreach (var moveInformation in possibleMoves)
            {
                // Analyzing single move
                var intermediateResult      = MakeAnalyzingMoves(moveInformation, depth, playerType, currentPlayerArmyCells, otherPlayerArmyCells);
                var distanceEnemyCastleTo   = boardStorage.GetDistanceToEnemyCastle(moveInformation.To, playerType);
                var distanceEnemyCastleFrom = boardStorage.GetDistanceToEnemyCastle(moveInformation.From, playerType);

                if (distanceEnemyCastleTo == 0) // If castle was reached
                {
                    resultBenefit       = playerType == personPlayerType ? double.PositiveInfinity : double.NegativeInfinity;
                    bestMoveInformation = moveInformation;
                    break;
                }

                // Comparing best and current moves
                if (IsMoveBetter(resultBenefit, intermediateResult.Item1, bestMoveInformation, playerType, distanceEnemyCastleTo))
                {
                    resultBenefit       = intermediateResult.Item1;
                    bestMoveInformation = moveInformation;

                    if (IsMovePerfect(resultBenefit, playerType, distanceEnemyCastleTo, distanceEnemyCastleFrom))
                    {
                        break;
                    }
                }
            }

            return(new Tuple <double, MoveInformation>(resultBenefit, bestMoveInformation));
        }
Пример #3
0
        /// <summary>
        /// Checks that analyzing move is better than current the best
        /// </summary>
        private Boolean IsMoveBetter(double currentBenefit, double moveBenefit, MoveInformation currentMove,
                                     PlayerType playerType, double distanceEnemyCastleTo)
        {
            if (playerType == aiPlayerType)
            {
                return(moveBenefit < currentBenefit ||
                       Math.Abs(moveBenefit - currentBenefit) < EPSILON &&
                       (currentMove == null ||
                        boardStorage.GetDistanceToEnemyCastle(currentMove.To, playerType) > distanceEnemyCastleTo));
            }

            return(moveBenefit > currentBenefit ||
                   Math.Abs(moveBenefit - currentBenefit) < EPSILON &&
                   (currentMove == null ||
                    boardStorage.GetDistanceToEnemyCastle(currentMove.To, playerType) > distanceEnemyCastleTo));
        }
Пример #4
0
        /// <summary>
        /// After army was moved its position was changed and maybe position of some other armies was changed too
        /// (if it was located on target cell), so list of armies should be updated
        /// </summary>
        private void ChangeArmyListAfterMoving(List <Cell> armyCells, PlayerType playerType, MoveInformation move)
        {
            armyCells.Remove(move.From);
            armyCells.Remove(move.To);

            var resultItem = boardStorage.GetItem(move.To) as ArmyStorageItem;

            if (resultItem?.Army != null && resultItem.Army is UserArmy userArmy)
            {
                if (playerType == userArmy.PlayerType)
                {
                    armyCells.Add(move.To);
                }
            }
        }
Пример #5
0
        /// <summary>
        /// After cancelling move in game simulation all armies should return to their cells and list of
        /// armies should be updated
        /// </summary>
        private void ChangeArmyListAfterCancellingMove(List <Cell> currentPlayerArmyCells,
                                                       List <Cell> otherPlayerArmyCells, PlayerType playerType, MoveInformation move,
                                                       ItemAndPosition memorizedFrom, ItemAndPosition memorizedTo)
        {
            currentPlayerArmyCells.Remove(move.To);
            otherPlayerArmyCells.Remove(move.To);

            if (memorizedFrom.Item?.Army != null)
            {
                AddCellToArmyCellsList(currentPlayerArmyCells, otherPlayerArmyCells, playerType,
                                       memorizedFrom.Item.Army.PlayerType, move.From);
            }

            if (memorizedTo.Item?.Army != null)
            {
                AddCellToArmyCellsList(currentPlayerArmyCells, otherPlayerArmyCells, playerType,
                                       memorizedTo.Item.Army.PlayerType, move.To);
            }
        }