예제 #1
0
        public void ApplyEngineAction(EngineActions action)
        {
            var tip        = new[] { Math.Sin(this.transform.Rotation), Math.Cos(this.transform.Rotation) };
            var side       = new[] { -tip[1], tip[0] };
            var dispersion = new[] { ((this.random.NextDouble() * 2) - 1) / LunarConstants.SCALE, ((this.random.NextDouble() * 2) - 1) / LunarConstants.SCALE };

            if (action == EngineActions.Main)
            {
                var power           = 1f;
                var ox              = tip[0] * (4 / LunarConstants.SCALE + 2 * dispersion[0]) + side[0] * dispersion[1];
                var oy              = -tip[1] * (4 / LunarConstants.SCALE + 2 * dispersion[0]) - side[1] * dispersion[1];
                var impulsePosition = new Vector2(this.transform.Position.X + (float)ox, this.transform.Position.Y + (float)oy);
                var impulsePower    = new Vector2((float)-ox * LunarConstants.MAIN_ENGINE_POWER * power, (float)oy * LunarConstants.MAIN_ENGINE_POWER * power);
                this.body.ApplyLinearImpulse(impulsePower, impulsePosition, true);
                this.particlesEmitter.CreateParticle(3.5f, impulsePosition, power, impulsePower * -1f);
            }

            if (action == EngineActions.Left || action == EngineActions.Right)
            {
                var power           = 1f;
                var direction       = (int)action - 2;
                var ox              = tip[0] * dispersion[0] + side[0] * (3 * dispersion[1] + direction * LunarConstants.SIDE_ENGINE_AWAY / LunarConstants.SCALE);
                var oy              = -tip[1] * dispersion[0] - side[1] * (3 * dispersion[1] + direction * LunarConstants.SIDE_ENGINE_AWAY / LunarConstants.SCALE);
                var impulsePosition = new Vector2(this.transform.Position.X + (float)ox - (float)tip[0] * 17 / LunarConstants.SCALE, this.transform.Position.Y + (float)oy + (float)tip[1] * LunarConstants.SIDE_ENGINE_HEIGHT / LunarConstants.SCALE);
                var impulsePower    = new Vector2((float)-ox * LunarConstants.SIDE_ENGINE_POWER * power, (float)oy * LunarConstants.SIDE_ENGINE_POWER * power);
                this.body.ApplyLinearImpulse(impulsePower, impulsePosition, true);
                this.particlesEmitter.CreateParticle(3.5f, impulsePosition, power, impulsePower * -1f);
            }
        }
예제 #2
0
        public void ApplyEngineAction(EngineActions action)
        {
            var rotation = Quaternion.Identity;

            var enginePenalty = 0f;

            switch (action)
            {
            case EngineActions.None:
                break;

            case EngineActions.YawPositive:
                this.shipBody.ApplyTorqueImpulse(this.transform.WorldTransform.Up * rotationImpulse);
                enginePenalty -= 0.03f;
                break;

            case EngineActions.YawNegative:
                this.shipBody.ApplyTorqueImpulse(this.transform.WorldTransform.Up * -rotationImpulse);
                enginePenalty -= 0.03f;
                break;

            case EngineActions.RollPositive:
                this.shipBody.ApplyTorqueImpulse(this.transform.WorldTransform.Forward * -rotationImpulse);
                enginePenalty -= 0.03f;
                break;

            case EngineActions.RollNegative:
                this.shipBody.ApplyTorqueImpulse(this.transform.WorldTransform.Forward * rotationImpulse);
                enginePenalty -= 0.03f;
                break;

            case EngineActions.Main:
                var impulse = 0.7f * this.transform.LocalTransform.Up;
                this.shipBody.ApplyImpulse(impulse);
                this.dust.MainEngine = true;
                enginePenalty       -= 0.3f;
                break;

            case EngineActions.PitchPositive:
                this.shipBody.ApplyTorqueImpulse(this.transform.WorldTransform.Left * rotationImpulse);
                enginePenalty -= 0.03f;

                break;

            case EngineActions.PitchNegative:
                this.shipBody.ApplyTorqueImpulse(this.transform.WorldTransform.Left * -rotationImpulse);
                enginePenalty -= 0.03f;
                break;

            default:
                break;
            }

            if (this.numActions < MaxActions)
            {
                this.actionsQueue[this.numActions++] = action;
            }
        }
예제 #3
0
        private ActionResult GetActionResult(EngineActions action)
        {
            var observation = this.GetUpdatedObservation();

            var gameOver = this.LanderBodyCollided; // || !this.LanderAwake

            return(new ActionResult
            {
                Done = gameOver,
                Observation = observation,
                Reward = 0f
            });
        }
예제 #4
0
        private ActionResult GetActionResult(EngineActions action)
        {
            var observation = new Observation
            {
                PosX         = this.landerBody.Transform2D.Position.X / ((LunarConstants.VIEWPORT_W / LunarConstants.SCALE) / 2),
                PosY         = (LunarConstants.VIEWPORT_H - this.landerBody.Transform2D.Position.Y) / (LunarConstants.VIEWPORT_H / LunarConstants.SCALE),
                VelX         = this.landerBody.LinearVelocity.X * ((LunarConstants.VIEWPORT_W / LunarConstants.SCALE) / 2) / LunarConstants.FPS,
                VelY         = this.landerBody.LinearVelocity.Y * ((LunarConstants.VIEWPORT_H / LunarConstants.SCALE) / 2) / LunarConstants.FPS,
                Angle        = this.landerBody.RigidBody.Angle,
                AngVel       = 20f * this.landerBody.AngularVelocity / LunarConstants.FPS,
                LeftContact  = this.leftCollided ? 1f : 0f,
                RightContact = this.rightCollided ? 1f : 0f
            };

            var reward  = 0d;
            var shaping = -100 * Math.Sqrt(observation.PosX * observation.PosX + observation.PosY * observation.PosY)
                          - 100 * Math.Sqrt(observation.VelX * observation.VelX + observation.VelY * observation.VelY)
                          - 100 * Math.Abs(observation.Angle) + 10 * observation.LeftContact + 10 * observation.LeftContact;

            if (this.previousShaping != null)
            {
                reward = shaping - this.previousShaping.Value;
            }

            this.previousShaping = shaping;

            reward -= (action == EngineActions.Main ? 1 : 0) * 0.3;
            reward -= (action == EngineActions.Left || action == EngineActions.Right ? 1 : 0) * 0.3;

            var done = false;

            if (this.gameOver || Math.Abs(observation.PosX) >= 1)
            {
                done   = true;
                reward = -100;
            }

            if (!this.landerBody.Awake)
            {
                done   = true;
                reward = 100;
            }

            return(new ActionResult
            {
                Done = done,
                Observation = observation,
                Reward = (float)reward
            });
        }
예제 #5
0
 private void OnActionReceived(object sender, EngineActions e)
 {
     this.shipComponent.ApplyEngineAction(e);
 }