生活随笔
收集整理的這篇文章主要介紹了
八皇后问题求解动态图形演示
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
??? 這是我以前用Delphi寫的一個教學軟件。內容是關于“八皇后”問題的求解動態圖形演示。這個軟件采用多線程設計,包含了遞歸回溯與非遞歸回溯兩種算法,還可隨時調整演示速度,界面共有五種前景和五種背景圖形。包含所有源程序和資源文件。
??? 以下是軟件截圖:
??? 其中的核心Unit如下:?
unit?Unit2; ??interface ??uses ???Windows,?Messages,?Classes,?SysUtils,?StdCtrls,?Graphics; ??type ???TQS?=?function(n:?integer):?boolean?of?object; ???TQueenThread?=?class(TThread) ???private ?????FBackgroundBitmap:?TBitmap; ?????FQueenIcon,?FSeekIcon,?FClashIcon:?TIcon; ?????FCanvas:?TCanvas; ?????FCounter:?integer; ?????FQueen:?integer; ?????FDemo:?boolean; ?????FDelay:?integer; ?????FClashRestoreIcon,?FSeekQueenIcon:?TIcon; ?????FRecursion:?boolean; ?????QS:?TQS; ?????procedure?SeekFinish(Sender:?TObject); ?????function?QSeek(n:?integer):?boolean; ?????function?QSeekNonrecursion(n:?integer):?boolean; ?????function?QClash(n:?integer):?boolean; ?????procedure?ShowDelete; ?????procedure?ShowDraw; ?????procedure?ShowClashRestore; ?????procedure?SetRecursion(Value:?boolean); ???protected ?????procedure?Execute;?override; ???public?????constructor?Create(ABackgroundBitmap:?TBitmap;?AQueenIcon,?ASeekIcon,?AClashIcon:?TIcon;?ACanvas:?TCanvas); ?????procedure?ShowResult; ?????property?Demo:?boolean?write?FDemo; ?????property?Delay:?integer?write?FDelay; ?????property?Recursion:?boolean?write?SetRecursion; ???end; ??implementation ??uses?Unit1; ??constructor?TQueenThread.Create(ABackgroundBitmap:?TBitmap;?AQueenIcon,?ASeekIcon,?AClashIcon:?TIcon;?ACanvas:?TCanvas); ?begin???FBackgroundBitmap?:=?ABackgroundBitmap; ???FQueenIcon?:=?AQueenIcon; ???FSeekIcon?:=?ASeekIcon; ???FClashIcon?:=?AClashIcon; ???FCanvas?:=?ACanvas; ???FCounter?:=?0; ???FDemo?:=?true; ???FDelay?:=?400; ???SetRecursion(true); ???OnTerminate?:=?SeekFinish; ???inherited?Create(true); ?end; ??procedure?TQueenThread.SetRecursion(Value:?boolean); ?begin???FRecursion?:=?Value; ???if?FRecursion?then?????QS?:=?QSeek ???else?????QS?:=?QSeekNonrecursion; ?end; ??procedure?TQueenThread.SeekFinish(Sender:?TObject); ?begin???PostMessage(Form1.Handle,?WM_SEEKFINISH,?0,?0); ?end; ??procedure?TQueenThread.ShowClashRestore; ?var ???i:?integer; ???t:?TRect; ?begin???for?i?:=?1?to?FQueen?-?1?do ???begin?????if?(Q[FQueen]?=?Q[i])?or?(Abs(Q[FQueen]?-?Q[i])?=?(FQueen?-?i))?then?????begin???????t?:=?Rect((Q[i]?-?1)?*?CellWidth,?(i?-?1)?*?CellHeight,?Q[i]?*?CellWidth,?i?*?CellHeight); ???????FCanvas.CopyRect(t,?FBackgroundBitmap.Canvas,?t); ???????FCanvas.Draw((Q[i]?-?1)?*?CellWidth,?(i?-?1)?*?CellHeight,?FClashRestoreIcon); ?????end; ???end; ?end; ??procedure?TQueenThread.ShowDelete; ?var ???t:?TRect; ?begin???t?:=?Rect((Q[FQueen]?-?1)?*?CellWidth,?(FQueen?-?1)?*?CellHeight,?Q[FQueen]?*?CellWidth,?FQueen?*?CellHeight); ???FCanvas.CopyRect(t,?FBackgroundBitmap.Canvas,?t); ?end; ??procedure?TQueenThread.ShowDraw; ?begin???FCanvas.Draw((Q[FQueen]?-?1)?*?CellWidth,?(FQueen?-?1)?*?CellHeight,?FSeekQueenIcon); ?end; ??procedure?TQueenThread.ShowResult; ?var ???i:?integer; ?begin???FCanvas.Draw(0,?0,?FBackgroundBitmap); ???FSeekQueenIcon?:=?FQueenIcon; ???for?i?:=?1?to?8?do ???begin?????FQueen?:=?i; ?????ShowDraw; ???end; ?end; ??function?TQueenThread.QSeek(n:?integer):?boolean; ?begin???if?n?>?0?then???begin?????//==========demo?begin========== ?????if?FDemo?then?????begin???????FQueen?:=?n;?//Setup?variable?for?call?synchronize ???????Synchronize(ShowDelete); ?????end; ?????//==========demo?end============ ?????inc(Q[n]); ?????//==========demo?begin========== ?????if?FDemo?then?????begin???????FSeekQueenIcon?:=?FSeekIcon; ???????Synchronize(ShowDraw); ???????sleep(FDelay); ?????end; ?????//==========demo?end============ ?????if?Q[n]?<=?8?then???????if?QClash(n)?then???????begin?????????//==========demo?begin========== ?????????if?FDemo?then?????????begin???????????FClashRestoreIcon?:=?FClashIcon; ???????????Synchronize(ShowClashRestore); ???????????sleep(FDelay); ???????????FClashRestoreIcon?:=?FQueenIcon; ???????????Synchronize(ShowClashRestore); ?????????end; ?????????//==========demo?end============ ?????????result?:=?QSeek(n); ???????end???????else???????begin?????????//==========demo?begin========== ?????????if?FDemo?then?????????begin???????????Synchronize(ShowDelete); ???????????FSeekQueenIcon?:=?FQueenIcon; ???????????Synchronize(ShowDraw); ???????????sleep(FDelay); ?????????end; ?????????//==========demo?end============ ?????????result?:=?true???????end?????else?????begin???????Q[n]?:=?0; ???????if?QSeek(n?-?1)?then?????????result?:=?Qseek(n) ???????else?????????result?:=?false; ?????end; ???end???else?????result?:=?false; ?end; ??function?TQueenThread.QSeekNonrecursion(n:?integer):?boolean; ?var ???flag:?boolean; ???m:?integer; ?begin???m?:=?n; ???flag?:=?false; ???repeat ?????//==========demo?begin========== ?????if?FDemo?then?????begin???????FQueen?:=?n; ???????Synchronize(ShowDelete); ?????end; ?????//==========demo?end============ ?????inc(Q[n]); ?????//==========demo?begin========== ?????if?FDemo?then?????begin???????FSeekQueenIcon?:=?FSeekIcon; ???????Synchronize(ShowDraw); ???????sleep(FDelay); ?????end; ?????//==========demo?end============ ?????if?Q[n]?>?8?then?????begin???????Q[n]?:=?0; ???????dec(n); ?????end?????else???????if?not?QClash(n)?then???????begin?????????//==========demo?begin========== ?????????if?FDemo?then?????????begin???????????Synchronize(ShowDelete); ???????????FSeekQueenIcon?:=?FQueenIcon; ???????????Synchronize(ShowDraw); ???????????sleep(FDelay); ?????????end; ?????????//==========demo?end============ ?????????if?m?=?n?then???????????flag?:=?true?????????else???????????inc(n); ???????end???????else?????????//==========demo?begin========== ?????????if?FDemo?then?????????begin???????????FClashRestoreIcon?:=?FClashIcon; ???????????Synchronize(ShowClashRestore); ???????????sleep(FDelay); ???????????FClashRestoreIcon?:=?FQueenIcon; ???????????Synchronize(ShowClashRestore); ?????????end; ?????????//==========demo?end============ ???until?flag?or?(n?<?1); ???result?:=?flag; ?end; ??function?TQueenThread.QClash(n:?integer):?boolean; ?var ???flag:?boolean; ???i:?integer; ?begin???flag?:=?false; ???i?:=?1; ???while?(i?<?n)?and?not?flag?do ???begin?????flag?:=?(Q[n]?=?Q[i])?or?(Abs(Q[n]?-?Q[i])?=?(n?-?i)); ?????inc(i); ???end; ???result?:=?flag; ?end; ??procedure?TQueenThread.Execute; ?var ???i:?integer; ?begin???for?i?:=?1?to?7?do ?????QS(i); ???while?QS(8)?do ???begin?????if?FDemo?then???????Beep ?????else???????Synchronize(ShowResult); ?????inc(FCounter); ?????PostMessage(Form1.Handle,?WM_SEEKSUSPEND,?0,?0); ?????Suspend; ???end; ?end; ??end.? ??? 這個程序雖然是一個教學軟件,但涉及到許多方面的知識,比如Win32下的圖像處理、多線程等等。這里并沒有使用信號量,而是使用了用戶自定義消息來完成多線程的同步、等待、掛起等操作。
下面是另一個Unit的源碼:?
unit?Unit1; ??interface ??uses ???Windows,?Messages,?SysUtils,?Variants,?Classes,?Graphics,?Controls,?Forms, ???Dialogs,?StdCtrls,?ExtCtrls,?ImgList,?ComCtrls; ??const ???WM_SEEKFINISH?=?WM_USER?+?$1; ???WM_SEEKSUSPEND?=?WM_USER?+?$2; ???CellWidth?=?50; ???CellHeight?=?50; ??type ???TForm1?=?class(TForm) ?????GroupBox1:?TGroupBox; ?????GroupBox2:?TGroupBox; ?????GroupBox3:?TGroupBox; ?????GroupBox4:?TGroupBox; ?????GroupBox5:?TGroupBox; ?????GroupBox6:?TGroupBox; ?????Panel1:?TPanel; ?????Image1:?TImage; ?????Label1:?TLabel; ?????Label2:?TLabel; ?????Label3:?TLabel; ?????Label4:?TLabel; ?????Label5:?TLabel; ?????CheckBox1:?TCheckBox; ?????CheckBox2:?TCheckBox; ?????TrackBar1:?TTrackBar; ?????ComboBox1:?TComboBox; ?????ComboBox2:?TComboBox; ?????ListBox1:?TListBox; ?????Button1:?TButton; ?????ImageList1:?TImageList; ?????procedure?FormCreate(Sender:?TObject); ?????procedure?FormDestroy(Sender:?TObject); ?????procedure?Button1Click(Sender:?TObject); ?????procedure?CheckBox1Click(Sender:?TObject); ?????procedure?CheckBox2Click(Sender:?TObject); ?????procedure?TrackBar1Change(Sender:?TObject); ?????procedure?ComboBox1Change(Sender:?TObject); ?????procedure?ComboBox2Change(Sender:?TObject); ?????procedure?ListBox1DblClick(Sender:?TObject); ???private ?????BG:?TBitmap; ?????QIcon,?SIcon,?CIcon:?TIcon; ?????QResult:?array?of?array[1..8]?of?integer; ?????RunFlag:?boolean; ???public?????procedure?MsgSeekSuspend(var?Msg:?TMessage);?message?WM_SEEKSUSPEND; ?????procedure?MsgSeekFinish(var?Msg:?TMessage);?message?WM_SEEKFINISH; ???end; ??var ???Form1:?TForm1; ???Q:?array[1..8]?of?integer; ??implementation ??{$R?*.dfm} ??uses?Unit2; ??var ???QueenThread:?TQueenThread; ???CurrentResultIndex:?integer; ??procedure?TForm1.MsgSeekSuspend(var?Msg:?TMessage); ?var ???i:?integer; ?begin???CurrentResultIndex?:=?high(QResult)?+?1; ???setlength(QResult,?CurrentResultIndex?+?1); ???for?i?:=?1?to?8?do ?????QResult[CurrentResultIndex,?i]?:=?Q[i]; ???with?ListBox1?do ???begin?????Items.Add(format('%u,?%u,?%u,?%u,?%u,?%u,?%u,?%u?[%u]',?[Q[1],?Q[2],?Q[3],?Q[4],?Q[5],?Q[6],?Q[7],?Q[8],?CurrentResultIndex?+?1])); ?????ItemIndex?:=?Count?-?1; ???end; ???RunFlag?:=?false; ???Button1.Caption?:=?'&Seek'; ?end; ??procedure?TForm1.MsgSeekFinish(var?Msg:?TMessage); ?begin???MessageBox(Handle,?'End?of?seek.'+?#13#10#13#10?+?'Restart?seek?from?first?queen.',?PWChar(Caption),?MB_ICONINFORMATION?or?MB_OK); ???ListBox1.Clear; ???Image1.Canvas.Draw(0,?0,?BG); ???QueenThread?:=?nil; ???CurrentResultIndex?:=?-1; ???setlength(QResult,?0); ???Button1.Caption?:=?'&Seek'; ?end; ??procedure?TForm1.Button1Click(Sender:?TObject); ?var ???i:?integer; ?begin???if?not?Assigned(QueenThread)?then???begin?????QueenThread?:=?TQueenThread.Create(BG,?QIcon,?SIcon,?CIcon,?Image1.Canvas); ?????QueenThread.Demo?:=?CheckBox1.Checked; ?????QueenThread.Delay?:=?TrackBar1.Position; ?????QueenThread.Recursion?:=?CheckBox2.Checked; ???end; ???if?QueenThread.Suspended?then???begin?????with?ListBox1?do ?????begin???????if?(CurrentResultIndex?<>?high(QResult))?and?not?RunFlag?then???????begin?????????for?i?:=?1?to?8?do ???????????Q[i]?:=?QResult[high(QResult),?i]; ?????????QueenThread.ShowResult; ???????end; ???????ItemIndex?:=?Count?-?1; ?????end; ?????QueenThread.Resume; ?????Button1.Caption?:=?'&Pause'; ???end???else???begin?????QueenThread.Suspend; ?????Button1.Caption?:=?'&Resume'; ???end; ???RunFlag?:=?true; ?end; ??procedure?TForm1.CheckBox1Click(Sender:?TObject); ?begin???TrackBar1.Enabled?:=?CheckBox1.Checked; ???if?Assigned(QueenThread)?then?????QueenThread.Demo?:=?CheckBox1.Checked; ?end; ??procedure?TForm1.CheckBox2Click(Sender:?TObject); ?begin???if?Assigned(QueenThread)?then?????QueenThread.Recursion?:=?CheckBox2.Checked; ?end; ??procedure?TForm1.ComboBox1Change(Sender:?TObject); ?var ???n:?integer; ?begin???n?:=??+?ComboBox1.ItemIndex?*?3; ???ImageList1.GetIcon(0?+?n,?QIcon); ???ImageList1.GetIcon(1?+?n,?SIcon); ???ImageList1.GetIcon(2?+?n,?CIcon); ???if?Assigned(QueenThread)?then?????QueenThread.ShowResult; ?end; ??procedure?TForm1.ComboBox2Change(Sender:?TObject); ?begin???BG.LoadFromResourceName(hInstance,?'BG'?+?IntToStr(ComboBox2.ItemIndex?+?1)); ???if?Assigned(QueenThread)?then?????QueenThread.ShowResult ???else?????Image1.Canvas.Draw(0,?0,?BG); ?end; ??procedure?TForm1.TrackBar1Change(Sender:?TObject); ?begin???if?Assigned(QueenThread)?then?????QueenThread.Delay?:=?TrackBar1.Position; ?end; ??procedure?TForm1.ListBox1DblClick(Sender:?TObject); ?var ???i:?integer; ?begin???if?Assigned(QueenThread)?and?not?RunFlag?then???begin?????CurrentResultIndex?:=?ListBox1.ItemIndex; ?????for?i?:=?1?to?8?do ???????Q[i]?:=?QResult[CurrentResultIndex,?i]; ?????QueenThread.ShowResult; ???end; ?end; ??procedure?TForm1.FormCreate(Sender:?TObject); ?var ???i:?integer; ?begin???for?i?:=?1?to?8?do ?????Q[i]?:=?0; ???BG?:=?TBitmap.Create; ???QIcon?:=?TIcon.Create; ???SIcon?:=?TIcon.Create; ???CIcon?:=?TIcon.Create; ???ComboBox1Change(self); ???ComboBox2Change(self); ???CurrentResultIndex?:=?-1; ?end; ??procedure?TForm1.FormDestroy(Sender:?TObject); ?begin???BG.Free; ???QIcon.Free; ???SIcon.Free; ???CIcon.Free; ?end; ??end.? ??? 可以從后面的附件或者如下鏈接下載完整的源碼項目(包含一個編譯好的可執行文件):
http://mengliao.blog.51cto.com/p_w_upload/201101/876134_1293891480.rar
轉載于:https://blog.51cto.com/mengliao/470620
總結
以上是生活随笔為你收集整理的八皇后问题求解动态图形演示的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。