經典面試問題:12小球問題演算法(原始碼)
(文件請參考:http://blog.csdn.net/CXXSoft/archive/2006/09/28/1299731.aspx)
3、 執行效果
4、 演算法原始碼
...{
作品名稱: 小球問題通用解決方案
開發作者: 成曉旭
開發時間: 2003年01月22日
完成時間: 2003年01月23日
修改時間1: 2003年11月14日
增加使用者問題條件設定繪製方法
修改時間2: 2003年11月18日
增加比較過程的記錄功能
}
unit Common;
interface
uses
Windows,SysUtils,Classes,Graphics,BallType;
//清除畫面方法
procedure ClearCanvas(aCanvas: TCanvas; aRect: TRect);
//小球問題條件設定方法
procedure Draw_Ball_Config(
AllBall:array of TC_Ball;
ACanvas:TCanvas;
aClearRect: TRect;
bShowTrace:Boolean);
//小球問題解決方法
procedure Serach_Error_Ball(
AllBall:array of TC_Ball;
ACanvas:TCanvas;
aClearRect: TRect;
bShowTrace:Boolean);
var
strLog1:AnsiString;
strLog2:AnsiString;
strLog3:AnsiString;
implementation
//單元內部常量定義
const
Fir_Pivot_X = 200;
Fir_Pivot_Y = 80;
Hint_X = 10;
One_DrawDelta = 140;
One_PreDelta = 70;
One_FroDelta = 30;
strADyB = '比較:A端(重) > B端(輕)' + CHR(13) + CHR(10);
strAXDB = '比較:A端 = B端' + CHR(13) + CHR(10);
strAXyB = '比較:A端(輕) ' + CHR(13) + CHR(10);
A_Team = 'A 組:';
B_Team = 'B 組:';
preTail0 = '號球' + CHR(13) + CHR(10);
preTail1 = '號球';
proHead = '結論:異常球在 [';
lastResult = '結論:異常球是';
nextHint = CHR(13) + CHR(10) + '啟示:';
ErrorHint = '命題不嚴密,請檢查設定條件!';
function SearchBall_At4(AllBall:array of TC_Ball;
A,G:array of Byte;var vErr_Ball_Order:Byte;
var vIsHeavy:Boolean;ACanvas:TCanvas;bShowTrace:Boolean):Boolean;
var
A2,B2:Word;
A3,B3:Word;
Loop:Word;
bNumber:Byte;
bPartA,bPartB:array of TC_Ball;
bCmpPara:TC_CmpPara;
str:AnsiString;
begin
vErr_Ball_Order := 0;
vIsHeavy := False;
A2 := AllBall[A[1]].Weight + AllBall[A[2]].Weight + AllBall[G[1]].Weight;
B2 := AllBall[A[3]].Weight + AllBall[G[2]].Weight + AllBall[G[3]].Weight;
str := A_Team + IntToStr(AllBall[A[1]].Order) + ','
+ IntToStr(AllBall[A[2]].Order) + ','
+ IntToStr(AllBall[G[1]].Order);
str := str + preTail0;
strLog2 := strLog2 + str;
str := B_Team + IntToStr(AllBall[A[3]].Order) + ','
+ IntToStr(AllBall[G[2]].Order) + ','
+ IntToStr(AllBall[G[3]].Order);
str := str + preTail0;
strLog2 := strLog2 + str;
bNumber := 3;
SetLength(bPartA,bNumber);
SetLength(bPartB,bNumber);
bPartA[0] := AllBall[A[1]];
bPartA[1] := AllBall[A[2]];
bPartA[2] := AllBall[G[1]];
bPartB[0] := AllBall[A[3]];
bPartB[1] := AllBall[G[2]];
bPartB[2] := AllBall[G[3]];
Balance_One_Compare(Point(Fir_Pivot_X,Fir_Pivot_Y + One_DrawDelta),
bNumber,bPartA,bPartB,ACanvas,bShowTrace);
if A2 = B2 then
begin
A3 := AllBall[A[4]].Weight;
B3 := AllBall[G[1]].Weight;
strLog2 := strLog2 + strAXDB;
str := proHead;
str := str + IntToStr(AllBall[A[4]].Order);
str := str + ']' + preTail1 + ' 【排3餘1】';
strLog2 := strLog2 + str;
str := '用任一正常球與之比較,即可知異常球是偏輕偏重!';
strLog2 := strLog2 + nextHint + str;
with bCmpPara do
begin
Pre_LNumber := 4;
Fro_LNumber := 1;
SetLength(Pre_Latency,Pre_LNumber);
SetLength(Fro_Latency,Fro_LNumber);
for Loop := 0 to Pre_LNumber - 1 do
Pre_Latency[Loop] := AllBall[Loop + 9];
Fro_Latency[0] := AllBall[A[4]];
end;
Balance_One_Latency(Point(Hint_X,Fir_Pivot_Y + One_DrawDelta - One_PreDelta),
Point(Hint_X,Fir_Pivot_Y + One_DrawDelta + One_FroDelta),
bCmpPara,ACanvas,bShowTrace);
bNumber := 1;
SetLength(bPartA,bNumber);
SetLength(bPartB,bNumber);
bPartA[0] := AllBall[A[4]];
bPartB[0] := AllBall[G[1]];
Balance_One_Compare(Point(Fir_Pivot_X,Fir_Pivot_Y + One_DrawDelta * 2),
bNumber,bPartA,bPartB,ACanvas,bShowTrace);
if A3 = B3 then
begin
vErr_Ball_Order := 0;
strLog3 := '異常球與正常球一樣重!' + ErrorHint;
end
else
begin
vErr_Ball_Order := A[4];
vIsHeavy := A3 > B3;
end;
end
else
begin
A3 := AllBall[A[1]].Weight;
B3 := AllBall[A[2]].Weight;
if A2 > B2 then
strLog2 := strLog2 + strADYB
else
strLog2 := strLog2 + strAXYB;
str := proHead;
str := str + IntToStr(AllBall[A[1]].Order) + ','
+ IntToStr(AllBall[A[2]].Order) + ','
+ IntToStr(AllBall[A[3]].Order);
str := str + ']' + preTail1 + ' 【排1餘3】';
strLog2 := strLog2 + str;
str := '下一輪必須在本輪比較的同一端的兩球中進行.即取:'
+IntToStr(AllBall[A[1]].Order) + ','
+ IntToStr(AllBall[A[2]].Order)
+'號球,在推算結果時,還必須用到此輪A、B端誰輕誰重!';
strLog2 := strLog2 + nextHint + str;
bNumber := 1;
SetLength(bPartA,bNumber);
SetLength(bPartB,bNumber);
bPartA[0] := AllBall[A[1]];
bPartB[0] := AllBall[A[2]];
Balance_One_Compare(Point(Fir_Pivot_X,Fir_Pivot_Y + One_DrawDelta * 2),
bNumber,bPartA,bPartB,ACanvas,bShowTrace);
if A3 = B3 then
begin
vErr_Ball_Order := A[3];
vIsHeavy := A2 < B2;
end
else
begin
if A2 > B2 then
begin
if A3 > B3 then
vErr_Ball_Order := A[1]
else
vErr_Ball_Order := A[2];
//IsHeavy := True;
end
else
begin
if A3 > B3 then
vErr_Ball_Order := A[2]
else
vErr_Ball_Order := A[1];
//IsHeavy := NOT True;
end;
vIsHeavy := A2 > B2;
end;
end;
Result := vErr_Ball_Order <> 0;
end;
function SearchBall_At8(AllBall:array of TC_Ball;IsAdyB:Boolean;
A,B,G:array of Byte;var vErr_Ball_Order:Byte;
var vIsHeavy:Boolean;ACanvas:TCanvas;bShowTrace:Boolean):Boolean;
var
A2,B2:Word;
A3,B3:Word;
bNumber:Byte;
bPartA,bPartB:array of TC_Ball;
senPivot,thrPivot:TPoint;
str:AnsiString;
begin
vErr_Ball_Order := 0;
vIsHeavy := False;
A2 := AllBall[A[1]].Weight + AllBall[A[2]].Weight + AllBall[B[1]].Weight;
B2 := AllBall[A[3]].Weight + AllBall[B[2]].Weight + AllBall[G[1]].Weight;
str := A_Team + IntToStr(AllBall[A[1]].Order) + ','
+ IntToStr(AllBall[A[2]].Order) + ','
+ IntToStr(AllBall[B[1]].Order);
str := str + preTail0;
strLog2 := strLog2 + str;
str := B_Team + IntToStr(AllBall[A[3]].Order) + ','
+ IntToStr(AllBall[B[2]].Order) + ','
+ IntToStr(AllBall[G[1]].Order);
str := str + preTail0;
strLog2 := strLog2 + str;
bNumber := 3;
SetLength(bPartA,bNumber);
SetLength(bPartB,bNumber);
bPartA[0] := AllBall[A[1]];
bPartA[1] := AllBall[A[2]];
bPartA[2] := AllBall[B[1]];
bPartB[0] := AllBall[A[3]];
bPartB[1] := AllBall[B[2]];
bPartB[2] := AllBall[G[1]];
Balance_One_Compare(Point(Fir_Pivot_X,Fir_Pivot_Y + One_DrawDelta),
bNumber,bPartA,bPartB,ACanvas,bShowTrace);
if A2 = B2 then
begin
A3 := AllBall[B[3]].Weight;
B3 := AllBall[B[4]].Weight;
strLog2 := strLog2 + strAXDB;
str := proHead;
str := str + IntToStr(AllBall[A[4]].Order) + ','
+ IntToStr(AllBall[B[3]].Order) + ','
+ IntToStr(AllBall[B[4]].Order);
str := str + ']' + preTail1 + ' 【排5餘3】';
strLog2 := strLog2 + str;
str := '下一輪必須在本輪比較的同一端的兩球中進行.即取:'
+IntToStr(AllBall[B[3]].Order) + ','
+ IntToStr(AllBall[B[4]].Order)
+'號球,在推算結果時,還必須用到此輪A、B端誰輕誰重!';
strLog2 := strLog2 + nextHint + str;
bNumber := 1;
SetLength(bPartA,bNumber);
SetLength(bPartB,bNumber);
bPartA[0] := AllBall[B[3]];
bPartB[0] := AllBall[B[4]];
Balance_One_Compare(Point(Fir_Pivot_X,Fir_Pivot_Y + One_DrawDelta * 2),
bNumber,bPartA,bPartB,ACanvas,bShowTrace);
if A3 = B3 then
begin
vErr_Ball_Order := A[4];
vIsHeavy := IsAdyB;
end
else
begin
if IsAdyB then
begin
if A3 > B3 then
vErr_Ball_Order := B[4]
else
vErr_Ball_Order := B[3];
//IsHeavy := NOT IsAdyB;
end
else
begin
if A3 > B3 then
vErr_Ball_Order := B[3]
else
vErr_Ball_Order := B[4];
//IsHeavy := NOT IsAdyB;
end;
vIsHeavy := NOT IsAdyB;
end;
end
else
begin
if A2 > B2 then
strLog2 := strLog2 + strADYB
else
strLog2 := strLog2 + strAXYB;
str := proHead;
str := str + IntToStr(AllBall[A[1]].Order) + ','
+ IntToStr(AllBall[A[2]].Order) + ','
+ IntToStr(AllBall[A[3]].Order) + ','
+ IntToStr(AllBall[B[1]].Order) + ','
+ IntToStr(AllBall[B[2]].Order);
str := str + ']' + preTail1 + ' 【排3餘5】';
strLog2 := strLog2 + str;
str := '此時,必須綜合分析近兩次的比較結果.當近兩次比較的天平傾向相同時,'
+ '必須比較共同產生傾向因素的兩個球;傾向相反時,'
+ '任取一個正常球與A組第3個球('
+ IntToStr(AllBall[A[2]].Order)
+ ')或B組第1個球('
+ IntToStr(AllBall[B[1]].Order)
+ ')比較.';
strLog2 := strLog2 + nextHint + str;
if ((IsAdyB = True) and (A2 > B2)) or ((IsAdyB = False) and (A2 < B2)) then
begin
A3 := AllBall[A[1]].Weight;
B3 := AllBall[A[2]].Weight;
bNumber := 1;
SetLength(bPartA,bNumber);
SetLength(bPartB,bNumber);
bPartA[0] := AllBall[A[1]];
bPartB[0] := AllBall[A[2]];
Balance_One_Compare(Point(Fir_Pivot_X,Fir_Pivot_Y + One_DrawDelta * 2),
bNumber,bPartA,bPartB,ACanvas,bShowTrace);
if A3 = B3 then
begin
vErr_Ball_Order := B[2];
vIsHeavy := NOT IsAdyB;
end
else if A2 > B2 then
begin
if A3 > B3 then
vErr_Ball_Order := A[1]
else
vErr_Ball_Order := A[2];
vIsHeavy := IsAdyB;
end
else if A2 < B2 then
begin
if A3 > B3 then
vErr_Ball_Order := A[2]
else
vErr_Ball_Order := A[1];
vIsHeavy := IsAdyB;
end;
end
else if ((IsAdyB = True) and (A2 < B2)) or ((IsAdyB = False) and (A2 > B2)) then
begin
A3 := AllBall[A[3]].Weight;
B3 := AllBall[G[1]].Weight;
bNumber := 1;
SetLength(bPartA,bNumber);
SetLength(bPartB,bNumber);
bPartA[0] := AllBall[A[1]];
bPartB[0] := AllBall[G[1]];
Balance_One_Compare(Point(Fir_Pivot_X,Fir_Pivot_Y + One_DrawDelta * 2),
bNumber,bPartA,bPartB,ACanvas,bShowTrace);
if A3 = B3 then
begin
vErr_Ball_Order := B[1];
vIsHeavy := NOT IsAdyB;
end
else if A3 > B3 then
begin
if IsAdyB then
begin
vErr_Ball_Order := A[3];
vIsHeavy := IsAdyB;
end
else
begin
vErr_Ball_Order := 0;
strLog3 := '"偏輕"的異常球 > 正常球!' + ErrorHint;
end;
end
else
begin
if IsAdyB then
begin
vErr_Ball_Order := 0;
strLog3 := '"偏重"的異常球 ' + ErrorHint;
end
else
begin
vErr_Ball_Order := A[3];
vIsHeavy := IsAdyB;
end
end;
end;
end;
Result := vErr_Ball_Order <> 0;
end;
procedure Serach_Error_Ball(
AllBall:array of TC_Ball;
ACanvas:TCanvas;aClearRect: TRect;
bShowTrace:Boolean);
var
A,B:Word;
Loop:Word;
BufC:array[0..4] of Byte;
BufT:array[0..8] of Byte;
BufA,BufB:array[0..4] of Byte;
BufG:array[0..4] of Byte;
bOrder:Byte;
bHeavy:Boolean;
FoundBall :TC_SearchBall;
str:AnsiString;
bNumber:Byte;
bPartA,bPartB:array of TC_Ball;
bCmpPara:TC_CmpPara;
begin
A := 0;
strLog1 := '';
strLog2 := '';
strLog3 := '';
ClearCanvas(aCanvas,aClearRect);
str := A_Team;
for Loop := 1 to 4 do
begin
A := A + AllBall[Loop].Weight;
str := str + IntToStr(AllBall[Loop].Order) + ',';
//bPartA[Loop] := AllBall[Loop];
end;
str := str + preTail0;
strLog1 := strLog1 + str;
B := 0;
str := B_Team;
for Loop := 5 to 8 do
begin
B := B + AllBall[Loop].Weight;
str := str + IntToStr(AllBall[Loop].Order) + ',';
//bPartB[Loop] := AllBall[Loop];
end;
str := str + preTail0;
strLog1 := strLog1 + str;
bNumber := 4;
SetLength(bPartA,bNumber);
SetLength(bPartB,bNumber);
for Loop := 0 to bNumber - 1 do
begin
bPartA[Loop] := AllBall[Loop+1];
bPartB[Loop] := AllBall[Loop+bNumber + 1];
end;
Balance_One_Compare(Point(Fir_Pivot_X,Fir_Pivot_Y),
bNumber,bPartA,bPartB,ACanvas,bShowTrace);
if A = B then
begin
strLog1 := strLog1 + strAXDB;
str := proHead;
for Loop := 1 to 4 do
begin
BufC[Loop] := AllBall[8 + Loop].Order;
str := str + IntToStr(AllBall[8 + Loop].Order) + ',';
end;
str := str + '] ' + preTail1 + ' 【排8餘4】';
strLog1 := strLog1 + str;
for Loop := 1 to 8 do
BufT[Loop] := AllBall[Loop].Order;
with bCmpPara do
begin
Pre_LNumber := 12;
Fro_LNumber := 4;
SetLength(Pre_Latency,Pre_LNumber);
SetLength(Fro_Latency,Fro_LNumber);
for Loop := 0 to Pre_LNumber - 1 do
Pre_Latency[Loop] := AllBall[Loop + 1];
for Loop := 0 to Fro_LNumber - 1 do
Fro_Latency[Loop] := AllBall[Loop + 9];
end;
Balance_One_Latency(Point(10,Fir_Pivot_Y - One_PreDelta),Point(10,Fir_Pivot_Y + One_FroDelta),
bCmpPara,ACanvas,bShowTrace);
if SearchBall_At4(AllBall,BufC,BufT,bOrder,bHeavy,ACanvas,bShowTrace) then
begin
FoundBall.Ball := AllBall[bOrder];
FoundBall.IsHeavy := bHeavy;
if FoundBall.IsHeavy then
FoundBall.ErrorMsg := '【偏重】'
else
FoundBall.ErrorMsg := '【偏輕】';
str := '【'+ IntToStr(FoundBall.Ball.Order) + '】 = '
+ IntToStr(FoundBall.Ball.Weight) + ' ' + FoundBall.ErrorMsg;
strLog3 := lastResult + str;
end;
end
else
begin
if A > B then
strLog1 := strLog1 + strADYB
else
strLog1 := strLog1 + strAXYB;
str := proHead;
for Loop := 1 to 8 do
str := str + IntToStr(AllBall[Loop].Order) + ',';
str := str + '] ' + preTail1 + '【排4餘8】';
strLog1 := strLog1 + str;
for Loop := 1 to 4 do
begin
BufA[Loop] := AllBall[Loop].Order;
BufB[Loop] := AllBall[4 + Loop].Order;
BufG[Loop] := AllBall[8 + Loop].Order;
end;
with bCmpPara do
begin
Pre_LNumber := 12;
Fro_LNumber := 4;
SetLength(Pre_Latency,Pre_LNumber);
SetLength(Fro_Latency,Fro_LNumber);
for Loop := 0 to Pre_LNumber - 1 do
Pre_Latency[Loop] := AllBall[Loop + 1];
for Loop := 0 to Fro_LNumber - 1 do
Fro_Latency[Loop] := AllBall[Loop + 9];
end;
Balance_One_Latency(Point(Hint_X,Fir_Pivot_Y - One_PreDelta),Point(10,Fir_Pivot_Y + One_FroDelta),
bCmpPara,ACanvas,bShowTrace);
if SearchBall_At8(AllBall,A > B,BufA,BufB,BufG,bOrder,bHeavy,ACanvas,bShowTrace) then
begin
FoundBall.Ball := AllBall[bOrder];
FoundBall.IsHeavy := bHeavy;
if FoundBall.IsHeavy then
FoundBall.ErrorMsg := '【偏重】'
else
FoundBall.ErrorMsg := '【偏輕】';
str := '【'+ IntToStr(FoundBall.Ball.Order) + '】 = '
+ IntToStr(FoundBall.Ball.Weight) + ' ' + FoundBall.ErrorMsg;
strLog3 := lastResult + str;
end;
end;
//MessageBox(0,PChar(Str),'小球問題',MB_OK or MB_IConInformation);
end;
procedure Draw_Ball_Config(
AllBall:array of TC_Ball;
ACanvas:TCanvas;
aClearRect: TRect;
bShowTrace:Boolean);
begin
ClearCanvas(aCanvas,aClearRect);
Process_Initial_Ball(
Point(0,Fir_Pivot_Y - One_PreDelta-10),
AllBall,ACanvas,bShowTrace);
end;
procedure ClearCanvas(aCanvas: TCanvas; aRect: TRect);
begin
with aCanvas do
begin
Brush.Style := bsSolid;
Brush.Color := clWhite;
FillRect(aRect);
end;
end;
end.
作品名稱: 小球問題通用解決方案
開發作者: 成曉旭
開發時間: 2003年01月22日
完成時間: 2003年01月23日
修改時間1: 2003年11月14日
增加使用者問題條件設定繪製方法
修改時間2: 2003年11月18日
增加比較過程的記錄功能
}
unit Common;
interface
uses
Windows,SysUtils,Classes,Graphics,BallType;
//清除畫面方法
procedure ClearCanvas(aCanvas: TCanvas; aRect: TRect);
//小球問題條件設定方法
procedure Draw_Ball_Config(
AllBall:array of TC_Ball;
ACanvas:TCanvas;
aClearRect: TRect;
bShowTrace:Boolean);
//小球問題解決方法
procedure Serach_Error_Ball(
AllBall:array of TC_Ball;
ACanvas:TCanvas;
aClearRect: TRect;
bShowTrace:Boolean);
var
strLog1:AnsiString;
strLog2:AnsiString;
strLog3:AnsiString;
implementation
//單元內部常量定義
const
Fir_Pivot_X = 200;
Fir_Pivot_Y = 80;
Hint_X = 10;
One_DrawDelta = 140;
One_PreDelta = 70;
One_FroDelta = 30;
strADyB = '比較:A端(重) > B端(輕)' + CHR(13) + CHR(10);
strAXDB = '比較:A端 = B端' + CHR(13) + CHR(10);
strAXyB = '比較:A端(輕) ' + CHR(13) + CHR(10);
A_Team = 'A 組:';
B_Team = 'B 組:';
preTail0 = '號球' + CHR(13) + CHR(10);
preTail1 = '號球';
proHead = '結論:異常球在 [';
lastResult = '結論:異常球是';
nextHint = CHR(13) + CHR(10) + '啟示:';
ErrorHint = '命題不嚴密,請檢查設定條件!';
function SearchBall_At4(AllBall:array of TC_Ball;
A,G:array of Byte;var vErr_Ball_Order:Byte;
var vIsHeavy:Boolean;ACanvas:TCanvas;bShowTrace:Boolean):Boolean;
var
A2,B2:Word;
A3,B3:Word;
Loop:Word;
bNumber:Byte;
bPartA,bPartB:array of TC_Ball;
bCmpPara:TC_CmpPara;
str:AnsiString;
begin
vErr_Ball_Order := 0;
vIsHeavy := False;
A2 := AllBall[A[1]].Weight + AllBall[A[2]].Weight + AllBall[G[1]].Weight;
B2 := AllBall[A[3]].Weight + AllBall[G[2]].Weight + AllBall[G[3]].Weight;
str := A_Team + IntToStr(AllBall[A[1]].Order) + ','
+ IntToStr(AllBall[A[2]].Order) + ','
+ IntToStr(AllBall[G[1]].Order);
str := str + preTail0;
strLog2 := strLog2 + str;
str := B_Team + IntToStr(AllBall[A[3]].Order) + ','
+ IntToStr(AllBall[G[2]].Order) + ','
+ IntToStr(AllBall[G[3]].Order);
str := str + preTail0;
strLog2 := strLog2 + str;
bNumber := 3;
SetLength(bPartA,bNumber);
SetLength(bPartB,bNumber);
bPartA[0] := AllBall[A[1]];
bPartA[1] := AllBall[A[2]];
bPartA[2] := AllBall[G[1]];
bPartB[0] := AllBall[A[3]];
bPartB[1] := AllBall[G[2]];
bPartB[2] := AllBall[G[3]];
Balance_One_Compare(Point(Fir_Pivot_X,Fir_Pivot_Y + One_DrawDelta),
bNumber,bPartA,bPartB,ACanvas,bShowTrace);
if A2 = B2 then
begin
A3 := AllBall[A[4]].Weight;
B3 := AllBall[G[1]].Weight;
strLog2 := strLog2 + strAXDB;
str := proHead;
str := str + IntToStr(AllBall[A[4]].Order);
str := str + ']' + preTail1 + ' 【排3餘1】';
strLog2 := strLog2 + str;
str := '用任一正常球與之比較,即可知異常球是偏輕偏重!';
strLog2 := strLog2 + nextHint + str;
with bCmpPara do
begin
Pre_LNumber := 4;
Fro_LNumber := 1;
SetLength(Pre_Latency,Pre_LNumber);
SetLength(Fro_Latency,Fro_LNumber);
for Loop := 0 to Pre_LNumber - 1 do
Pre_Latency[Loop] := AllBall[Loop + 9];
Fro_Latency[0] := AllBall[A[4]];
end;
Balance_One_Latency(Point(Hint_X,Fir_Pivot_Y + One_DrawDelta - One_PreDelta),
Point(Hint_X,Fir_Pivot_Y + One_DrawDelta + One_FroDelta),
bCmpPara,ACanvas,bShowTrace);
bNumber := 1;
SetLength(bPartA,bNumber);
SetLength(bPartB,bNumber);
bPartA[0] := AllBall[A[4]];
bPartB[0] := AllBall[G[1]];
Balance_One_Compare(Point(Fir_Pivot_X,Fir_Pivot_Y + One_DrawDelta * 2),
bNumber,bPartA,bPartB,ACanvas,bShowTrace);
if A3 = B3 then
begin
vErr_Ball_Order := 0;
strLog3 := '異常球與正常球一樣重!' + ErrorHint;
end
else
begin
vErr_Ball_Order := A[4];
vIsHeavy := A3 > B3;
end;
end
else
begin
A3 := AllBall[A[1]].Weight;
B3 := AllBall[A[2]].Weight;
if A2 > B2 then
strLog2 := strLog2 + strADYB
else
strLog2 := strLog2 + strAXYB;
str := proHead;
str := str + IntToStr(AllBall[A[1]].Order) + ','
+ IntToStr(AllBall[A[2]].Order) + ','
+ IntToStr(AllBall[A[3]].Order);
str := str + ']' + preTail1 + ' 【排1餘3】';
strLog2 := strLog2 + str;
str := '下一輪必須在本輪比較的同一端的兩球中進行.即取:'
+IntToStr(AllBall[A[1]].Order) + ','
+ IntToStr(AllBall[A[2]].Order)
+'號球,在推算結果時,還必須用到此輪A、B端誰輕誰重!';
strLog2 := strLog2 + nextHint + str;
bNumber := 1;
SetLength(bPartA,bNumber);
SetLength(bPartB,bNumber);
bPartA[0] := AllBall[A[1]];
bPartB[0] := AllBall[A[2]];
Balance_One_Compare(Point(Fir_Pivot_X,Fir_Pivot_Y + One_DrawDelta * 2),
bNumber,bPartA,bPartB,ACanvas,bShowTrace);
if A3 = B3 then
begin
vErr_Ball_Order := A[3];
vIsHeavy := A2 < B2;
end
else
begin
if A2 > B2 then
begin
if A3 > B3 then
vErr_Ball_Order := A[1]
else
vErr_Ball_Order := A[2];
//IsHeavy := True;
end
else
begin
if A3 > B3 then
vErr_Ball_Order := A[2]
else
vErr_Ball_Order := A[1];
//IsHeavy := NOT True;
end;
vIsHeavy := A2 > B2;
end;
end;
Result := vErr_Ball_Order <> 0;
end;
function SearchBall_At8(AllBall:array of TC_Ball;IsAdyB:Boolean;
A,B,G:array of Byte;var vErr_Ball_Order:Byte;
var vIsHeavy:Boolean;ACanvas:TCanvas;bShowTrace:Boolean):Boolean;
var
A2,B2:Word;
A3,B3:Word;
bNumber:Byte;
bPartA,bPartB:array of TC_Ball;
senPivot,thrPivot:TPoint;
str:AnsiString;
begin
vErr_Ball_Order := 0;
vIsHeavy := False;
A2 := AllBall[A[1]].Weight + AllBall[A[2]].Weight + AllBall[B[1]].Weight;
B2 := AllBall[A[3]].Weight + AllBall[B[2]].Weight + AllBall[G[1]].Weight;
str := A_Team + IntToStr(AllBall[A[1]].Order) + ','
+ IntToStr(AllBall[A[2]].Order) + ','
+ IntToStr(AllBall[B[1]].Order);
str := str + preTail0;
strLog2 := strLog2 + str;
str := B_Team + IntToStr(AllBall[A[3]].Order) + ','
+ IntToStr(AllBall[B[2]].Order) + ','
+ IntToStr(AllBall[G[1]].Order);
str := str + preTail0;
strLog2 := strLog2 + str;
bNumber := 3;
SetLength(bPartA,bNumber);
SetLength(bPartB,bNumber);
bPartA[0] := AllBall[A[1]];
bPartA[1] := AllBall[A[2]];
bPartA[2] := AllBall[B[1]];
bPartB[0] := AllBall[A[3]];
bPartB[1] := AllBall[B[2]];
bPartB[2] := AllBall[G[1]];
Balance_One_Compare(Point(Fir_Pivot_X,Fir_Pivot_Y + One_DrawDelta),
bNumber,bPartA,bPartB,ACanvas,bShowTrace);
if A2 = B2 then
begin
A3 := AllBall[B[3]].Weight;
B3 := AllBall[B[4]].Weight;
strLog2 := strLog2 + strAXDB;
str := proHead;
str := str + IntToStr(AllBall[A[4]].Order) + ','
+ IntToStr(AllBall[B[3]].Order) + ','
+ IntToStr(AllBall[B[4]].Order);
str := str + ']' + preTail1 + ' 【排5餘3】';
strLog2 := strLog2 + str;
str := '下一輪必須在本輪比較的同一端的兩球中進行.即取:'
+IntToStr(AllBall[B[3]].Order) + ','
+ IntToStr(AllBall[B[4]].Order)
+'號球,在推算結果時,還必須用到此輪A、B端誰輕誰重!';
strLog2 := strLog2 + nextHint + str;
bNumber := 1;
SetLength(bPartA,bNumber);
SetLength(bPartB,bNumber);
bPartA[0] := AllBall[B[3]];
bPartB[0] := AllBall[B[4]];
Balance_One_Compare(Point(Fir_Pivot_X,Fir_Pivot_Y + One_DrawDelta * 2),
bNumber,bPartA,bPartB,ACanvas,bShowTrace);
if A3 = B3 then
begin
vErr_Ball_Order := A[4];
vIsHeavy := IsAdyB;
end
else
begin
if IsAdyB then
begin
if A3 > B3 then
vErr_Ball_Order := B[4]
else
vErr_Ball_Order := B[3];
//IsHeavy := NOT IsAdyB;
end
else
begin
if A3 > B3 then
vErr_Ball_Order := B[3]
else
vErr_Ball_Order := B[4];
//IsHeavy := NOT IsAdyB;
end;
vIsHeavy := NOT IsAdyB;
end;
end
else
begin
if A2 > B2 then
strLog2 := strLog2 + strADYB
else
strLog2 := strLog2 + strAXYB;
str := proHead;
str := str + IntToStr(AllBall[A[1]].Order) + ','
+ IntToStr(AllBall[A[2]].Order) + ','
+ IntToStr(AllBall[A[3]].Order) + ','
+ IntToStr(AllBall[B[1]].Order) + ','
+ IntToStr(AllBall[B[2]].Order);
str := str + ']' + preTail1 + ' 【排3餘5】';
strLog2 := strLog2 + str;
str := '此時,必須綜合分析近兩次的比較結果.當近兩次比較的天平傾向相同時,'
+ '必須比較共同產生傾向因素的兩個球;傾向相反時,'
+ '任取一個正常球與A組第3個球('
+ IntToStr(AllBall[A[2]].Order)
+ ')或B組第1個球('
+ IntToStr(AllBall[B[1]].Order)
+ ')比較.';
strLog2 := strLog2 + nextHint + str;
if ((IsAdyB = True) and (A2 > B2)) or ((IsAdyB = False) and (A2 < B2)) then
begin
A3 := AllBall[A[1]].Weight;
B3 := AllBall[A[2]].Weight;
bNumber := 1;
SetLength(bPartA,bNumber);
SetLength(bPartB,bNumber);
bPartA[0] := AllBall[A[1]];
bPartB[0] := AllBall[A[2]];
Balance_One_Compare(Point(Fir_Pivot_X,Fir_Pivot_Y + One_DrawDelta * 2),
bNumber,bPartA,bPartB,ACanvas,bShowTrace);
if A3 = B3 then
begin
vErr_Ball_Order := B[2];
vIsHeavy := NOT IsAdyB;
end
else if A2 > B2 then
begin
if A3 > B3 then
vErr_Ball_Order := A[1]
else
vErr_Ball_Order := A[2];
vIsHeavy := IsAdyB;
end
else if A2 < B2 then
begin
if A3 > B3 then
vErr_Ball_Order := A[2]
else
vErr_Ball_Order := A[1];
vIsHeavy := IsAdyB;
end;
end
else if ((IsAdyB = True) and (A2 < B2)) or ((IsAdyB = False) and (A2 > B2)) then
begin
A3 := AllBall[A[3]].Weight;
B3 := AllBall[G[1]].Weight;
bNumber := 1;
SetLength(bPartA,bNumber);
SetLength(bPartB,bNumber);
bPartA[0] := AllBall[A[1]];
bPartB[0] := AllBall[G[1]];
Balance_One_Compare(Point(Fir_Pivot_X,Fir_Pivot_Y + One_DrawDelta * 2),
bNumber,bPartA,bPartB,ACanvas,bShowTrace);
if A3 = B3 then
begin
vErr_Ball_Order := B[1];
vIsHeavy := NOT IsAdyB;
end
else if A3 > B3 then
begin
if IsAdyB then
begin
vErr_Ball_Order := A[3];
vIsHeavy := IsAdyB;
end
else
begin
vErr_Ball_Order := 0;
strLog3 := '"偏輕"的異常球 > 正常球!' + ErrorHint;
end;
end
else
begin
if IsAdyB then
begin
vErr_Ball_Order := 0;
strLog3 := '"偏重"的異常球 ' + ErrorHint;
end
else
begin
vErr_Ball_Order := A[3];
vIsHeavy := IsAdyB;
end
end;
end;
end;
Result := vErr_Ball_Order <> 0;
end;
procedure Serach_Error_Ball(
AllBall:array of TC_Ball;
ACanvas:TCanvas;aClearRect: TRect;
bShowTrace:Boolean);
var
A,B:Word;
Loop:Word;
BufC:array[0..4] of Byte;
BufT:array[0..8] of Byte;
BufA,BufB:array[0..4] of Byte;
BufG:array[0..4] of Byte;
bOrder:Byte;
bHeavy:Boolean;
FoundBall :TC_SearchBall;
str:AnsiString;
bNumber:Byte;
bPartA,bPartB:array of TC_Ball;
bCmpPara:TC_CmpPara;
begin
A := 0;
strLog1 := '';
strLog2 := '';
strLog3 := '';
ClearCanvas(aCanvas,aClearRect);
str := A_Team;
for Loop := 1 to 4 do
begin
A := A + AllBall[Loop].Weight;
str := str + IntToStr(AllBall[Loop].Order) + ',';
//bPartA[Loop] := AllBall[Loop];
end;
str := str + preTail0;
strLog1 := strLog1 + str;
B := 0;
str := B_Team;
for Loop := 5 to 8 do
begin
B := B + AllBall[Loop].Weight;
str := str + IntToStr(AllBall[Loop].Order) + ',';
//bPartB[Loop] := AllBall[Loop];
end;
str := str + preTail0;
strLog1 := strLog1 + str;
bNumber := 4;
SetLength(bPartA,bNumber);
SetLength(bPartB,bNumber);
for Loop := 0 to bNumber - 1 do
begin
bPartA[Loop] := AllBall[Loop+1];
bPartB[Loop] := AllBall[Loop+bNumber + 1];
end;
Balance_One_Compare(Point(Fir_Pivot_X,Fir_Pivot_Y),
bNumber,bPartA,bPartB,ACanvas,bShowTrace);
if A = B then
begin
strLog1 := strLog1 + strAXDB;
str := proHead;
for Loop := 1 to 4 do
begin
BufC[Loop] := AllBall[8 + Loop].Order;
str := str + IntToStr(AllBall[8 + Loop].Order) + ',';
end;
str := str + '] ' + preTail1 + ' 【排8餘4】';
strLog1 := strLog1 + str;
for Loop := 1 to 8 do
BufT[Loop] := AllBall[Loop].Order;
with bCmpPara do
begin
Pre_LNumber := 12;
Fro_LNumber := 4;
SetLength(Pre_Latency,Pre_LNumber);
SetLength(Fro_Latency,Fro_LNumber);
for Loop := 0 to Pre_LNumber - 1 do
Pre_Latency[Loop] := AllBall[Loop + 1];
for Loop := 0 to Fro_LNumber - 1 do
Fro_Latency[Loop] := AllBall[Loop + 9];
end;
Balance_One_Latency(Point(10,Fir_Pivot_Y - One_PreDelta),Point(10,Fir_Pivot_Y + One_FroDelta),
bCmpPara,ACanvas,bShowTrace);
if SearchBall_At4(AllBall,BufC,BufT,bOrder,bHeavy,ACanvas,bShowTrace) then
begin
FoundBall.Ball := AllBall[bOrder];
FoundBall.IsHeavy := bHeavy;
if FoundBall.IsHeavy then
FoundBall.ErrorMsg := '【偏重】'
else
FoundBall.ErrorMsg := '【偏輕】';
str := '【'+ IntToStr(FoundBall.Ball.Order) + '】 = '
+ IntToStr(FoundBall.Ball.Weight) + ' ' + FoundBall.ErrorMsg;
strLog3 := lastResult + str;
end;
end
else
begin
if A > B then
strLog1 := strLog1 + strADYB
else
strLog1 := strLog1 + strAXYB;
str := proHead;
for Loop := 1 to 8 do
str := str + IntToStr(AllBall[Loop].Order) + ',';
str := str + '] ' + preTail1 + '【排4餘8】';
strLog1 := strLog1 + str;
for Loop := 1 to 4 do
begin
BufA[Loop] := AllBall[Loop].Order;
BufB[Loop] := AllBall[4 + Loop].Order;
BufG[Loop] := AllBall[8 + Loop].Order;
end;
with bCmpPara do
begin
Pre_LNumber := 12;
Fro_LNumber := 4;
SetLength(Pre_Latency,Pre_LNumber);
SetLength(Fro_Latency,Fro_LNumber);
for Loop := 0 to Pre_LNumber - 1 do
Pre_Latency[Loop] := AllBall[Loop + 1];
for Loop := 0 to Fro_LNumber - 1 do
Fro_Latency[Loop] := AllBall[Loop + 9];
end;
Balance_One_Latency(Point(Hint_X,Fir_Pivot_Y - One_PreDelta),Point(10,Fir_Pivot_Y + One_FroDelta),
bCmpPara,ACanvas,bShowTrace);
if SearchBall_At8(AllBall,A > B,BufA,BufB,BufG,bOrder,bHeavy,ACanvas,bShowTrace) then
begin
FoundBall.Ball := AllBall[bOrder];
FoundBall.IsHeavy := bHeavy;
if FoundBall.IsHeavy then
FoundBall.ErrorMsg := '【偏重】'
else
FoundBall.ErrorMsg := '【偏輕】';
str := '【'+ IntToStr(FoundBall.Ball.Order) + '】 = '
+ IntToStr(FoundBall.Ball.Weight) + ' ' + FoundBall.ErrorMsg;
strLog3 := lastResult + str;
end;
end;
//MessageBox(0,PChar(Str),'小球問題',MB_OK or MB_IConInformation);
end;
procedure Draw_Ball_Config(
AllBall:array of TC_Ball;
ACanvas:TCanvas;
aClearRect: TRect;
bShowTrace:Boolean);
begin
ClearCanvas(aCanvas,aClearRect);
Process_Initial_Ball(
Point(0,Fir_Pivot_Y - One_PreDelta-10),
AllBall,ACanvas,bShowTrace);
end;
procedure ClearCanvas(aCanvas: TCanvas; aRect: TRect);
begin
with aCanvas do
begin
Brush.Style := bsSolid;
Brush.Color := clWhite;
FillRect(aRect);
end;
end;
end.
5、 顯示繪製原始碼
...{
作品名稱: 小球問題通用解決方案
開發作者: 成曉旭
開發時間: 2003年01月22日
完成時間: 2003年01月22日
修改時間1: 2003年11月15日
增加小於問題初始狀態繪製方法
}
unit BallType;
interface
uses
Dialogs,Windows,Classes,SysUtils,Graphics;
type
//小球問題:小球抽象資料型別
TC_Ball = Packed Record
Order:Byte;
Weight:Byte;
BgColor:TColor;
TextColor:TColor;
end;
//小球問題:被尋找的目標小球抽象資料型別
TC_SearchBall = Packed Record
Ball:TC_Ball;
IsHeavy:Boolean;
ErrorMsg:AnsiString;
end;
//小球問題:一次比較的引數的抽象資料型別
TC_CmpPara = Packed Record
Pre_LNumber:Byte;
Pre_Latency:array of TC_Ball;
Fro_LNumber:Byte;
Fro_Latency:array of TC_Ball;
end;
//小球問題:小球抽象類
TC_Ball_Class = class
private
bDrawOrder: Boolean;
bAbstractBall:TC_Ball;
bStartPoint:TPoint;
bSize:Integer;
bTextColor:TColor;
bBgColor:TColor;
bColorChanged: Boolean;
bCanvas: TCanvas;
public
procedure SetBgAndTextColor(bgColor: TColor; ttColor: TColor);
procedure DrawSelf();
constructor Create(bTrance: Boolean);
end;
//小球問題:天平抽象類
TC_Balance = class
// published
bMainPivot:TPoint;
bPartAPivot:TPoint;
bPartBPivot:TPoint;
bColor:TColor;
bPivotColor:TColor;
bCanvas: TCanvas;
bWeightA:Integer;
bWeightB:Integer;
private
bWidth:Integer;
bHeight:Integer;
bDelta:Integer;
public
procedure DrawSelf();
end;
//小球問題:天平比較一次抽象類[行為抽象]
TC_Compare = class
cbPivot:TPoint;
cbPreStart,cbFroStart:TPoint;
cbCmpPara:TC_CmpPara;
cbCount:Byte;
cbPre_Latency:array of TC_Ball;
cBallPartA:array of TC_Ball;
cBallPartB:array of TC_Ball;
cbFro_Latency:array of TC_Ball;
cBalance:TC_Balance;
cCanvas: TCanvas;
private
cbPPartA,cbPPartB:TPoint;
pPre_Latency:array of TC_Ball_Class;
pPartA:array of TC_Ball_Class;
pPartB:array of TC_Ball_Class;
pFro_Latency:array of TC_Ball_Class;
isShowTrace:Boolean;
procedure Draw_Balance();
procedure Draw_Part_A();
procedure Draw_Part_B();
procedure Draw_Latency();
public
procedure Draw_AllBall();
procedure Weigh_Out();
constructor Create(bTrace: Boolean);
end;
//小球問題抽象類<2003-11-14至今未被使用,是為方法的通用性而設計>
TC_Ball_Problem = class
bpBall:array of TC_Ball;
bpCompareCount:Byte;
bpBallCount:Byte;
bpCanvas: TCanvas;
bpCompare:array of TC_Compare;
pBalace:TC_Balance;
public
//procedure Weigh_Out(bCenterX,bCenterY:Integer);
end;
//天平的一次比較結果處理演算法
procedure Balance_One_Latency(
BallStart1,BallStart2:TPoint;
OneCmpPara:TC_CmpPara;
ACanvas:TCanvas;
bTrace:Boolean);
//天平的一次比較執行演算法
procedure Balance_One_Compare(
BalancePivot:TPoint;
BallNum:Byte;
PartA,PartB:array of TC_Ball;
ACanvas:TCanvas;
bTrace:Boolean);
//問題條件設定處理演算法(小於的初始狀態演示演算法)
procedure Process_Initial_Ball(
StartPoint:TPoint;
AllBall:array of TC_Ball;
ACanvas:TCanvas;
bTrace:Boolean
);
implementation
...{ TC_Ball_Class }
constructor TC_Ball_Class.Create(bTrance: Boolean);
begin
bDrawOrder := NOT bTrance;
end;
procedure TC_Ball_Class.DrawSelf();
var
strDrawText:String;
w,h,r:Integer;
begin
//暫時增加
if bDrawOrder then
strDrawText := IntToStr(bAbstractBall.Order)
else
strDrawText := IntToStr(bAbstractBall.Weight);
if bColorChanged then
begin
bCanvas.Brush.Color := bBgColor;
bCanvas.Pen.Color := bBgColor;
bCanvas.Font.Color := bTextColor;
end
else
begin
bCanvas.Brush.Color := bAbstractBall.BgColor;
bCanvas.Pen.Color := bAbstractBall.BgColor;
bCanvas.Font.Color := bAbstractBall.TextColor;
end;
bCanvas.Font.Size := bSize;
bCanvas.Font.Style := [fsBold];
w := bCanvas.TextWidth(strDrawText);
h := bCanvas.TextHeight(strDrawText);
if w > h then
r := w
else
r := h;
//注意:此處的計算比例,是根據矩形的內接圓、外切圓推算出來的,
//再加以實現繪製時的位置係數除錯、調整而來
bCanvas.Ellipse(bStartPoint.X,bStartPoint.Y,bStartPoint.X + r * 1414 div 1000,bStartPoint.Y + r * 1414 div 1000);
if (Length(strDrawText) = 1) then
bCanvas.TextOut(bStartPoint.X + r * 414 div 1000,bStartPoint.Y + r * 207 div 1000,strDrawText)
else if (Length(strDrawText) = 2) then
bCanvas.TextOut(bStartPoint.X + r * 214 div 1000,bStartPoint.Y + r * 228 div 1000,strDrawText);
end;
procedure TC_Ball_Class.SetBgAndTextColor(bgColor: TColor; ttColor: TColor);
begin
Self.bBgColor := bgColor;
Self.bTextColor := ttColor;
bColorChanged := true;
end;
...{ TC_Balance }
procedure TC_Balance.DrawSelf;
procedure DrawTray(ACanvas:TCanvas;aX,aY,Awidth,AHeight:Integer;aDeltaY:Integer);
begin
with ACanvas do
begin
MoveTo(aX,aY);
LineTo(aX - AWidth,aY + aDeltaY);
LineTo(aX - AWidth - AHeight,aY - AHeight + aDeltaY);
MoveTo(aX,aY);
LineTo(aX + AWidth,aY - aDeltaY);
LineTo(aX + AWidth + AHeight,aY - aHeight - aDeltaY);
end;
end;
var
X0,Y0,X1,Y1,X2,Y2,D,H:Integer;
begin
bDelta := 6;
if bWeightA > bWeightB then//[A > B]
bDelta := bDelta
else if bWeightA = bWeightB then//[A = B]
bDelta := 0
else//[A
bDelta := - bDelta;
X0 := bMainPivot.X;
Y0 := bMainPivot.Y;
D := bWidth;
H := bHeight;
bCanvas.Pen.Color := bPivotColor;
bCanvas.Brush.Color := bPivotColor;
bCanvas.Polygon([Point(X0,Y0),Point(X0 - H,Y0 + H),Point(X0 + H,Y0 + H),Point(X0,Y0)]);
bCanvas.Pen.Color := bColor;
DrawTray(bCanvas,X0,Y0,D,H,bDelta);
X1 := X0 - D - H;
Y1 := Y0 - H + bDelta;
DrawTray(bCanvas,X1,Y1,D div 2,H,0);
X2 := X0 + D + H;
Y2 := Y0 - H - bDelta;
DrawTray(bCanvas,X2,Y2,D div 2,H,0);
bPartAPivot.X := X1;
bPartAPivot.Y := Y1;
bPartBPivot.X := X2;
bPartBPivot.Y := Y2;
end;
...{ TC_Compare }
constructor TC_Compare.Create(bTrace: Boolean);
begin
isShowTrace := bTrace;
end;
procedure TC_Compare.Draw_AllBall;
const
strHint = '比較前:';
var
Loop:Integer;
begin
SetLength(pPre_Latency,cbCmpPara.Pre_LNumber);
SetLength(cbCmpPara.Pre_Latency,cbCmpPara.Pre_LNumber);
for Loop := 0 to cbCmpPara.Pre_LNumber - 1 do
begin
pPre_Latency[Loop] := TC_Ball_Class.Create(isShowTrace);
pPre_Latency[Loop].bAbstractBall := cbCmpPara.Pre_Latency[Loop];
pPre_Latency[Loop].bSize := 10;
pPre_Latency[Loop].bStartPoint := Point(80+cbPreStart.X + Loop * 25,cbPreStart.Y);
pPre_Latency[Loop].SetBgAndTextColor(clBlue,clYellow);
pPre_Latency[Loop].bCanvas := cCanvas;
pPre_Latency[Loop].bCanvas.Font.Size := 11;
pPre_Latency[Loop].bCanvas.Font.Style := [fsBold];
pPre_Latency[Loop].bCanvas.Font.Color := clBlack;
pPre_Latency[Loop].bCanvas.Brush.Color := clWhite;
pPre_Latency[Loop].bCanvas.TextOut(cbPreStart.X,cbPreStart.Y,strHint);
pPre_Latency[Loop].DrawSelf();
pPre_Latency[Loop].Free();
end;
end;
procedure TC_Compare.Draw_Balance;
var
Loop:Integer;
begin
cBalance := TC_Balance.Create();
cBalance.bWeightA := 0;
cBalance.bWeightB := 0;
for Loop := 0 to cbCount - 1 do
begin
cBalance.bWeightA := cBalance.bWeightA + cBallPartA[Loop].Weight;
cBalance.bWeightB := cBalance.bWeightB + cBallPartB[Loop].Weight;
end;
cBalance.bMainPivot := cbPivot;
cBalance.bPivotColor := clFuchsia;
cBalance.bColor := clBlue;
cBalance.bWidth := 100;
cBalance.bHeight := 18;
cBalance.bCanvas := cCanvas;
cBalance.DrawSelf();
cbPPartA := cBalance.bPartAPivot;
cbPPartB := cBalance.bPartBPivot;
cBalance.Free();
end;
procedure TC_Compare.Draw_Latency;
const
strHint = '比較後:';
var
Loop:Integer;
begin
SetLength(pFro_Latency,cbCmpPara.Fro_LNumber);
//SetLength(cbCmpPara.Fro_Latency,cbCmpPara.Fro_LNumber);
//注意:下面Pre_Latency不能用Fro_Latency來代替,不知道為什麼2003-11-20
SetLength(cbCmpPara.Pre_Latency,cbCmpPara.Fro_LNumber);
for Loop := 0 to cbCmpPara.Fro_LNumber - 1 do
begin
pFro_Latency[Loop] := TC_Ball_Class.Create(isShowTrace);
pFro_Latency[Loop].bAbstractBall := cbCmpPara.Fro_Latency[Loop];
pFro_Latency[Loop].bSize := 10;
pFro_Latency[Loop].bStartPoint := Point(80+cbFroStart.X + Loop * 25,cbFroStart.Y);
pFro_Latency[Loop].SetBgAndTextColor(clGreen,clYellow);
pFro_Latency[Loop].bCanvas := cCanvas;
pFro_Latency[Loop].bCanvas.Font.Size := 11;
pFro_Latency[Loop].bCanvas.Font.Style := [fsBold];
pFro_Latency[Loop].bCanvas.Font.Color := clBlack;
pFro_Latency[Loop].bCanvas.Brush.Color := clWhite;
pFro_Latency[Loop].bCanvas.TextOut(cbFroStart.X,cbFroStart.Y,strHint);
pFro_Latency[Loop].DrawSelf();
pFro_Latency[Loop].Free();
end;
end;
procedure TC_Compare.Draw_Part_A;
var
Loop,r:Integer;
begin
SetLength(pPartA,cbCount);
for Loop := 0 to cbCount - 1 do
begin
pPartA[Loop] := TC_Ball_Class.Create(isShowTrace);
pPartA[Loop].bAbstractBall.Order := cBallPartA[Loop].Order;
pPartA[Loop].bAbstractBall.Weight := cBallPartA[Loop].Weight;
pPartA[Loop].bSize := 10;
pPartA[Loop].SetBgAndTextColor(clYellow,clRed);
pPartA[Loop].bCanvas := cCanvas;
//注意:此句一定要有,設定字型的大小屬性
pPartA[Loop].bCanvas.Font.Size := pPartA[Loop].bSize;
if pPartA[Loop].bCanvas.TextWidth(IntToStr(pPartA[Loop].bAbstractBall.Order)) >
pPartA[Loop].bCanvas.TextHeight(IntToStr(pPartA[Loop].bAbstractBall.Order)) then
r := pPartA[Loop].bCanvas.TextWidth(IntToStr(pPartA[Loop].bAbstractBall.Order))
else
r := pPartA[Loop].bCanvas.TextHeight(IntToStr(pPartA[Loop].bAbstractBall.Order));
r := r * 1414 div 1000;
//下面的計算公式有點難
pPartA[Loop].bStartPoint.X := cbPPartA.X - (cbCount div 2) * r - r * 5 * (cbCount mod 2) div 10 + Loop * r;
pPartA[Loop].bStartPoint.Y := cbPPartA.Y - r;
pPartA[Loop].DrawSelf();
pPartA[Loop].Free();
end;
end;
procedure TC_Compare.Draw_Part_B;
var
Loop,r:Integer;
begin
SetLength(pPartb,cbCount);
for Loop := 0 to cbCount - 1 do
begin
pPartB[Loop] := TC_Ball_Class.Create(isShowTrace);
pPartB[Loop].bAbstractBall.Order := cBallPartB[Loop].Order;
pPartB[Loop].bAbstractBall.Weight := cBallPartB[Loop].Weight;
pPartB[Loop].bSize := 10;
pPartB[Loop].SetBgAndTextColor(clYellow,clRed);
pPartB[Loop].bCanvas := cCanvas;
pPartB[Loop].bCanvas.Font.Size := pPartB[Loop].bSize;
if pPartB[Loop].bCanvas.TextWidth(IntToStr(pPartB[Loop].bAbstractBall.Order)) >
pPartB[Loop].bCanvas.TextHeight(IntToStr(pPartB[Loop].bAbstractBall.Order)) then
r := pPartB[Loop].bCanvas.TextWidth(IntToStr(pPartB[Loop].bAbstractBall.Order))
else
r := pPartB[Loop].bCanvas.TextHeight(IntToStr(pPartB[Loop].bAbstractBall.Order));
r := r * 1414 div 1000;
pPartB[Loop].bStartPoint.X := cbPPartB.X - (cbCount div 2) * r - r * 5 * (cbCount mod 2) div 10 + Loop * r;
pPartB[Loop].bStartPoint.Y := cbPPartB.Y - r;
pPartB[Loop].DrawSelf();
pPartB[Loop].Free();
end;
end;
procedure TC_Compare.Weigh_Out();
begin
Draw_Balance();
Draw_Part_A();
Draw_Part_B();
end;
procedure Balance_One_Compare(
BalancePivot:TPoint;
BallNum:Byte;
PartA,PartB:array of TC_Ball;
ACanvas:TCanvas;
bTrace:Boolean);
var
OneCmp:TC_Compare;
Loop:Integer;
begin
OneCmp := TC_Compare.Create(bTrace);
OneCmp.cbPivot := BalancePivot;
OneCmp.cbCount := BallNum;
OneCmp.cCanvas := ACanvas;
SetLength(OneCmp.cBallPartA,OneCmp.cbCount);
SetLength(OneCmp.cBallPartB,OneCmp.cbCount);
for Loop := 0 to OneCmp.cbCount - 1 do
begin
OneCmp.cBallPartA[Loop] := PartA[Loop];
OneCmp.cBallPartB[Loop] := PartB[Loop];
end;
OneCmp.Weigh_Out();
OneCmp.Free();
end;
procedure Balance_One_Latency(
BallStart1,BallStart2:TPoint;
OneCmpPara:TC_CmpPara;
ACanvas:TCanvas;
bTrace:Boolean);
var
OneCmp:TC_Compare;
begin
OneCmp := TC_Compare.Create(bTrace);
OneCmp.cCanvas := ACanvas;
OneCmp.cbCmpPara := OneCmpPara;
OneCmp.cbPreStart := BallStart1;
OneCmp.cbFroStart := BallStart2;
OneCmp.Draw_AllBall();
OneCmp.Draw_Latency();
OneCmp.Free();
end;
//問題條件設定處理演算法(小於的初始狀態演示演算法)
procedure Process_Initial_Ball(
StartPoint:TPoint;
AllBall:array of TC_Ball;
ACanvas:TCanvas;
bTrace:Boolean);
const
//strHint = '初始狀態:';
strHint = '';
var
Loop:Integer;
aBall: TC_Ball_Class;
begin
for Loop := Low(AllBall) to High(AllBall) - 1 do
begin
aBall := TC_Ball_Class.Create(bTrace);
aBall.bAbstractBall := AllBall[Loop + 1];
aBall.bSize := 10;
aBall.bStartPoint := Point(2 + StartPoint.X + Loop * 25,StartPoint.Y);
aBall.bCanvas := ACanvas;
aBall.bCanvas.Font.Size := 11;
aBall.bCanvas.Font.Style := [fsBold];
aBall.bCanvas.Font.Color := clBlack;
aBall.bCanvas.Brush.Color := clWhite;
aBall.bCanvas.TextOut(StartPoint.X,StartPoint.Y,strHint);
aBall.DrawSelf();
aBall.Free();
end;
end;
end.
作品名稱: 小球問題通用解決方案
開發作者: 成曉旭
開發時間: 2003年01月22日
完成時間: 2003年01月22日
修改時間1: 2003年11月15日
增加小於問題初始狀態繪製方法
}
unit BallType;
interface
uses
Dialogs,Windows,Classes,SysUtils,Graphics;
type
//小球問題:小球抽象資料型別
TC_Ball = Packed Record
Order:Byte;
Weight:Byte;
BgColor:TColor;
TextColor:TColor;
end;
//小球問題:被尋找的目標小球抽象資料型別
TC_SearchBall = Packed Record
Ball:TC_Ball;
IsHeavy:Boolean;
ErrorMsg:AnsiString;
end;
//小球問題:一次比較的引數的抽象資料型別
TC_CmpPara = Packed Record
Pre_LNumber:Byte;
Pre_Latency:array of TC_Ball;
Fro_LNumber:Byte;
Fro_Latency:array of TC_Ball;
end;
//小球問題:小球抽象類
TC_Ball_Class = class
private
bDrawOrder: Boolean;
bAbstractBall:TC_Ball;
bStartPoint:TPoint;
bSize:Integer;
bTextColor:TColor;
bBgColor:TColor;
bColorChanged: Boolean;
bCanvas: TCanvas;
public
procedure SetBgAndTextColor(bgColor: TColor; ttColor: TColor);
procedure DrawSelf();
constructor Create(bTrance: Boolean);
end;
//小球問題:天平抽象類
TC_Balance = class
// published
bMainPivot:TPoint;
bPartAPivot:TPoint;
bPartBPivot:TPoint;
bColor:TColor;
bPivotColor:TColor;
bCanvas: TCanvas;
bWeightA:Integer;
bWeightB:Integer;
private
bWidth:Integer;
bHeight:Integer;
bDelta:Integer;
public
procedure DrawSelf();
end;
//小球問題:天平比較一次抽象類[行為抽象]
TC_Compare = class
cbPivot:TPoint;
cbPreStart,cbFroStart:TPoint;
cbCmpPara:TC_CmpPara;
cbCount:Byte;
cbPre_Latency:array of TC_Ball;
cBallPartA:array of TC_Ball;
cBallPartB:array of TC_Ball;
cbFro_Latency:array of TC_Ball;
cBalance:TC_Balance;
cCanvas: TCanvas;
private
cbPPartA,cbPPartB:TPoint;
pPre_Latency:array of TC_Ball_Class;
pPartA:array of TC_Ball_Class;
pPartB:array of TC_Ball_Class;
pFro_Latency:array of TC_Ball_Class;
isShowTrace:Boolean;
procedure Draw_Balance();
procedure Draw_Part_A();
procedure Draw_Part_B();
procedure Draw_Latency();
public
procedure Draw_AllBall();
procedure Weigh_Out();
constructor Create(bTrace: Boolean);
end;
//小球問題抽象類<2003-11-14至今未被使用,是為方法的通用性而設計>
TC_Ball_Problem = class
bpBall:array of TC_Ball;
bpCompareCount:Byte;
bpBallCount:Byte;
bpCanvas: TCanvas;
bpCompare:array of TC_Compare;
pBalace:TC_Balance;
public
//procedure Weigh_Out(bCenterX,bCenterY:Integer);
end;
//天平的一次比較結果處理演算法
procedure Balance_One_Latency(
BallStart1,BallStart2:TPoint;
OneCmpPara:TC_CmpPara;
ACanvas:TCanvas;
bTrace:Boolean);
//天平的一次比較執行演算法
procedure Balance_One_Compare(
BalancePivot:TPoint;
BallNum:Byte;
PartA,PartB:array of TC_Ball;
ACanvas:TCanvas;
bTrace:Boolean);
//問題條件設定處理演算法(小於的初始狀態演示演算法)
procedure Process_Initial_Ball(
StartPoint:TPoint;
AllBall:array of TC_Ball;
ACanvas:TCanvas;
bTrace:Boolean
);
implementation
...{ TC_Ball_Class }
constructor TC_Ball_Class.Create(bTrance: Boolean);
begin
bDrawOrder := NOT bTrance;
end;
procedure TC_Ball_Class.DrawSelf();
var
strDrawText:String;
w,h,r:Integer;
begin
//暫時增加
if bDrawOrder then
strDrawText := IntToStr(bAbstractBall.Order)
else
strDrawText := IntToStr(bAbstractBall.Weight);
if bColorChanged then
begin
bCanvas.Brush.Color := bBgColor;
bCanvas.Pen.Color := bBgColor;
bCanvas.Font.Color := bTextColor;
end
else
begin
bCanvas.Brush.Color := bAbstractBall.BgColor;
bCanvas.Pen.Color := bAbstractBall.BgColor;
bCanvas.Font.Color := bAbstractBall.TextColor;
end;
bCanvas.Font.Size := bSize;
bCanvas.Font.Style := [fsBold];
w := bCanvas.TextWidth(strDrawText);
h := bCanvas.TextHeight(strDrawText);
if w > h then
r := w
else
r := h;
//注意:此處的計算比例,是根據矩形的內接圓、外切圓推算出來的,
//再加以實現繪製時的位置係數除錯、調整而來
bCanvas.Ellipse(bStartPoint.X,bStartPoint.Y,bStartPoint.X + r * 1414 div 1000,bStartPoint.Y + r * 1414 div 1000);
if (Length(strDrawText) = 1) then
bCanvas.TextOut(bStartPoint.X + r * 414 div 1000,bStartPoint.Y + r * 207 div 1000,strDrawText)
else if (Length(strDrawText) = 2) then
bCanvas.TextOut(bStartPoint.X + r * 214 div 1000,bStartPoint.Y + r * 228 div 1000,strDrawText);
end;
procedure TC_Ball_Class.SetBgAndTextColor(bgColor: TColor; ttColor: TColor);
begin
Self.bBgColor := bgColor;
Self.bTextColor := ttColor;
bColorChanged := true;
end;
...{ TC_Balance }
procedure TC_Balance.DrawSelf;
procedure DrawTray(ACanvas:TCanvas;aX,aY,Awidth,AHeight:Integer;aDeltaY:Integer);
begin
with ACanvas do
begin
MoveTo(aX,aY);
LineTo(aX - AWidth,aY + aDeltaY);
LineTo(aX - AWidth - AHeight,aY - AHeight + aDeltaY);
MoveTo(aX,aY);
LineTo(aX + AWidth,aY - aDeltaY);
LineTo(aX + AWidth + AHeight,aY - aHeight - aDeltaY);
end;
end;
var
X0,Y0,X1,Y1,X2,Y2,D,H:Integer;
begin
bDelta := 6;
if bWeightA > bWeightB then//[A > B]
bDelta := bDelta
else if bWeightA = bWeightB then//[A = B]
bDelta := 0
else//[A
bDelta := - bDelta;
X0 := bMainPivot.X;
Y0 := bMainPivot.Y;
D := bWidth;
H := bHeight;
bCanvas.Pen.Color := bPivotColor;
bCanvas.Brush.Color := bPivotColor;
bCanvas.Polygon([Point(X0,Y0),Point(X0 - H,Y0 + H),Point(X0 + H,Y0 + H),Point(X0,Y0)]);
bCanvas.Pen.Color := bColor;
DrawTray(bCanvas,X0,Y0,D,H,bDelta);
X1 := X0 - D - H;
Y1 := Y0 - H + bDelta;
DrawTray(bCanvas,X1,Y1,D div 2,H,0);
X2 := X0 + D + H;
Y2 := Y0 - H - bDelta;
DrawTray(bCanvas,X2,Y2,D div 2,H,0);
bPartAPivot.X := X1;
bPartAPivot.Y := Y1;
bPartBPivot.X := X2;
bPartBPivot.Y := Y2;
end;
...{ TC_Compare }
constructor TC_Compare.Create(bTrace: Boolean);
begin
isShowTrace := bTrace;
end;
procedure TC_Compare.Draw_AllBall;
const
strHint = '比較前:';
var
Loop:Integer;
begin
SetLength(pPre_Latency,cbCmpPara.Pre_LNumber);
SetLength(cbCmpPara.Pre_Latency,cbCmpPara.Pre_LNumber);
for Loop := 0 to cbCmpPara.Pre_LNumber - 1 do
begin
pPre_Latency[Loop] := TC_Ball_Class.Create(isShowTrace);
pPre_Latency[Loop].bAbstractBall := cbCmpPara.Pre_Latency[Loop];
pPre_Latency[Loop].bSize := 10;
pPre_Latency[Loop].bStartPoint := Point(80+cbPreStart.X + Loop * 25,cbPreStart.Y);
pPre_Latency[Loop].SetBgAndTextColor(clBlue,clYellow);
pPre_Latency[Loop].bCanvas := cCanvas;
pPre_Latency[Loop].bCanvas.Font.Size := 11;
pPre_Latency[Loop].bCanvas.Font.Style := [fsBold];
pPre_Latency[Loop].bCanvas.Font.Color := clBlack;
pPre_Latency[Loop].bCanvas.Brush.Color := clWhite;
pPre_Latency[Loop].bCanvas.TextOut(cbPreStart.X,cbPreStart.Y,strHint);
pPre_Latency[Loop].DrawSelf();
pPre_Latency[Loop].Free();
end;
end;
procedure TC_Compare.Draw_Balance;
var
Loop:Integer;
begin
cBalance := TC_Balance.Create();
cBalance.bWeightA := 0;
cBalance.bWeightB := 0;
for Loop := 0 to cbCount - 1 do
begin
cBalance.bWeightA := cBalance.bWeightA + cBallPartA[Loop].Weight;
cBalance.bWeightB := cBalance.bWeightB + cBallPartB[Loop].Weight;
end;
cBalance.bMainPivot := cbPivot;
cBalance.bPivotColor := clFuchsia;
cBalance.bColor := clBlue;
cBalance.bWidth := 100;
cBalance.bHeight := 18;
cBalance.bCanvas := cCanvas;
cBalance.DrawSelf();
cbPPartA := cBalance.bPartAPivot;
cbPPartB := cBalance.bPartBPivot;
cBalance.Free();
end;
procedure TC_Compare.Draw_Latency;
const
strHint = '比較後:';
var
Loop:Integer;
begin
SetLength(pFro_Latency,cbCmpPara.Fro_LNumber);
//SetLength(cbCmpPara.Fro_Latency,cbCmpPara.Fro_LNumber);
//注意:下面Pre_Latency不能用Fro_Latency來代替,不知道為什麼2003-11-20
SetLength(cbCmpPara.Pre_Latency,cbCmpPara.Fro_LNumber);
for Loop := 0 to cbCmpPara.Fro_LNumber - 1 do
begin
pFro_Latency[Loop] := TC_Ball_Class.Create(isShowTrace);
pFro_Latency[Loop].bAbstractBall := cbCmpPara.Fro_Latency[Loop];
pFro_Latency[Loop].bSize := 10;
pFro_Latency[Loop].bStartPoint := Point(80+cbFroStart.X + Loop * 25,cbFroStart.Y);
pFro_Latency[Loop].SetBgAndTextColor(clGreen,clYellow);
pFro_Latency[Loop].bCanvas := cCanvas;
pFro_Latency[Loop].bCanvas.Font.Size := 11;
pFro_Latency[Loop].bCanvas.Font.Style := [fsBold];
pFro_Latency[Loop].bCanvas.Font.Color := clBlack;
pFro_Latency[Loop].bCanvas.Brush.Color := clWhite;
pFro_Latency[Loop].bCanvas.TextOut(cbFroStart.X,cbFroStart.Y,strHint);
pFro_Latency[Loop].DrawSelf();
pFro_Latency[Loop].Free();
end;
end;
procedure TC_Compare.Draw_Part_A;
var
Loop,r:Integer;
begin
SetLength(pPartA,cbCount);
for Loop := 0 to cbCount - 1 do
begin
pPartA[Loop] := TC_Ball_Class.Create(isShowTrace);
pPartA[Loop].bAbstractBall.Order := cBallPartA[Loop].Order;
pPartA[Loop].bAbstractBall.Weight := cBallPartA[Loop].Weight;
pPartA[Loop].bSize := 10;
pPartA[Loop].SetBgAndTextColor(clYellow,clRed);
pPartA[Loop].bCanvas := cCanvas;
//注意:此句一定要有,設定字型的大小屬性
pPartA[Loop].bCanvas.Font.Size := pPartA[Loop].bSize;
if pPartA[Loop].bCanvas.TextWidth(IntToStr(pPartA[Loop].bAbstractBall.Order)) >
pPartA[Loop].bCanvas.TextHeight(IntToStr(pPartA[Loop].bAbstractBall.Order)) then
r := pPartA[Loop].bCanvas.TextWidth(IntToStr(pPartA[Loop].bAbstractBall.Order))
else
r := pPartA[Loop].bCanvas.TextHeight(IntToStr(pPartA[Loop].bAbstractBall.Order));
r := r * 1414 div 1000;
//下面的計算公式有點難
pPartA[Loop].bStartPoint.X := cbPPartA.X - (cbCount div 2) * r - r * 5 * (cbCount mod 2) div 10 + Loop * r;
pPartA[Loop].bStartPoint.Y := cbPPartA.Y - r;
pPartA[Loop].DrawSelf();
pPartA[Loop].Free();
end;
end;
procedure TC_Compare.Draw_Part_B;
var
Loop,r:Integer;
begin
SetLength(pPartb,cbCount);
for Loop := 0 to cbCount - 1 do
begin
pPartB[Loop] := TC_Ball_Class.Create(isShowTrace);
pPartB[Loop].bAbstractBall.Order := cBallPartB[Loop].Order;
pPartB[Loop].bAbstractBall.Weight := cBallPartB[Loop].Weight;
pPartB[Loop].bSize := 10;
pPartB[Loop].SetBgAndTextColor(clYellow,clRed);
pPartB[Loop].bCanvas := cCanvas;
pPartB[Loop].bCanvas.Font.Size := pPartB[Loop].bSize;
if pPartB[Loop].bCanvas.TextWidth(IntToStr(pPartB[Loop].bAbstractBall.Order)) >
pPartB[Loop].bCanvas.TextHeight(IntToStr(pPartB[Loop].bAbstractBall.Order)) then
r := pPartB[Loop].bCanvas.TextWidth(IntToStr(pPartB[Loop].bAbstractBall.Order))
else
r := pPartB[Loop].bCanvas.TextHeight(IntToStr(pPartB[Loop].bAbstractBall.Order));
r := r * 1414 div 1000;
pPartB[Loop].bStartPoint.X := cbPPartB.X - (cbCount div 2) * r - r * 5 * (cbCount mod 2) div 10 + Loop * r;
pPartB[Loop].bStartPoint.Y := cbPPartB.Y - r;
pPartB[Loop].DrawSelf();
pPartB[Loop].Free();
end;
end;
procedure TC_Compare.Weigh_Out();
begin
Draw_Balance();
Draw_Part_A();
Draw_Part_B();
end;
procedure Balance_One_Compare(
BalancePivot:TPoint;
BallNum:Byte;
PartA,PartB:array of TC_Ball;
ACanvas:TCanvas;
bTrace:Boolean);
var
OneCmp:TC_Compare;
Loop:Integer;
begin
OneCmp := TC_Compare.Create(bTrace);
OneCmp.cbPivot := BalancePivot;
OneCmp.cbCount := BallNum;
OneCmp.cCanvas := ACanvas;
SetLength(OneCmp.cBallPartA,OneCmp.cbCount);
SetLength(OneCmp.cBallPartB,OneCmp.cbCount);
for Loop := 0 to OneCmp.cbCount - 1 do
begin
OneCmp.cBallPartA[Loop] := PartA[Loop];
OneCmp.cBallPartB[Loop] := PartB[Loop];
end;
OneCmp.Weigh_Out();
OneCmp.Free();
end;
procedure Balance_One_Latency(
BallStart1,BallStart2:TPoint;
OneCmpPara:TC_CmpPara;
ACanvas:TCanvas;
bTrace:Boolean);
var
OneCmp:TC_Compare;
begin
OneCmp := TC_Compare.Create(bTrace);
OneCmp.cCanvas := ACanvas;
OneCmp.cbCmpPara := OneCmpPara;
OneCmp.cbPreStart := BallStart1;
OneCmp.cbFroStart := BallStart2;
OneCmp.Draw_AllBall();
OneCmp.Draw_Latency();
OneCmp.Free();
end;
//問題條件設定處理演算法(小於的初始狀態演示演算法)
procedure Process_Initial_Ball(
StartPoint:TPoint;
AllBall:array of TC_Ball;
ACanvas:TCanvas;
bTrace:Boolean);
const
//strHint = '初始狀態:';
strHint = '';
var
Loop:Integer;
aBall: TC_Ball_Class;
begin
for Loop := Low(AllBall) to High(AllBall) - 1 do
begin
aBall := TC_Ball_Class.Create(bTrace);
aBall.bAbstractBall := AllBall[Loop + 1];
aBall.bSize := 10;
aBall.bStartPoint := Point(2 + StartPoint.X + Loop * 25,StartPoint.Y);
aBall.bCanvas := ACanvas;
aBall.bCanvas.Font.Size := 11;
aBall.bCanvas.Font.Style := [fsBold];
aBall.bCanvas.Font.Color := clBlack;
aBall.bCanvas.Brush.Color := clWhite;
aBall.bCanvas.TextOut(StartPoint.X,StartPoint.Y,strHint);
aBall.DrawSelf();
aBall.Free();
end;
end;
end.
6、 介面原始碼
...{
作品名稱: 小球問題通用解決方案
開發作者: 成曉旭
開發時間: 2003年01月21日
完成時間: 2003年01月22日
修改時間1: 2003年02月10日 新增Delphi繪圖功能
修改時間2: 2003年11月14日 新增對問題模擬條件的使用者設定功能
修改時間2: 2003年11月20日 新增ClearCanvas()方法,解決不能清除畫面問題
}
unit BMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,BallType,Common, Buttons, ExtCtrls;
type
TExceptStyle = (esLight,esHeavy); //偏輕 偏重
const
strHint = '中國';
BallNumber = 12; //小球數量
BallValue = 10; //正常小球的質量
HeavyValue = 15; //偏重小球的質量
LightValue = 5; //偏輕小球的質量
type
TfrmMain = class(TForm)
btnDemo: TButton;
imgMain: TImage;
gbConfig: TGroupBox;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
RadioButton3: TRadioButton;
RadioButton4: TRadioButton;
RadioButton5: TRadioButton;
RadioButton6: TRadioButton;
RadioButton7: TRadioButton;
RadioButton8: TRadioButton;
RadioButton9: TRadioButton;
RadioButton10: TRadioButton;
RadioButton11: TRadioButton;
RadioButton12: TRadioButton;
ImgConfig: TImage;
cbEStyle: TCheckBox;
Label1: TLabel;
Memo0: TMemo;
Label2: TLabel;
Label3: TLabel;
Memo1: TMemo;
Label4: TLabel;
Memo2: TMemo;
Label5: TLabel;
Memo3: TMemo;
btnSetNumber: TButton;
btnAuto: TButton;
btnAbout: TButton;
Label6: TLabel;
cbTrance: TCheckBox;
procedure FormShow(Sender: TObject);
procedure RadioButton1Click(Sender: TObject);
procedure btnDemoClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btnSetNumberClick(Sender: TObject);
procedure btnAutoClick(Sender: TObject);
procedure btnAboutClick(Sender: TObject);
private
...{ Private declarations }
isTrance: Boolean; //是否跟蹤(cbTrance的狀態記錄)
SmallBall:array[0..BallNumber] of TC_Ball; //小球的抽象資料
ExceptBall: TC_Ball; //異常小球
ExceptStyle:TExceptStyle; //異常小球的特性
ExceptBallValue:Integer; //異常小球的質量
ExceptColor:TColor; //異常小球的表示顏色
//處理小球問題條件設定RadioGroup
function ProcessRadioButton(isSort:Boolean):Integer;
//選擇異常小球方法
procedure ChooseExceptBall();
//繪製所有小球方法
// withExceptBall = true
// withExceptBall = false
procedure DrawSmallBall(withExceptBall: Boolean; isTrance: Boolean);
procedure ClearCanvas
(aCanvas: TCanvas);
public
...{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
...{$R *.dfm}
//單元內部常量定義
const
Soft_Name = '小球問題解答過程演示程式0.2版';
strWaitHint = '本功能正在加緊完善中......' + CHR(13) + CHR(10) +
'請拭目以待!';
strSetNumber = '設定[3-12]的小球數目,程式將自動演示問題的解答過程!'
+ CHR(13) + CHR(10) + strWaitHint;
strAutoAnswer = '設定任意數目的小球,程式將根據本題的問題模式,'
+'推算最少的比較次數,並自動演示推算過程!'
+ CHR(13) + CHR(10) + strWaitHint;
About_Soft_Info = Soft_Name + CHR(13) + CHR(10) +
'開發作者:成曉旭'+ CHR(13) + CHR(10) +
'完成時間:2003年01月23日' + CHR(13) + CHR(10) +
'最後修改:2003年11月20日' + CHR(13) + CHR(10) +
'聯絡方式:CXXSoft@163.com' + CHR(13) + CHR(10) +
'設計說明:本程式採用純物件導向的分析、設計、實現。' +
'也是本人的第一個運用' +
' 設計模式的作品。' + CHR(13) + CHR(10) +
'釋出說明:程式完成時,我將公佈其原始碼。';
function TfrmMain.ProcessRadioButton(isSort:Boolean):Integer;
const
space = 25;
var
aCtrl:TControl;
aChoose:TRadioButton;
//點選的小球索引號,迴圈計數器,第一個RadioButton的Top屬性,GroupBox中RadioCount的計數器(關鍵)
indexBall,I,aTop,RadioCount:Integer;
begin
indexBall := -1;
aTop := 0;
RadioCount := 0; //注意:此處初值 = -1 是錯誤的
for I := 0 to gbConfig.ControlCount - 1 do
begin
aCtrl := gbConfig.Controls[I];
if aCtrl.ClassType = TRadioButton then
begin
try
Inc(RadioCount);
aChoose := TRadioButton(aCtrl);
if isSort then
begin
if indexBall = -1 then
aTop := aChoose.Top
else
aChoose.Top := aTop;
aChoose.Left := (RadioCount - 1) * space + 8;
end
else
begin
if aChoose.Checked then
begin
indexBall := RadioCount;
//ShowMessage('Index Ball = ' + IntToStr(indexBall));
break; //演算法效率之關鍵
end;
end;
except
end;
end;
end;
Result := indexBall;
end;
procedure TfrmMain.FormShow(Sender: TObject);
begin
ProcessRadioButton(true);
DrawSmallBall(false,cbTrance.Checked);
end;
procedure TfrmMain.ChooseExceptBall();
var
index:Integer;
begin
index := ProcessRadioButton(false);
if (index >= 0) and (index <= BallNumber) then
ExceptBall := SmallBall[index];
if cbEStyle.Checked then
begin
ExceptStyle := esHeavy;
ExceptBallValue := HeavyValue;
ExceptColor := clRed;
end
else
begin
ExceptStyle := esLight;
ExceptBallValue := LightValue;
ExceptColor := clFuchsia;
end;
ExceptBall.Weight := ExceptBallValue;
ExceptBall.BgColor := ExceptColor;
ExceptBall.TextColor := clBlack;
SmallBall[index] := ExceptBall;
end;
procedure TfrmMain.DrawSmallBall(withExceptBall: Boolean; isTrance: Boolean);
var
Loop:Integer;
begin
for Loop := 1 to BallNumber do
begin
SmallBall[Loop].Order := Loop;
SmallBall[Loop].Weight := BallValue;
SmallBall[Loop].BgColor := clBlue;
SmallBall[Loop].TextColor := clRed;
end;
if withExceptBall then
begin
ChooseExceptBall();
end;
Draw_Ball_Config(SmallBall,ImgConfig.Canvas,ClientRect,isTrance);
end;
procedure TfrmMain.RadioButton1Click(Sender: TObject);
begin
try
isTrance := cbTrance.Checked;
except
isTrance := NOT isTrance;
end;;
DrawSmallBall(true,isTrance);
btnDemo.SetFocus();
end;
procedure TfrmMain.btnDemoClick(Sender: TObject);
begin
Serach_Error_Ball(SmallBall,imgMain.Canvas,ClientRect,isTrance);
Memo1.Lines.Text := strLog1;
Memo2.Lines.Text := strLog2;
Memo3.Lines.Text := strLog3;
end;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
// Width := Screen.Width;
// Height := Screen.Height;
Width := 800;
Height := 600;
Caption := Soft_Name;
end;
procedure TfrmMain.ClearCanvas(aCanvas: TCanvas);
begin
aCanvas.Brush.Style := bsSolid;
aCanvas.Brush.Color := clWhite;
aCanvas.FillRect(ClientRect);
end;
procedure TfrmMain.btnSetNumberClick(Sender: TObject);
begin
Application.MessageBox(strSetNumber,Soft_Name,MB_ICONINFORMATION);
end;
procedure TfrmMain.btnAutoClick(Sender: TObject);
begin
Application.MessageBox(strAutoAnswer,Soft_Name,MB_ICONINFORMATION);
end;
procedure TfrmMain.btnAboutClick(Sender: TObject);
begin
Application.MessageBox(About_Soft_Info,Soft_Name,MB_ICONINFORMATION);
end;
end.
作品名稱: 小球問題通用解決方案
開發作者: 成曉旭
開發時間: 2003年01月21日
完成時間: 2003年01月22日
修改時間1: 2003年02月10日 新增Delphi繪圖功能
修改時間2: 2003年11月14日 新增對問題模擬條件的使用者設定功能
修改時間2: 2003年11月20日 新增ClearCanvas()方法,解決不能清除畫面問題
}
unit BMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,BallType,Common, Buttons, ExtCtrls;
type
TExceptStyle = (esLight,esHeavy); //偏輕 偏重
const
strHint = '中國';
BallNumber = 12; //小球數量
BallValue = 10; //正常小球的質量
HeavyValue = 15; //偏重小球的質量
LightValue = 5; //偏輕小球的質量
type
TfrmMain = class(TForm)
btnDemo: TButton;
imgMain: TImage;
gbConfig: TGroupBox;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
RadioButton3: TRadioButton;
RadioButton4: TRadioButton;
RadioButton5: TRadioButton;
RadioButton6: TRadioButton;
RadioButton7: TRadioButton;
RadioButton8: TRadioButton;
RadioButton9: TRadioButton;
RadioButton10: TRadioButton;
RadioButton11: TRadioButton;
RadioButton12: TRadioButton;
ImgConfig: TImage;
cbEStyle: TCheckBox;
Label1: TLabel;
Memo0: TMemo;
Label2: TLabel;
Label3: TLabel;
Memo1: TMemo;
Label4: TLabel;
Memo2: TMemo;
Label5: TLabel;
Memo3: TMemo;
btnSetNumber: TButton;
btnAuto: TButton;
btnAbout: TButton;
Label6: TLabel;
cbTrance: TCheckBox;
procedure FormShow(Sender: TObject);
procedure RadioButton1Click(Sender: TObject);
procedure btnDemoClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btnSetNumberClick(Sender: TObject);
procedure btnAutoClick(Sender: TObject);
procedure btnAboutClick(Sender: TObject);
private
...{ Private declarations }
isTrance: Boolean; //是否跟蹤(cbTrance的狀態記錄)
SmallBall:array[0..BallNumber] of TC_Ball; //小球的抽象資料
ExceptBall: TC_Ball; //異常小球
ExceptStyle:TExceptStyle; //異常小球的特性
ExceptBallValue:Integer; //異常小球的質量
ExceptColor:TColor; //異常小球的表示顏色
//處理小球問題條件設定RadioGroup
function ProcessRadioButton(isSort:Boolean):Integer;
//選擇異常小球方法
procedure ChooseExceptBall();
//繪製所有小球方法
// withExceptBall = true
// withExceptBall = false
procedure DrawSmallBall(withExceptBall: Boolean; isTrance: Boolean);
procedure ClearCanvas
(aCanvas: TCanvas);
public
...{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
...{$R *.dfm}
//單元內部常量定義
const
Soft_Name = '小球問題解答過程演示程式0.2版';
strWaitHint = '本功能正在加緊完善中......' + CHR(13) + CHR(10) +
'請拭目以待!';
strSetNumber = '設定[3-12]的小球數目,程式將自動演示問題的解答過程!'
+ CHR(13) + CHR(10) + strWaitHint;
strAutoAnswer = '設定任意數目的小球,程式將根據本題的問題模式,'
+'推算最少的比較次數,並自動演示推算過程!'
+ CHR(13) + CHR(10) + strWaitHint;
About_Soft_Info = Soft_Name + CHR(13) + CHR(10) +
'開發作者:成曉旭'+ CHR(13) + CHR(10) +
'完成時間:2003年01月23日' + CHR(13) + CHR(10) +
'最後修改:2003年11月20日' + CHR(13) + CHR(10) +
'聯絡方式:CXXSoft@163.com' + CHR(13) + CHR(10) +
'設計說明:本程式採用純物件導向的分析、設計、實現。' +
'也是本人的第一個運用' +
' 設計模式的作品。' + CHR(13) + CHR(10) +
'釋出說明:程式完成時,我將公佈其原始碼。';
function TfrmMain.ProcessRadioButton(isSort:Boolean):Integer;
const
space = 25;
var
aCtrl:TControl;
aChoose:TRadioButton;
//點選的小球索引號,迴圈計數器,第一個RadioButton的Top屬性,GroupBox中RadioCount的計數器(關鍵)
indexBall,I,aTop,RadioCount:Integer;
begin
indexBall := -1;
aTop := 0;
RadioCount := 0; //注意:此處初值 = -1 是錯誤的
for I := 0 to gbConfig.ControlCount - 1 do
begin
aCtrl := gbConfig.Controls[I];
if aCtrl.ClassType = TRadioButton then
begin
try
Inc(RadioCount);
aChoose := TRadioButton(aCtrl);
if isSort then
begin
if indexBall = -1 then
aTop := aChoose.Top
else
aChoose.Top := aTop;
aChoose.Left := (RadioCount - 1) * space + 8;
end
else
begin
if aChoose.Checked then
begin
indexBall := RadioCount;
//ShowMessage('Index Ball = ' + IntToStr(indexBall));
break; //演算法效率之關鍵
end;
end;
except
end;
end;
end;
Result := indexBall;
end;
procedure TfrmMain.FormShow(Sender: TObject);
begin
ProcessRadioButton(true);
DrawSmallBall(false,cbTrance.Checked);
end;
procedure TfrmMain.ChooseExceptBall();
var
index:Integer;
begin
index := ProcessRadioButton(false);
if (index >= 0) and (index <= BallNumber) then
ExceptBall := SmallBall[index];
if cbEStyle.Checked then
begin
ExceptStyle := esHeavy;
ExceptBallValue := HeavyValue;
ExceptColor := clRed;
end
else
begin
ExceptStyle := esLight;
ExceptBallValue := LightValue;
ExceptColor := clFuchsia;
end;
ExceptBall.Weight := ExceptBallValue;
ExceptBall.BgColor := ExceptColor;
ExceptBall.TextColor := clBlack;
SmallBall[index] := ExceptBall;
end;
procedure TfrmMain.DrawSmallBall(withExceptBall: Boolean; isTrance: Boolean);
var
Loop:Integer;
begin
for Loop := 1 to BallNumber do
begin
SmallBall[Loop].Order := Loop;
SmallBall[Loop].Weight := BallValue;
SmallBall[Loop].BgColor := clBlue;
SmallBall[Loop].TextColor := clRed;
end;
if withExceptBall then
begin
ChooseExceptBall();
end;
Draw_Ball_Config(SmallBall,ImgConfig.Canvas,ClientRect,isTrance);
end;
procedure TfrmMain.RadioButton1Click(Sender: TObject);
begin
try
isTrance := cbTrance.Checked;
except
isTrance := NOT isTrance;
end;;
DrawSmallBall(true,isTrance);
btnDemo.SetFocus();
end;
procedure TfrmMain.btnDemoClick(Sender: TObject);
begin
Serach_Error_Ball(SmallBall,imgMain.Canvas,ClientRect,isTrance);
Memo1.Lines.Text := strLog1;
Memo2.Lines.Text := strLog2;
Memo3.Lines.Text := strLog3;
end;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
// Width := Screen.Width;
// Height := Screen.Height;
Width := 800;
Height := 600;
Caption := Soft_Name;
end;
procedure TfrmMain.ClearCanvas(aCanvas: TCanvas);
begin
aCanvas.Brush.Style := bsSolid;
aCanvas.Brush.Color := clWhite;
aCanvas.FillRect(ClientRect);
end;
procedure TfrmMain.btnSetNumberClick(Sender: TObject);
begin
Application.MessageBox(strSetNumber,Soft_Name,MB_ICONINFORMATION);
end;
procedure TfrmMain.btnAutoClick(Sender: TObject);
begin
Application.MessageBox(strAutoAnswer,Soft_Name,MB_ICONINFORMATION);
end;
procedure TfrmMain.btnAboutClick(Sender: TObject);
begin
Application.MessageBox(About_Soft_Info,Soft_Name,MB_ICONINFORMATION);
end;
end.
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1299788
相關文章
- google經典演算法面試題-雞蛋問題Go演算法面試題
- 70個經典的 Shell 指令碼面試問題指令碼面試
- 八數碼 經典問題
- 經典演算法-最大流問題演算法
- 30 個 Openstack 經典面試問題和解答面試
- 5個經典的前端面試問題前端面試
- 16個經典面試問題及回答思路面試
- 經典演算法面試題(二)演算法面試題
- 70個經典面試問題,有備無患~面試
- 5個經典的JavaScript面試基礎問題JavaScript面試
- 覆盤 PHP 經典面試問題解決過程:上臺階問題PHP面試
- 【經典演算法問題】馬的遍歷【回溯】演算法
- UVA 11235 經典RMQ問題MQ
- 經典面試題面試題
- oracle經典亂碼問題——靠靠靠靠Oracle
- 揹包問題的一道經典問題
- 演算法面試:陣列編碼面試問題演算法面試陣列
- java經典面試題Java面試題
- javascript經典面試題JavaScript面試題
- Js 經典面試題JS面試題
- 前端經典面試題前端面試題
- 經典n皇后問題java程式碼實現Java
- Angular 2的12個經典面試問題彙總(文末附帶Angular測試)Angular面試
- SQL language裡面的經典問題SQL
- IOS面試經常被問到的問題iOS面試
- [面試題]事件迴圈經典面試題解析面試題事件
- 幾道 BAT 演算法面試中經常問的「字串」問題BAT演算法面試字串
- 一篇文章帶你搞定經典面試題之扔雞蛋問題面試題
- Google經典面試題解析Go面試題
- 經典Java面試題收集Java面試題
- C++經典面試題C++面試題
- 經典SQL面試題1SQL面試題
- 經典SQL面試題2SQL面試題
- 七大快取經典問題快取
- CSS 佈局經典問題初步整理CSS
- 面試70問經典回答技巧面試
- 面試70問經典回答 - 下面試
- 面試70問經典回答 - 上面試