public static Bullet CopyAndFlip(Bullet bullet, CoordinateFlipper flipper,
            Dictionary<int, Entity> flippedEntities)
        {
            if (flippedEntities.ContainsKey(bullet.Id)) return (Bullet) flippedEntities[bullet.Id];

            var copy = new Bullet(bullet)
            {
                PlayerNumber = bullet.PlayerNumber == 1 ? 2 : 1,
                X = flipper.CalculateFlippedX(bullet.X),
                Y = flipper.CalculateFlippedY(bullet.Y)
            };

            flippedEntities.Add(copy.Id, copy);
            return copy;
        }
 private Bullet(Bullet bullet)
     : base(bullet)
 {
 }
        private void Shoot()
        {
            var bulletX = X;
            var bulletY = (PlayerNumber == 1) ? Y - 1 : Y + 1;

            var bullet = new Bullet(PlayerNumber) {X = bulletX, Y = bulletY};

            try
            {
                GetMap().AddEntity(bullet);
            }
            catch (CollisionException ex)
            {
                ex.Entity.Destroy();
            }
        }
        public void TestShipMovingRightIntoBulletDies()
        {
            // Given
            var game = Match.GetInstance();
            game.StartNewGame();
            var map = game.Map;

            var player = game.GetPlayer(1);
            var ship = player.Ship;
            var aliens = game.GetPlayer(2).AlienManager;

            // When
            var bullet = new Bullet(2) { X = ship.X + 3, Y = ship.Y - 1 };
            map.AddEntity(bullet);

            ship.Command = ShipCommand.MoveRight;
            game.Update();

            // Then
            Assert.IsFalse(bullet.Alive, "Bullet was not destroyed, must've mis-timed the collision.");
            Assert.IsNull(player.Ship, "Ship was not destroyed.");
        }
        public void TestMultipleBulletsKillShip()
        {
            // Given
            var game = Match.GetInstance();
            game.StartNewGame();

            var player = game.GetPlayer(1);
            var ship = player.Ship;
            var map = game.Map;
            var player2 = game.GetPlayer(2);
            var initialScore = player2.Kills;

            // When

            var bullet1 = new Bullet(2) { X = ship.X, Y = ship.Y - 3 }; //left side of ship
            map.AddEntity(bullet1);
            var bullet2 = new Bullet(2) { X = ship.X + 1, Y = ship.Y - 3 }; //centre of ship
            map.AddEntity(bullet2);
            var bullet3 = new Bullet(2) { X = ship.X + 2, Y = ship.Y - 3 }; //right side of ship
            map.AddEntity(bullet3);

            for (var i = 0; i < respawnDelay; i++)
            {
                game.Update();
            }
            var finalScore = player2.Kills;

            // Then
            Assert.IsNull(player.Ship, "Ship was not destroyed.");
            Assert.IsFalse(bullet1.Alive, "Bullet was not destroyed, must've mis-timed the collision.");
            Assert.IsFalse(bullet2.Alive, "Bullet was not destroyed, must've mis-timed the collision.");
            Assert.IsFalse(bullet3.Alive, "Bullet was not destroyed, must've mis-timed the collision.");
            Assert.IsTrue(finalScore == initialScore, "Player 2 increased.");
        }
        public void TestBuildShieldDestroysMissilesAndBullets()
        {
            // Given
            var game = Match.GetInstance();
            game.StartNewGame();
            var map = game.Map;
            var player = game.GetPlayer(1);
            var ship = player.Ship;

            // When
            var missile = new Missile(2) {X = ship.X, Y = ship.Y - 3};
            var bullet = new Bullet(2) {X = ship.X + 2, Y = ship.Y - 3};
            map.AddEntity(missile);
            map.AddEntity(bullet);
            ship.Command = ShipCommand.BuildShield;
            game.Update();

            // Then
            Assert.IsFalse(missile.Alive, "Missile was not destroyed");
            Assert.IsFalse(bullet.Alive, "Bullet was not destroyed");

            Assert.IsNotNull(map.GetEntity(ship.X, ship.Y - 1),
                "Left rear shield tile is missing");
            Assert.IsNotNull(map.GetEntity(ship.X + 1, ship.Y - 1),
                "Center rear shield tile is missing");
            Assert.IsNotNull(map.GetEntity(ship.X + 2, ship.Y - 1),
                "Right rear shield tile is missing");

            // Missiles and bullets fly for one turn before the shields spawn, hence here instead of in front
            Assert.IsNull(map.GetEntity(ship.X, ship.Y - 2),
                "Left middle shield was not destroyed");
            Assert.IsNotNull(map.GetEntity(ship.X + 1, ship.Y - 2),
                "Center middle shield tile is missing");
            Assert.IsNull(map.GetEntity(ship.X + 2, ship.Y - 2),
                "Right middle shield tile was not destroyed");

            Assert.IsNotNull(map.GetEntity(ship.X, ship.Y - 3),
                "Left front shield tile is missing");
            Assert.IsNotNull(map.GetEntity(ship.X + 1, ship.Y - 3),
                "Center front shield tile is missing");
            Assert.IsNotNull(map.GetEntity(ship.X + 2, ship.Y - 3),
                "Right front shield tile is missing");
        }
        public void TestShipSpawningOnMultipleEntitiesDie()
        {
            // Given
            var game = Match.GetInstance();
            game.StartNewGame();

            var player = game.GetPlayer(1);
            var ship = player.Ship;
            var aliens = game.GetPlayer(2).AlienManager;
            var map = game.Map;
            var player2 = game.GetPlayer(2);
            var initialScore = player2.Kills;

            // When
            var alien = aliens.TestAddAlien(ship.X, ship.Y - 3); //left side of ship
            aliens.TestMakeAllAliensMoveForward();
            ship.Destroy();
            var missile = new Missile(2) { X = ship.X + 1, Y = ship.Y - 3 }; //centre of ship
            map.AddEntity(missile);

            var bullet = new Bullet(2) { X = ship.X + 2, Y = ship.Y - 3 }; //right side of ship
            map.AddEntity(bullet);

            for (var i = 0; i < respawnDelay; i++)
            {
                game.Update();
            }
            var finalScore = player2.Kills;

            // Then
            Assert.IsFalse(alien.Alive, "Alien was not destroyed, must've mis-timed the collision.");
            Assert.IsNull(player.Ship, "Ship was not destroyed.");
            Assert.IsFalse(missile.Alive, "Missile was not destroyed, must've mis-timed the collision.");
            Assert.IsFalse(bullet.Alive, "Bullet was not destroyed, must've mis-timed the collision.");
            Assert.IsTrue(finalScore > initialScore, "Player 2 score did not increase.");
        }