Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VB

A cube assembly solution

4.25/5 (4 votes)
19 Jan 2009CPOL2 min read 21.8K   491  
A puzzle class to solve a cube assembly puzzle.

Introduction

I have a cube assembly puzzle that I could not solve. The parts of the puzzle have been laying around loose for years. It appeared to be an ideal project to improve my programming skills.

The user interface is a Windows Form. First, encapsulate the routines in a puzzle class. Then, in the form code, I can instantiate the class by:

VB
Private d = New cubepuzzle

In the cubepuzzle class, we have:

VB
Public part As New Bitmap(1301, 501, Drawing.Imaging.PixelFormat.Format24bppRgb)

The dimensions are chosen to give nice even numbers for the program to work with. It will fit into a PictureBox on the form.

Using the Code

When the form loads, we have:

VB
d.wide = Me.Width d.high = Me.Height

The puzzle class uses the user form information to set the dimensions of the PictureBox so that it will be the the same size for any user screen resolution.

VB
Dim partbox As New PictureBox partbox = d.picbox(True) Me.Controls.Add(partbox)

We now have the PictureBox on the form, but we need to link to mouse_move and then fill the box with the user entry display.

VB
AddHandler partbox.MouseMove, AddressOf partbox_MouseMove partbox.Image = d.partentrymap

cubeassemblyVB

In the partbox_MouseMove event, we use the position and left and right click to provide the part configuration to the puzzle class:

VB
If e.Button = Windows.Forms.MouseButtons.Left Then C_left = True If e.Button = 
    Windows.Forms.MouseButtons.Right Then C_right = True d.shaderect(e.Y, e.X, C_left,
    C_right) 'input to bitmap and puzzle array

When the part is correct, the user selects the enter part to program. Here, we save a copy of the part display in a reduced size to the form. Up to 7 parts can be input:

VB
Dim partbox As New PictureBox partbox = 
    d.picbox(False) Me.Controls.Add(partbox) d.enter_part() partbox.Image = 
    d.partentrymap.clone

allparts.jpg

When all parts have been input, the user selects to solve the puzzle, and we:

VB
d.solve_puzzle()

The puzzle may take some time and lots of CPU time, so I start a worker thread with a low priority to do the calculations. This is to go through every combination to find one that works. The user can use the computer without loss of performance, but whenever it's free, it can run the worker thread. XP keeps the CPU at 100%, but Vista runs at 60% while the thread is working. Why only 60%??

The worker thread keeps a count down going, and updates this in the part bitmap. The worker thread cannot update the Windows control, so a timer keeps the display updated in the main thread. To prevent the worker thread accessing the bitmap while the PictureBox is being refreshed, it is wrapped in:

VB
SyncLock part  'ensure not using same time as form  End SyncLock

Windows controls are not thread safe, so to prevent clash with the worker, the refresh is also wrapped in SyncLock d.part.

working.jpg

Finally, the solution is displayed on the form, or a message of no solution is displayed.

solution.jpg

License

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