Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Lock Puzzle: A Perplexing Puzzle

, 22 Jun 2010 CPOL
A brain melting puzzle in which you must turn several interconnected keys to unlock the solution
LockProblemCS_exe.zip
LockProblemCS.exe
LockProblemCS_src.zip
LockProblemCS
LockProblemCS
Properties
Settings.settings
LockProblemCS.suo
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Drawing.Drawing2D;

namespace LockProblemCS
{

    /// <summary>
    /// Coded by Christopher Denmark in 2010
    /// </summary>
    public partial class Key : UserControl
    {
        #region Internals and Proprties
        
        // internals
        int Degrees = 0;
        int degreeOffset = 58; // I don't know why.  58 just worked through tiral & error.  I'd love an explaination
        private bool m_isLocked = false;
        private bool m_isTurning = false;

        public bool IsLocked
        {
            get{return m_isLocked; }
            set { m_isLocked = value;}
        }
        public bool IsTurning
        {
            get{return m_isTurning;}
            set{m_isTurning = value;}
        }
        #endregion

        #region Constructor
        public Key()
        {       
            InitializeComponent();
        }
        #endregion

        #region Methods

        /// <summary>
        /// Draws the key and defines the center point and outer circular path on which the edges of the key are to follow.  
        /// </summary>
        /// <param name="g">g as Graphics object.</param>
        public void DrawKey(Graphics g)
        {
            // ake sure all graphics are smooth, not blocky.
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;

            // Declare Brush and pen objects
            Brush brshREC = new SolidBrush(Color.White);
            Pen p = new Pen(brshREC, 10);
            
            // Declare surface and origin of circle
            int x_center;
            int y_center;
            float x_path;
            float y_path;
            float x_path2;
            float y_path2;
            DefineSurfacePath(out x_center, out y_center, out x_path, out y_path, out x_path2, out y_path2);
           
            // draw previously defined points
            g.DrawLine(p, x_center, y_center, x_path, y_path);
            g.DrawLine(p, x_center, y_center, x_path2, y_path2);

        }

        /// <summary>
        /// Defines the surface path of the circle.  This is the origin and outer most lines of the key durring rotation.  one center and two lines stem outward.
        /// </summary>
        /// <param name="x_center">The x_center.</param>
        /// <param name="y_center">The y_center.</param>
        /// <param name="x_path">The x_path.</param>
        /// <param name="y_path">The y_path.</param>
        /// <param name="x_path2">The x_path2.</param>
        /// <param name="y_path2">The y_path2.</param>
        private void DefineSurfacePath(out int x_center, out int y_center, out float x_path, out float y_path, out float x_path2, out float y_path2)
        {
            int Radius = 30;
            x_center = this.Width / 2;
            y_center = this.Height / 2;

            // define outer rotation path for first line
            x_path = (GetCos(360 + Degrees + x_center + degreeOffset) * Radius) + x_center;
            y_path = (GetSin(360 + Degrees + y_center + degreeOffset) * Radius) + y_center;

            // define outer rotation path for second line
            x_path2 = (GetCos(360 + Degrees + 180 + x_center + degreeOffset) * Radius) + x_center;
            y_path2 = (GetSin(360 + Degrees + 180 + y_center + degreeOffset) * Radius) + y_center;
        }

        /// <summary>
        /// Turns the key and toggles the relevant variables.
        /// </summary>
        public void TurnKey()
        {
            // toggle status of 'turning flag'
            m_isTurning = !m_isTurning;

            // remains locked until turn is complete
            m_isLocked = true;

            // toggle timer           
            this.timer1.Enabled = !this.timer1.Enabled;     
        }

        /// <summary>
        /// Defines the limits of rotation.
        /// </summary>
        private void DefinePositions()
        {
            // Rotate and stop at the 3, 6, 9, and 12 o'clock positions.
            if (Degrees == 360)
            {
                Degrees = 0;                    // reset
                this.timer1.Enabled = false;    // stop timer
                m_isTurning = !m_isTurning;     // toggle turning flag
                m_isLocked = false;             // toggle locked flag
            }
            else if (Degrees == 90)
            {
                this.timer1.Enabled = false;
                m_isTurning = !m_isTurning;
                m_isLocked = true;
                Degrees++;
            }
            else if (Degrees == 180)
            {
                this.timer1.Enabled = false;
                m_isTurning = !m_isTurning;
                m_isLocked = false;
                Degrees++;
            }
            else if (Degrees == 270)
            {
                this.timer1.Enabled = false;
                m_isTurning = !m_isTurning;
                m_isLocked = true;
                Degrees++;
            }
            else  // keep moving and let us know that you are moving.
            {
                Degrees++;
                m_isTurning = true;
            }

            // Update the form and controls.
            this.Refresh();
        }

        /// <summary>
        /// Gets the sin.
        /// </summary>
        /// <param name="degAngle">The angle of the Degree.</param>
        /// <returns></returns>
        private static float GetSin(float degAngle)
        {
            return (float)Math.Sin(Math.PI * degAngle / 180f);
        }

        /// <summary>
        /// Gets the cos.
        /// </summary>
        /// <param name="degAngle">The angle of the Degree.</param>
        /// <returns></returns>
        private static float GetCos(float degAngle)
        {
            return (float)Math.Cos(Math.PI * degAngle / 180f);
        }
        #endregion

        #region Override(s)
        protected override void OnPaint(PaintEventArgs e)
        {
            // give .net the first try
            base.OnPaint(e);

            // then take over
            Graphics g = e.Graphics;
            DrawKey(g);
        }

        #endregion
        
        #region Events
        private void timer1_Tick(object sender, EventArgs e)
        {
            // Defines postion of the key
            DefinePositions();
        }


        /// <summary>
        /// Handles the Click event of the Key control.  Makes sure the key is not already turning before you turn it.  
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void Lock_Click(object sender, EventArgs e)
        {
            // make sure your not in the process turning already
            if(m_isTurning == false)
                TurnKey();
        }
        #endregion

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Christopher Denmark
Software Developer (Senior)
United States United States
Technical professional with 11 years of experience in designing, developing and implementing sophisticated software solutions.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150123.1 | Last Updated 22 Jun 2010
Article Copyright 2010 by Christopher Denmark
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid