Click here to Skip to main content
15,884,353 members
Articles / Programming Languages / C# 3.5

Dynamic Sliding Puzzle Generator

Rate me:
Please Sign up or sign in to vote.
4.67/5 (3 votes)
27 Mar 2011CC (Attr 3U)2 min read 41.5K   2.3K   19   10
A dynamic sliding puzzle generator involving LINQ and photo scaling functionalities.

Image 1 Image 2

Introduction

As per Wiki, a sliding puzzle, sliding block puzzle, or sliding tile puzzle challenges a player to slide usually flat pieces along certain routes (usually on a board) to establish a certain end-configuration. But here I would go for a simple (programmatically complex) prototype of sliding puzzle where the players have the flexibility to generate a puzzle from an image of their choice.

Background

Of late, I have been going through various ways of implementing the sliding puzzle (in fact, there are numerous ways even). This version of game here is pretty simple and very dynamic in nature. Each and every line here is written in such a way that the user has complete flexibility to set the size of the individual pieces of a picture as well as the number of cells per row.

The key features in implementing the game are:

  1. Extremely dynamic with respect to the number of rows and the size of each individual cell.
  2. Loads image pieces dynamically.
  3. Scales images to the length of the puzzle.
  4. Uses events to implement the logic.

Using the code

The logic here is to construct and add images dynamically to the Windows form. The function AssignEventsToButtons() does the core functionality of this.

C#
private void AssignEventsToButtons()
{
    PictureBox temp = null;
    int x = -1;
    for (int i = 0; i <= MaxSeed; i++)
    {
         temp = new PictureBox
                {
                   TabIndex = ++x,
                   SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage,
                   Size = new System.Drawing.Size(SideLength, SideLength),
                   Name = string.Concat("pictureBox", x.ToString()),
                   AllowDrop = true,
                   Location = new Point(0, 0)
                };
        
        temp.MouseDown += new MouseEventHandler(button_MouseDown);
        temp.DragDrop += new DragEventHandler(button_DragDrop);
        temp.DragEnter += new DragEventHandler(button_DragEnter);
        temp.CreateControl();
        flowLayoutPanel1.Controls.Add(temp);
    }
    
    flowLayoutPanel1.Controls.Add(this.groupBox1);
    flowLayoutPanel1.PerformLayout();
}

Handling mouse events is crucial here. Every piece of block has to be handling all the three events, namely MouseDown, DragDrop, and DragEnter. Initially consider a piece to be moved to white space, the mouse down event of the current piece is handled to send the picture forward.

C#
private void button_MouseDown(object sender, MouseEventArgs e)
{
    Cursor = Cursors.Hand;
    _dragSource = (PictureBox)sender;
    _dragSource.DoDragDrop(_dragSource.Image, 
                DragDropEffects.Copy | DragDropEffects.Move);
}

The event DragEnter is basically to handle the desired effect of moving the picture.

C#
private void button_DragEnter(object sender, DragEventArgs e)
{
    e.Effect = e.Data.GetDataPresent(DataFormats.Bitmap) ? 
                         DragDropEffects.Move : DragDropEffects.None;
}

The logic part of the game is to check for a valid move. The dragging piece's information is stored and is compared with the destination piece's, with the following steps:

  1. Destination place should be a valid position to move (no cross movements).
  2. An image should not allow drag and drop on itself.
  3. Once checks are done, the images are swapped.
C#
private void button_DragDrop(object sender , DragEventArgs e)
{
    var dest = (PictureBox) sender;

    if(dest.Image.Equals(_dragSource.Image))
        return;

    if( !new List<int>
             {
                 _dragSource.TabIndex + 1,
                 _dragSource.TabIndex - 1,
                 _dragSource.TabIndex + RowCount,
                 _dragSource.TabIndex - RowCount
             }.Contains(dest.TabIndex))
    {
        MessageBox.Show(Resources.DynPuzzleform_button_DragDrop_Invalid_move);
        return;
    }
    
    if (!ImageCompareArray(dest.Image as Bitmap,Resources._17))
    {
        MessageBox.Show(Resources.DynPuzzleform_button_DragDrop_Invalid_move);
        return;
    }

    _dragSource.Image = dest.Image;
    dest.Image = e.Data.GetData(DataFormats.Bitmap) as Image;

    //checks state
    CheckState(_dragSource.TabIndex, dest.TabIndex);
}

Here the function CheckState checks for the state of the game on every step, and is checked with _successState so as to confirm the game's completion. Another interesting feature in this game can be seen when you press F3. Yes, you can load an image of your choice. The image is scaled down to the size the player configured, without distortion. The ResizeImage function does this for you.

Image 3

Note: Check for the settings SideLength and RowCount in DynSlidingPuzzle.exe.config. Please assign valid values for the same.

Conclusion

This concludes the making of a simple yet dynamic game application that demonstrates the ease of using .NET. Please go through the code and let me know your comments. Thanks in advance.

License

This article, along with any associated source code and files, is licensed under The Creative Commons Attribution 3.0 Unported License


Written By
Software Developer (Junior) Thomson Reuters
India India
Currently, I am Software Engineer in ThomsonReuters. I am a man who believes in a fact that -"Technology is best available now-a-days but what matter is "How you use it?" and "What you solved using it?" ....." My site, my work and everything about me demonstrates this basic idea. I do what I love and I love what I do.....
U can find all about me @ http://www.AKrishnachytanya.com Smile | :)

Comments and Discussions

 
Questionsource code Pin
Member 126694998-Aug-16 7:28
Member 126694998-Aug-16 7:28 
GeneralMy vote of 4 Pin
Amol Rawke Pune30-Mar-11 20:26
Amol Rawke Pune30-Mar-11 20:26 
GeneralRe: My vote of 4 Pin
Krishnachytanya Ayyagari2-Apr-11 8:42
Krishnachytanya Ayyagari2-Apr-11 8:42 
Generalpuzzling Pin
Luc Pattyn25-Mar-11 0:07
sitebuilderLuc Pattyn25-Mar-11 0:07 
GeneralRe: puzzling Pin
Krishnachytanya Ayyagari25-Mar-11 2:12
Krishnachytanya Ayyagari25-Mar-11 2:12 
AnswerRe: puzzling Pin
Luc Pattyn25-Mar-11 2:26
sitebuilderLuc Pattyn25-Mar-11 2:26 
GeneralRe: puzzling Pin
Krishnachytanya Ayyagari25-Mar-11 3:32
Krishnachytanya Ayyagari25-Mar-11 3:32 
AnswerRe: puzzling Pin
Luc Pattyn25-Mar-11 3:43
sitebuilderLuc Pattyn25-Mar-11 3:43 
GeneralThat's not a jigsaw puzzle... Pin
Dave Kreskowiak24-Mar-11 17:40
mveDave Kreskowiak24-Mar-11 17:40 
GeneralRe: That's not a jigsaw puzzle... Pin
Krishnachytanya Ayyagari25-Mar-11 4:35
Krishnachytanya Ayyagari25-Mar-11 4:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.