public void GiveBoatSemiEfficientParking(List <Boat> boats, Port port, List <int[]> freeSpots)
        {
            //List<int[]> freeSpots = FreePortSpots2(port);
            List <Boat> boatsToCheck = boats.Where(notAssigned)
                                       .OrderBy(boatSize)
                                       .ToList();

            foreach (Boat boat in boatsToCheck)
            {
                //t.ex plats 1 till 3 för en katamaran 3-1 = 2 katamaranens storlek = 3 därför -1
                int[] givenPortSpot = freeSpots.Where(spot => spot[1] - spot[0] == boat.Size - 1).FirstOrDefault();
                if (givenPortSpot == null)//finns det ingen plats som matchar exakt ska nästa kollas
                {
                    continue;
                }
                else
                {
                    //motorbåten ska endast ha 1 plats listad
                    boat.AssignedSpot = boat is Motorboat ? new int[1] {
                        givenPortSpot[0]
                    } : givenPortSpot;
                    port.AddBoat(boat);
                    freeSpots.Remove(givenPortSpot); //tar bort platsen ur listan
                    continue;
                }
            }
            boatsToCheck = boats.Where(notAssigned).ToList();
            if (freeSpots.Any() && boatsToCheck.Any())
            {
                TryPortSpots(boatsToCheck, port, freeSpots);
            }
        }
        public void PlaceRowboatNextToAnother(List <Boat> boats, Port port)
        {
            List <Rowboat> rowboatsToCheck         = boats.Where(notAssigned).OfType <Rowboat>().ToList();
            List <Rowboat> dockedRowboatsWithSpace =
                port.Boats.Where(boatIsRowboat)
                .OfType <Rowboat>()
                .GroupBy(boat => boat.AssignedSpot[0])
                .Where(group => group.Count() < 2)               //där det är mindre än 2 på samma plats kan nästa få hamna
                .Select(boatGroup => boatGroup.FirstOrDefault()) //väljer den första i varje grupp
                .ToList();


            //så länge det finns roddbåtar att placera ut och roddbåtar som har plats för en till
            while (dockedRowboatsWithSpace.Any() && rowboatsToCheck.Any())
            {
                foreach (Rowboat rowboat in rowboatsToCheck)
                {
                    Rowboat otherRowboat = dockedRowboatsWithSpace.FirstOrDefault();
                    if (otherRowboat == null) //finns det ingen roddbåt i listan ska loopen avslutas
                    {
                        break;
                    }
                    int[] otherRowboatsSpot = otherRowboat.AssignedSpot; //ger den nya roddbåten samma position som den som redan är ute i kajen
                    rowboat.AssignedSpot = otherRowboatsSpot;
                    port.AddBoat(rowboat);

                    dockedRowboatsWithSpace.Remove(otherRowboat); //tar bort den ur listan så inte nästa får samma plats
                }
                rowboatsToCheck = rowboatsToCheck.Where(notAssignedRowboat).ToList();
            }
        }
        /// <summary>
        /// Så länge det finns plats och roddbåtar kommer loopen att köras tills den hittar en plats
        /// </summary>
        /// <param name="rowboats"></param>
        /// <param name="port"></param>
        public void GiveRowboatUnassignedSpot(List <Boat> boats, Port port)
        {
            int            currentSpot     = 0;
            List <Rowboat> rowboatsToCheck = boats.OfType <Rowboat>().Where(notAssignedRowboat).ToList();

            //medans det finns plats kvar och roddbåtar i listan
            //ska loopen köras
            while (port.SpotsLeft > 0f && rowboatsToCheck.Any())
            {
                foreach (Rowboat rowboat in rowboatsToCheck)
                {
                    int  rowboatsOnSpot   = port.Boats.Count(boat => anotherRowboatOnSameSpot(boat, currentSpot));
                    bool currentSpotTaken = port.OccupiedSpots[currentSpot];

                    //för att en roddbåt ska kunna parkera måste det antingen vara exakt 1 där eller så ska platsen vara ledig
                    bool rowboatCanPark = rowboatsOnSpot == 1 || !currentSpotTaken;


                    if (rowboatCanPark)
                    {
                        rowboat.AssignedSpot = new int[1] {
                            currentSpot
                        };
                        port.AddBoat(rowboat);
                        continue;
                    }
                    else if (rowboatsOnSpot == 2 || currentSpotTaken)
                    {
                        break;
                    }
                }

                currentSpot++;
                rowboatsToCheck = rowboatsToCheck.Where(notAssignedRowboat).ToList();
                if (currentSpot == port.OccupiedSpots.GetUpperBound(0))
                {
                    break;
                }
            }
        }
        public void TryPortSpots(List <Boat> boats, Port port, List <int[]> spots)
        {
            var positionsToCheck = spots.OrderBy(portSpotSize)
                                   .ThenBy(firstSpot)
                                   .ToList();

            foreach (int[] position in positionsToCheck)
            {
                int         max          = position[1];
                List <Boat> boatsToCheck = boats.Where(notAssigned).OrderBy(boatSize).ToList();

                foreach (Boat boat in boatsToCheck)
                {
                    int currentSpot = position[0];

                    if (currentSpot > max)
                    {
                        break;
                    }
                    //array index 0, därför -1
                    int spotsToTake = (int)boat.Size - 1;

                    //eftersom listan med nya båtar är sorterade efter storleksordning kan man anta att
                    //nästa båt inte heller får plats, därav break
                    bool boatIsTooBig = !boatCanPark(port, currentSpot, max, spotsToTake);

                    if (boatIsTooBig)
                    {
                        break;
                    }
                    bool spotTaken = port.OccupiedSpots[currentSpot];

                    int  rowboatsOnSpot       = port.Boats.Count(boat => anotherBoatOnSameSpot(boat, currentSpot) && boatIsRowboat(boat));
                    int  rowboatsLeftToAssign = boatsToCheck.Count(boat => boatIsRowboat(boat) && notAssigned(boat));
                    bool rowboatCanPark       = boatIsRowboat(boat) && (rowboatsOnSpot == 1 || !spotTaken);


                    if (rowboatCanPark)
                    {
                        //hur många roddbåtar som det är kvar och hur många det är på platsen, är det
                        //redan en roddbåt på platsen så kommer inte det få plats en till, då plussas position[0] på med 1
                        //så får nästa båt försöka klämma sig in
                        //från nästa plats och är det här den sista som inte har en hamnplats ska samma sak ske
                        position[0]      += rowboatsOnSpot == 1 || rowboatsLeftToAssign == 1 ? 1 : 0;
                        boat.AssignedSpot = new int[1] {
                            currentSpot
                        };
                        port.AddBoat(boat);
                        continue;
                    }

                    //är platsen upptagen ska startpositionen för nästa båt bli 1 högre,
                    else if (spotTaken)
                    {
                        position[0]++;
                        continue;
                    }


                    //special regler för motorbåt, den ska bara få 1 hamnplats, och behöver inte en array med 2 index
                    else if (boat is Motorboat)
                    {
                        boat.AssignedSpot = new int[1] {
                            currentSpot
                        };
                        position[0]++;
                        port.AddBoat(boat);
                        continue;
                    }

                    else
                    {
                        //nästa båt ska börja kolla efter en plats
                        //från den sista båtens andra position
                        //dvs om en båt fick plats {22,24} ska nästa börja kolla från 25
                        int end        = currentSpot + spotsToTake;
                        int newMinimum = end + 1;
                        boat.AssignedSpot = new int[2] {
                            currentSpot, end
                        };
                        position[0] = newMinimum;
                        port.AddBoat(boat);
                        continue;
                    }
                }
            }
        }