65.9K
CodeProject 正在变化。 阅读更多。
Home

立方体装配解决方案

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.25/5 (4投票s)

2009年1月19日

CPOL

2分钟阅读

viewsIcon

22203

downloadIcon

519

一个用于解决立方体组装难题的类。

引言

我有一个立方体组装难题,一直无法解决。这个难题的零件已经散落多年了。这似乎是一个提高我编程技能的理想项目。

用户界面是一个 Windows 窗体。首先,将例程封装在一个难题类中。然后在窗体代码中,我可以实例化该类

Private d = New cubepuzzle

cubepuzzle 类中,我们有

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

选择尺寸是为了给程序提供良好的偶数,以便程序能够正常工作。它将适应窗体上的 PictureBox

Using the Code

当窗体加载时,我们有

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

难题类使用用户窗体信息来设置 PictureBox 的尺寸,以便它对于任何用户屏幕分辨率都将保持相同的大小。

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

现在我们有了窗体上的 PictureBox,但我们需要将其链接到 mouse_move,然后用用户输入显示填充该框。

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

cubeassemblyVB

partbox_MouseMove 事件中,我们使用位置以及左键和右键单击来向难题类提供零件配置

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

当零件正确时,用户选择输入零件以编程。在这里,我们将零件显示的副本以减小的尺寸保存到窗体中。最多可以输入 7 个零件

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

allparts.jpg

当所有零件都输入后,用户选择解决难题,然后我们

d.solve_puzzle()

解决难题可能需要一些时间和大量的 CPU 时间,所以我启动一个低优先级的 worker 线程来执行计算。这是为了遍历每种组合以找到可行的组合。用户可以在不损失性能的情况下使用计算机,但只要计算机空闲,就可以运行 worker 线程。XP 将 CPU 保持在 100%,但 Vista 在线程工作时运行在 60%。为什么只有 60%?

worker 线程保持倒计时,并在零件位图中更新此倒计时。worker 线程无法更新 Windows 控件,因此计时器会使主线程中的显示保持更新。为了防止 worker 线程在 PictureBox 被刷新时访问位图,它被包装在

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

Windows 控件不是线程安全的,因此为了防止与 worker 冲突,刷新也被包装在 SyncLock d.part 中。

working.jpg

最后,解决方案显示在窗体上,或者显示没有解决方案的消息。

solution.jpg

© . All rights reserved.