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()); }