Click here to Skip to main content
15,885,216 members
Articles / Programming Languages / C# 4.0

Lock Puzzle: A Perplexing Puzzle

Rate me:
Please Sign up or sign in to vote.
4.68/5 (26 votes)
22 Jun 2010CPOL3 min read 33.8K   840   31  
A brain melting puzzle in which you must turn several interconnected keys to unlock the solution
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;


namespace LockProblemCS
{
    /// <summary>
    /// Coded by Christopher Denmark in 2010
    /// </summary>
    public partial class frmLockPuzzle : Form
    {
        #region Internals
        int MovesCounter = 0;
        #endregion

        #region Constructor
        public frmLockPuzzle()
        {
           InitializeComponent();
           RandomizeKeys();
            
        }
        #endregion

        #region Methods
        /// <summary>
        /// Scrambles the keys in random positions so it's a diferent game every time.
        /// </summary>
        private void RandomizeKeys()
        {
            foreach (Key l in this.panel1.Controls)
            {
                Random rnd = new Random();
                int index = rnd.Next(2);

                if (index == 0)
                {
                    l.TurnKey();
                    l.IsLocked = true;
                }
                else
                {
                    l.IsLocked = false;
                }

                System.Threading.Thread.Sleep(15);
            }

            // reset counter
            MovesCounter = 0;
            lblMoves.Text = "Moves: 0";
        }

        /// <summary>
        /// Checks the status to see if all of the keys are in the upright position
        /// </summary>
        public void CheckStatus()
        {
            int counter = 0;
            
            foreach (Key l in this.panel1.Controls)
            {
                if (l.IsLocked == false) // unlocked
                {
                    counter++;
                }
            }

            if (counter == 16)
            {
                tmrIdle.Enabled = false;
                MessageBox.Show("Congratulations! You've opened the lock."); 
            }
        }

        /// <summary>
        /// Toggles the states of the keys in corresponding rows and columns
        /// </summary>
        /// <param name="sender">The Key object sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void ToggleKeyStates(object sender, EventArgs e)
        {

            // Get Sender cell coordinates and assign them to X and X char arrays
            // This is the Key that was clicked
            char[] XY = ((Key)sender).Name.ToCharArray(1, 2);
            char X = XY[0];
            char Y = XY[1];

            // Using the clicked object as a reference, 
            // Cycle through controls and find the corresponding key objects
            foreach (Key l in this.panel1.Controls)
            {
                // split the names of the key objects into char array
                char[] xy = l.Name.ToCharArray(1, 2);
                char x = xy[0];
                char y = xy[1];

                // Change state of rows and columns only
                if (X == x || Y == y)
                {
                    if(l.IsTurning == false)
                        l.TurnKey();
                }
            }
        }

        /// <summary>
        /// Just displays how many times we click a key
        /// </summary>
        private void IncrementMovesCounter()
        {
            MovesCounter++;
            lblMoves.Text = "Moves: " + MovesCounter.ToString();
        }
        #endregion

        #region Events
        /// <summary>
        /// Generic handler that handles the click events for all key objects
        /// </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 KeyObject_Click(object sender, EventArgs e)
        {
            // Turn the first key
            ((Key)sender).TurnKey();

            // make sure the keys have finished turning before performing further actions
            if (((Key)sender).IsTurning == false)
            {  
                ToggleKeyStates(sender, e);  // move the other keys
                IncrementMovesCounter();
                tmrIdle.Enabled = true; 
            }
            
        }

        /// <summary>
        /// Handles the Click event of the btnScramble control.
        /// </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 btnScramble_Click(object sender, EventArgs e)
        {
            RandomizeKeys();
        }

        /// <summary>
        /// Handles the Tick event of the tmrCheck control.  Constantly check the orientation of the keys to see if they are all unlocked
        /// </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 tmrIdle_Tick(object sender, EventArgs e)
        {
            CheckStatus();
        }
        #endregion

        private void mnuAbout_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Programmed by: Christopher Denmark - 2010");
        }
    }
}

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)


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

Comments and Discussions