Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

this is problem PP12.12 in Java software solutions (Lewis Loftus) it is also pro

ID: 647424 • Letter: T

Question

this is problem PP12.12 in Java software solutions (Lewis Loftus) it is also probably in earlier editions.

Design and implement a graphical version of the Towers of Hanoi puzzel. (For simplicity fix the number of disks to 3) or if you would like you can allow the user to set the number of disks used in the puzzle.

The user should be able to interact with the puzzle in two main ways. The user can move the disks from one peg to another using the mouse, in which case the program should ensure that each move is legal. The user can also watch a solution take place as an animation, with pause/resume buttons. Permit the user to control the speed of the animation.

Explanation / Answer

import java.awt.*;

import javax.swing.*;

import no.geosoft.cc.graphics.*;

public class Hanoi extends JFrame{
private TowersOfHanoi towersOfHanoi_;
private GWindow window_;
private Peg[] pegs_;
private int nDiscs_;
private JButton startButton_;
  
  
  
public Hanoi (int nDiscs)
{
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

nDiscs_ = nDiscs;

window_ = new GWindow (new Color (200, 230, 200));
getContentPane().add (window_.getCanvas());
  
GScene scene = new GScene (window_);
double w0[] = {0.0, 0.0, 0.0};
double w1[] = {4.0, 0.0, 0.0};
double w2[] = {0.0, nDiscs_ * 2, 0.0};
scene.setWorldExtent (w0, w1, w2);

scene.add (new Title());
  
int nPegs = 3;
pegs_ = new Peg[nPegs];
for (int i = 0; i < nPegs; i++) {
pegs_[i] = new Peg (i + 1.0);
scene.add (pegs_[i]);
}

for (int i = 0; i < nDiscs; i++) {
Disc disc = new Disc ((double) (nDiscs - i) / nDiscs);
disc.setPosition (1.0, i);
pegs_[0].add (disc);
}

pack();
setSize (new Dimension (500, 500));
setVisible (true);

towersOfHanoi_ = new TowersOfHanoi();
towersOfHanoi_.solve();
}

public void discMoved (int source, int destination)
{
Disc disc = (Disc) pegs_[source].getChild (pegs_[source].getNChildren()-1);
  
double y0 = disc.getY();
double y1 = nDiscs_ + 4.0;

double x0 = pegs_[source].getX();
double x1 = pegs_[destination].getX();

double step = 0.2;
double y = y0;
while (y < y1) {
disc.setPosition (x0, y);
disc.redraw();
window_.refresh();
y += step;
}

pegs_[source].remove (disc);
pegs_[destination].add (disc);
  
step = 0.05;
double x = x0;
while (x != x1) {
disc.setPosition (x, y);
disc.redraw();
window_.refresh();
x += (x1 > x0 ? step : -step);
if (Math.abs (x - x1) < 0.01) x = x1;
}
  
step = 0.2;
y = y1;
y1 = pegs_[destination].getNChildren() - 1;
while (y > y1) {
if (Math.abs (y - y1) < 0.01) y = y1;
disc.setPosition (x, y);
disc.redraw();
window_.refresh();
y -= step;
}
}
  

  
/**
* Graphics object for canvas title.
*/
class Title extends GObject
{
private GSegment anchor_;
  
public Title()
{
GStyle style = new GStyle();
style.setLineStyle (GStyle.LINESTYLE_INVISIBLE);
style.setForegroundColor (new Color (100, 100, 200));
style.setFont (new Font ("serif", Font.PLAIN, 36));
setStyle (style);

anchor_ = new GSegment();
addSegment (anchor_);
  
GText text = new GText ("Towers of Hanoi", GPosition.SOUTHEAST);
anchor_.setText (text);
}
  
  
public void draw()
{
anchor_.setGeometry (20, 20);
}
}
  
class Peg extends GObject
{
private double x_;
private GSegment peg_;
private double[] xy_;
  
  
public Peg (double x)
{
x_ = x;

GStyle style = new GStyle();
style.setBackgroundColor (new Color (100, 100, 100));
setStyle (style);

peg_ = new GSegment();
addSegment (peg_);

xy_ = new double[] {x_ - 0.05, 0.0,
x_ - 0.05, nDiscs_ + 2,
x_ + 0.05, nDiscs_ + 2,
x_ + 0.05, 0.0,
x_ - 0.05, 0.0};
}


public double getX()
{
return x_;
}
  

public void draw()
{
peg_.setGeometryXy (xy_);
}
}
  
class Disc extends GObject
{
private double size_;
private GSegment disc_;
private double x_, y_;
  

public Disc (double size)
{
size_ = size;
  
GStyle style = new GStyle();
style.setForegroundColor (new Color (255, 0, 0));
style.setBackgroundColor (new Color (255, 150, 150));
setStyle (style);
  
disc_ = new GSegment();
addSegment (disc_);
}


public void setPosition (double x, double y)
{
x_ = x;
y_ = y;
}


public double getY()
{
return y_;
}
  
  
public void draw()
{
double[] xy = new double[] {x_ - size_ / 2.0, y_,
x_ - size_ / 2.0, y_ + 1.0,
x_ + size_ / 2.0, y_ + 1.0,
x_ + size_ / 2.0, y_,
x_ - size_ / 2.0, y_};

disc_.setGeometryXy (xy);
}
}
  
class TowersOfHanoi
{
public void solve()
{
solve (nDiscs_, 0, 2, 1);
}
  
  
private void solve (int nDiscs, int source, int destination, int auxiliary)
{
if (nDiscs == 1)
discMoved (source, destination);
  
else if (nDiscs > 1) {
solve (nDiscs - 1, source, auxiliary, destination);
discMoved (source, destination);
solve (nDiscs - 1, auxiliary, destination, source);
}
}
}
  
  

public static void main (String[] args)
{
int nDiscs = 8;
Hanoi demo = new Hanoi (nDiscs);
}
}