Exemplo n.º 1
0
 public ShipPosition[] NewGame(GameSettings gameSettings)
 {
     _shooter = new Shooter(gameSettings, _hmg, _opt);
     if (_sg == ShipGenerator.BigBrain)
     {
         return(BattlefieldMap.GenerateInitialShipPositionsBigBrain(gameSettings));
     }
     else
     {
         return(BattlefieldMap.GenerateInitialShipPositions(gameSettings));
     }
 }
        // tests if placed ships don't violate rules
        private static bool PlacingSuccessful(BattlefieldMap map)
        {
            var gb = new Gameboard((byte)map.Width, (byte)map.Height);

            try
            {
                gb.PlaceShips(map.ConvertShipPositionsForEngine());
            }
            catch (GameOverException)
            {
                return(false);
            }
            return(true);
        }
        // randomly places ships according to rules
        public static ShipPosition[] GenerateInitialShipPositions(GameSettings gs)
        {
            BattlefieldMap map = new BattlefieldMap(gs);
            Random         rnd = new Random();

            /*
             * // "anti grid pattern" hack
             * // it didn't really work when we had single tile ships generated first - ommited, implemented correctly in the "big brain" generator
             * var singles = map.ShipTypes.FindAll(x => x == ShipType.Submarine);
             * map.ShipTypes.RemoveAll(x => x == ShipType.Submarine);
             * Console.WriteLine("a");
             * int a = (rnd.Next(2) == 1) ? (int)Math.Floor(singles.Count / 2.0) : (int)Math.Ceiling(singles.Count / 2.0); // in case there is odd number of single tile ships, we won't have bias for either odd or even tiles
             * Console.WriteLine($"b {a}");
             * for (int i = 0; i < a; i++)
             *  map.Ships.Add(new ShipPosition(ShipType.Submarine, new Position((byte)(2 * rnd.Next(0, (int)Math.Floor(map.Width / 2.0)) + 1), (byte)(2 * rnd.Next(0, (int)Math.Floor(map.Height / 2.0)) + 1)), Orientation.Down));
             * Console.WriteLine("c");
             * for (int i = 0; i < singles.Count - a; i++)
             *  map.Ships.Add(new ShipPosition(ShipType.Submarine, new Position((byte)(2 * rnd.Next(0, (int)Math.Floor(map.Width / 2.0))), (byte)(2 * rnd.Next(0, (int)Math.Floor(map.Height / 2.0)))), Orientation.Down));
             * Console.WriteLine("d");
             */
            bool success;

            /*
             * foreach (var s in map.ShipTypes)
             *  Console.Write("O");
             * foreach (var s in map.Ships)
             *  Console.Write("S");
             */
            foreach (var ship in map.ShipTypes)
            {
                do
                {
                    map.Ships.Add(new ShipPosition(ship, new Position((byte)rnd.Next(0, map.Width), (byte)rnd.Next(0, map.Height)), (Orientation)rnd.Next(0, 4)));
                    success = PlacingSuccessful(map);
                    if (!success)
                    {
                        map.Ships.RemoveAt(map.Ships.Count - 1);
                    }
                } while (!success);
                //Console.WriteLine("e");
            }
            return(map.ConvertShipPositionsForEngine());
        }
        public static ShipPosition[] GenerateInitialShipPositionsBigBrain(GameSettings gs)
        {
            // expects big brain move from other players - looking for ships more frequently on the edge or in the centre - punishes this approach by placing ships "in between" the edge and the centre
            // using random gaussian generator: https://stackoverflow.com/questions/218060/random-gaussian-variables
            BattlefieldMap map = new BattlefieldMap(gs);

            RandomGaussian rnd = new RandomGaussian();

            bool lastSingleShipPlacement = rnd.NextBool(); // when there is odd count of single tile ships, we don't want to have equal change to select odd or even tiles

            foreach (var ship in map.ShipTypes)
            {
                bool success = false;
                do
                {
                    Position p = new Position(1, 1);
                    if ((int)ship == 1)
                    {
                        // anti grid pattern hack - when someone uses grid (as I do), it makes it harder for them by placing 1/2 of the ships on the odd and 1/2 on the even tiles
                        lastSingleShipPlacement = !lastSingleShipPlacement;
                        do
                        {
                            p = rnd.NextPosition(map.Width, map.Height);
                        } while (((p.X + p.Y) % 2 == 0) ^ lastSingleShipPlacement); // this just works, don't ask me how
                    }
                    else
                    {
                        p = rnd.NextPosition(map.Width, map.Height);
                    }
                    map.Ships.Add(new ShipPosition(ship, p, (Orientation)rnd.Next(0, 4)));
                    success = PlacingSuccessful(map);
                    if (!success)
                    {
                        map.Ships.RemoveAt(map.Ships.Count - 1);
                    }
                } while (!success);
            }

            return(map.ConvertShipPositionsForEngine());
        }