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:
Private d = New cubepuzzle
cubepuzzle class, we have:
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:
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.
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.
AddHandler partbox.MouseMove, AddressOf partbox_MouseMove partbox.Image = d.partentrymap
partbox_MouseMove event, we use the position and left and right click to provide the part configuration to the puzzle class:
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,
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:
Dim partbox As New PictureBox partbox =
d.picbox(False) Me.Controls.Add(partbox) d.enter_part() partbox.Image =
When all parts have been input, the user selects to solve the puzzle, and we:
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:
Windows controls are not thread safe, so to prevent clash with the worker, the refresh is also wrapped in
Finally, the solution is displayed on the form, or a message of no solution is displayed.