public List <Ship> EnemiesOnField(int defenderUserId, Tuple <byte, byte> SysCoords)
        {
            var DefendingShips = this.ships.Where(ship => (ship.userid != defenderUserId &&
                                                           ((SysCoords != null && ship.systemX == SysCoords.Item1 && ship.systemY == SysCoords.Item2) ||
                                                            (SysCoords == null)) &&
                                                           UserRelations.IsLower(Core.Instance.userRelations.getRelation(defenderUserId, ship.userid), Relation.Neutral)));

            return(DefendingShips.ToList());
        }
        public Ship detectAttackingShip(User Attacker, Tuple <byte, byte> SysCoords)
        {
            //var DefendingShips;
            //if (systemXY != null)
            //{
            //   DefendingShips

            CombatField CombatField = new SpacegameServer.Core.CombatField(this, SysCoords);

            var DefendingShips = this.ships.Where(ship => (ship.userid != Attacker.id &&
                                                           ((SysCoords != null && ship.systemX == SysCoords.Item1 && ship.systemY == SysCoords.Item2) ||
                                                            (SysCoords == null)) &&
                                                           UserRelations.IsLower(Core.Instance.userRelations.getRelation(Attacker.id, ship.userid), Relation.Neutral)));

            var AttackingShips = this.ships.Where(ship => ship.userid == Attacker.id &&
                                                  ((SysCoords != null && ship.systemX == SysCoords.Item1 && ship.systemY == SysCoords.Item2) ||
                                                   (SysCoords == null)));

            double BestRatio         = -1.0;
            Ship   BestAttackerSoFar = null;

            foreach (var PossibleAttacker in AttackingShips)
            {
                if (BestAttackerSoFar == null)
                {
                    BestAttackerSoFar = PossibleAttacker;
                }

                double bestDefender = Double.MaxValue;
                foreach (var Defender in DefendingShips)
                {
                    var ratio = Defender.AttackerDefenderRatio(PossibleAttacker, CombatField);
                    if (ratio < bestDefender)
                    {
                        bestDefender = ratio;
                    }
                }

                if (bestDefender > BestRatio)
                {
                    BestRatio         = bestDefender;
                    BestAttackerSoFar = PossibleAttacker;
                }
            }

            //}

            return(BestAttackerSoFar);
        }
        public Ship StrongestEnemyOnField(Ship attackingShip, Tuple <byte, byte> SysCoords, int attackedShipId = 0)
        {
            CombatField CombatField = new SpacegameServer.Core.CombatField(this, SysCoords);

            var DefendingShips = this.ships.Where(ship => (ship.userid != attackingShip.userid &&
                                                           ((SysCoords != null && ship.systemX == SysCoords.Item1 && ship.systemY == SysCoords.Item2) ||
                                                            (SysCoords == null)) &&
                                                           UserRelations.IsLower(Core.Instance.userRelations.getRelation(attackingShip.userid, ship.userid), Relation.Neutral)));

            if (DefendingShips.Count() == 0 && attackedShipId != 0 && this.ships.Any(e => e.id == attackedShipId))
            {
                // the ship to attack is on the field. Add it to the DefendingShips, then add all other ships of this user or his alliance members, and all other ships from pact-members, as long as the pact is not also with the attacker
                var ShipToAttack    = this.ships.First(e => e.id == attackedShipId);
                var UserToAttack    = Core.Instance.users[ShipToAttack.userid];
                var UserThatAttacks = Core.Instance.users[attackingShip.userid];

                //Prepare Lists to get all other users that might defend the attcked ships
                var AttackerPacts = Core.Instance.userRelations.getAllContacts(UserThatAttacks, Relation.Pact);
                List <DiplomaticEntity> ExclusivePacts = new List <DiplomaticEntity>();
                List <User>             AllEnemyUsers  = new List <User>();

                if (UserToAttack.allianceId != 0 && UserThatAttacks.allianceId != UserToAttack.allianceId)
                {
                    AllEnemyUsers.AddRange(Core.Instance.alliances[UserToAttack.allianceId].getUsers());
                }
                else
                {
                    AllEnemyUsers.Add(UserToAttack);
                }

                //add pact-users that are not in a pact with the attacker
                foreach (var entry in Core.Instance.userRelations.getAllContacts(UserToAttack, Relation.Pact))
                {
                    if (AttackerPacts.Any(e => e.target == entry.target))
                    {
                        continue;
                    }

                    AllEnemyUsers.AddRange(entry.target.getUsers());
                }

                DefendingShips = this.ships.Where(
                    ship => AllEnemyUsers.Any(enemy => enemy.id == ship.userid) &&
                    ((SysCoords != null && ship.systemX == SysCoords.Item1 && ship.systemY == SysCoords.Item2) ||
                     (SysCoords == null))
                    );
            }

            //defensive pacts could provide additional defense unit at this point

            double BestRatio         = Double.MaxValue;
            Ship   BestDefenderSoFar = null;

            foreach (var Defender in DefendingShips)
            {
                if (BestDefenderSoFar == null)
                {
                    BestDefenderSoFar = Defender;
                }

                var ratio = Defender.AttackerDefenderRatio(attackingShip, CombatField);
                if (ratio < BestRatio)
                {
                    BestRatio         = ratio;
                    BestDefenderSoFar = Defender;
                }
            }

            return(BestDefenderSoFar);
        }