java实现汉诺塔.docx
《java实现汉诺塔.docx》由会员分享,可在线阅读,更多相关《java实现汉诺塔.docx(19页珍藏版)》请在冰豆网上搜索。
![java实现汉诺塔.docx](https://file1.bdocx.com/fileroot1/2023-4/20/436e413c-0a1d-4f52-9855-2029ea28a1ca/436e413c-0a1d-4f52-9855-2029ea28a1ca1.gif)
java实现汉诺塔
/**********************************************************
Hanoi11.java-TowerofHanoipuzzle
Version1.1
byBobKirkland
bob@
Downloadby
1.1-addedTimer,Titlebar
removedCCclass
**********************************************************/
importjava.applet.*;
importjava.awt.*;
import.*;
importjava.util.*;
/********HANOI11********
mainclass:
initializesappletpanel,startsgames,
runsautosolvethread,handlesdiscmovingevents
*/
publicclassHanoi11extendsAppletimplementsRunnable{
staticfinalFonttitleFont=newFont("Helvetica",Font.BOLD,12),
textFont=newFont("Helvetica",Font.PLAIN,11),
monoFont=newFont("Courier",Font.BOLD,12);
staticfinalintCANVAS_WIDTH=450,CANVAS_HEIGHT=250,TABLE_TOP=225,
PEG1=0,PEG2=1,PEG3=2,MIN_DISCS=3,MAX_DISCS=12;
privatebooleangameOver;
privateintsourceDisc,sourcePeg,targetPeg;
privateStringgameStatus;
privatePanelcpBack,titlePanel;
privateLabeltitleLabel;
privateBoardbd;
privateBoardCanvasbc;
privateStatusPanelsp;
privateControlPanelcp;
privateImageboardImage;
privateStringboardImageFile="board.gif";
privateThreadsolveThread,timer;
publicvoidinit(){
//loadboardimage
MediaTrackertracker=newMediaTracker(this);
URLurl=getCodeBase();
boardImage=getImage(url,boardImageFile);
tracker.addImage(boardImage,0);
try{tracker.waitForID(0);}
catch(InterruptedExceptione){}
//initializeappletlayout
setBackground(Color.black);
PanelmainPanel=newPanel();
mainPanel.setLayout(newBorderLayout(0,0));
//BoardCanvas
bc=newBoardCanvas(this);
bc.resize(CANVAS_WIDTH,CANVAS_HEIGHT);
//Titlepanel
titlePanel=newPanel();
titlePanel.setLayout(newGridLayout(1,1));
titlePanel.setBackground(Color.gray);
titlePanel.setFont(titleFont);
titlePanel.add(titleLabel=newLabel("TowerofHanoi1.1",Label.LEFT));
titleLabel.setForeground(Color.white);
//ControlPanel
cpBack=newPanel();
cpBack.setBackground(Color.gray);
cp=newControlPanel(this);
cpBack.add(cp);
//Statuspanel
sp=newStatusPanel(this);
sp.setBackground(Color.gray);
//constructappletpanel
mainPanel.add("Center",bc);
mainPanel.add("North",titlePanel);
mainPanel.add("East",cpBack);
mainPanel.add("South",sp);
add(mainPanel);
validate();
newGame();
}
//startup
voidnewGame(){
intdiscs=cp.getDiscs();
System.gc();
gameOver=false;
bd=newBoard(discs,this);
bc.drawBoard(bd,boardImage,0,0,0);
sp.setMoveCount(0);
if(cp.isTimerOn())timer=newTimer(cp);
elsecp.setTimer("");
if(solveThread==null)
sp.setStatus("Moveall"+discs+"discstotherightmostpeg.");
bc.requestFocus();
}
//handleResetevent
voidrestartGame(){
stop();
cp.setAutoSolveEnable(true);
newGame();
}
//killallthreads
publicvoidstop(){
if(solveThread!
=null){
solveThread.stop();
solveThread=null;
}
if(timer!
=null){
timer.stop();
timer=null;
}
}
//spawnAutosolvethread
publicvoidstartSolveThread(){
stop();
solveThread=newThread(this);
solveThread.start();
}
//runAutosolvethread
publicvoidrun(){
newGame();
sp.setStatus("Autosolving...");
solve(cp.getDiscs(),PEG1,PEG2,PEG3);
sp.setStatus("Finished!
");
gameOver=true;
solveThread=null;
cp.setAutoSolveEnable(true);
}
//here'sthefamousalgorithm
voidsolve(intdiscs,intsource,intaux,inttarget){
if(discs==0)return;//basetoendrecursion
solve(discs-1,source,target,aux);//recursivecall#1
bd.moveDisc(source,target);//movedisc
sp.setMoveCount(bd.getMoveCount());//updatedisplay
bc.drawBoard(bd,boardImage,0,0,0);
try{solveThread.sleep(cp.getDelay());}//Autosolvedelay
catch(InterruptedExceptione){}
solve(discs-1,aux,source,target);//recursivecall#2
}
//handlemousedragevent
voiddragDisc(intx,inty){
if(!
gameOver&&(sourceDisc!
=0))
bc.drawBoard(bd,boardImage,sourceDisc,x,y);
}
//handlemousedownevent
voidselectDisc(intx,inty){
if(!
gameOver&&(solveThread==null)){
if((timer!
=null)&&(!
timer.isAlive()))timer.start();
sourcePeg=pixelToPeg(x,y);
if(bd.isStartPeg(sourcePeg)){
sourceDisc=bd.getTopDisc(sourcePeg);
bc.drawBoard(bd,boardImage,sourceDisc,x,y);
}
}
}
//handlemouseupevent
voiddropDisc(intx,inty){
if(!
gameOver&&(sourceDisc!
=0)){
targetPeg=pixelToPeg(x,y);
if(bd.moveDisc(sourceDisc,sourcePeg,targetPeg)){
gameStatus=bd.getBoardStatus();
sp.setMoveCount(bd.getMoveCount());
if(gameStatus==null)
sp.setStatus("Theminimumnumberofmovesrequiredis"+
bd.getMinMoves()+".");
else{
gameOver=true;
stop();
sp.setStatus(gameStatus);
}
}
bc.drawBoard(bd,boardImage,0,0,0);
sourceDisc=0;
}
}
//conversionformousedown/upevents
intpixelToPeg(intx,inty){
intpeg=-1;
if((y>40)&&(yif((x>50)&&(x<100))peg=PEG1;
elseif((x>200)&&(x<250))peg=PEG2;
elseif((x>350)&&(x<400))peg=PEG3;
}
returnpeg;
}
}
/********TIMER********
controlsTimerthread
*/
finalclassTimerextendsThread{
staticfinalintONE_SECOND=1000;
privatelongstartTime,rem;
privateinthours,min,sec;
privateStringsMin,sSec,sTime;
privateControlPanelcp;
//constructor
Timer(ControlPanelcp){
this.cp=cp;
cp.setTimer(setTime(0));
}
//runthread
publicvoidrun(){
startTime=System.currentTimeMillis();
while(true){
try{Thread.sleep(ONE_SECOND);}
catch(InterruptedExceptione){}
cp.setTimer(setTime(System.currentTimeMillis()-startTime));
}
}
//returnh:
mm:
ssstringfrommilliseconds
StringsetTime(longmillisec){
hours=(int)(millisec/3600000);
rem=millisec-(hours*3600000);
min=(int)(rem/60000);
rem=rem-(min*60000);
sec=(int)(rem/1000);
sMin=Integer.toString(min);
if(sMin.length()==1)sMin="0"+sMin;
sSec=Integer.toString(sec);
if(sSec.length()==1)sSec="0"+sSec;
sTime=""+Integer.toString(hours)+":
"+sMin+":
"+sSec;
returnsTime;
}
}
/********BOARD********
controlsdiscpositions,rulesformovingdiscs
*/
finalclassBoard{
staticfinalintPEGS=3,
DISC_SIZES[][]={{68,18},{76,16},{84,14},{92,13},{100,12},
{108,12},{112,11},{116,10},{120,9},{124,9}};
privateintpeg[][],pegTop[]=newint[PEGS],discWidth[];
privateintdiscs,moveCount,minMoves;
privateHanoi11main;
//constructor
Board(intdiscs,Hanoi11main){
this.discs=discs;
this.main=main;
peg=newint[discs][PEGS];
//putallthedisksonthefirstpeg
for(inti=0;ipegTop[main.PEG1]=discs-1;
for(inti=1;i//calculatediscwidths
discWidth=newint[discs];
for(inti=discs-1;i>=0;i--)
discWidth[i]=DISC_SIZES[discs-main.MIN_DISCS][0]-
(DISC_SIZES[discs-main.MIN_DISCS][1]*
(discs-1-i));
moveCount=0;
//minimummovesis(2**discs)-1
minMoves=((int)Math.pow(2.0,discs))-1;
}
voidsetDisc(intd,intp){peg[++pegTop[p]][p]=d;}
intgetDisc(intd,intp){returnpeg[d][p];}
intgetTopDisc(intp){returnpeg[pegTop[p]--][p];}
intgetPegTop(intp){returnpegTop[p];}
intgetMoveCount(){returnmoveCount;}
intgetMinMoves(){returnminMoves;}
intgetDiscWidth(intd){returndiscWidth[d-1];}
booleanisStartPeg(inti){
if((i>=0)&&(pegTop[i]>=0))returntrue;
elsereturnfalse;
}
StringgetBoardStatus(){
Stringstatus=null;
if(pegTop[PEGS-1]==(discs-1)){
if(moveCount==minMoves)
status="Congratulations!
";
elsestatus="Youdidit!
Nowtryagain,makingonly"+minMoves+"moves.";
}
returnstatus;
}
//manualmove
booleanmoveDisc(intd,intp1,intp2){
if((p1>=0)&&(p2>=0)){
//todifferentpegwhichisemptyorhaslargerdisc
if((p1!
=p2)&&((pegTop[p2]<0)||(peg[pegTop[p2]][p2]>d))){
setDisc(d,p2);
moveCount++;
returntrue;
}
}
setDisc(d,p1);
returnfalse;
}
//AutoSolvemove
voidmoveDisc(intp1,intp2){
setDisc(getTopDisc(p1),p2);
moveCount++;
}
}
/********BOARDCANVAS********
drawstheboardusingdoublebuffer,
passescanvasmouseeventstomainclass
*/
finalclassBoardCanvasextendsCanvas{
staticfinalintPEG_SPACE=75,DISC_HEIGHT=15;
staticfinalColorCOLOR_1=newColor(102,51,0),
COLOR_2=newColor(153,102,0),
COLOR_3=newColor(204,153,51),
COLOR_4=newColor(255,204,0),
COLOR_5=newColor(255,255,204);
privateImagebufferImage;
privateGraphicsbuffer;
privateHanoi11main;
//constructor
BoardCanvas(Hanoi11main){
this.main=main;
}
voiddrawBoard(Boardb,ImageboardImage,intdragDisc,intdragX,intdragY){
intwidth=0,disc=0;
if(buffer==null){
bufferImage=createImage(main.CANVAS_WIDTH,main.CANVAS_HEIGHT);
buffer=bufferImage.getGraphics();
}
//drawboard
buffer.drawImage(boardImage,0,0,this);
//drawdiscs
for(intp=main.PEG1;p<=main.PEG3;p++){
for(intd=0;d<=b.getPegTop(p);d++){
disc=b.getDisc(d,p);
if(disc!
=0){
width=b.getDiscWidth(disc);
drawDisc((((2*p)+1)*PEG_SPACE)-((int)(width/2)),
main.TABLE_TOP-((d+1)*DISC_HEIGHT),width);
}
}
}
//drawdraggeddisc
if(dragDisc!
=0){
width=b.getDiscWidth(dragDisc);
drawDisc(dragX-(int)(width/2),
dragY-(int)(DISC_HEIGHT*.75),width);
}
repaint();
}
//drawsingledisc15pixelheightwithprimitives
voiddrawDisc(intx,inty,intwidth){
buffer.setColor(COLOR_3);
buffer.drawLine(x+4,y,x+width-4,y);//1
buffer.dr