Demo14.java Source code

Java tutorial

Introduction

Here is the source code for Demo14.java

Source

import java.awt.*;

import javax.swing.*;

import no.geosoft.cc.graphics.*;

/**
 * G demo program. Demonstrates:
 *
 * <ul>
 * <li>A sample game application
 * <li>Graphics animation
 * <li>GObject reparenting
 * </ul>
 * 
 * @author <a href="mailto:jacob.dreyer@geosoft.no">Jacob Dreyer</a>
 */
public class Demo14 extends JFrame {
    private TowersOfHanoi towersOfHanoi_;
    private GWindow window_;
    private Peg[] pegs_;
    private int nDiscs_;
    private JButton startButton_;

    public Demo14(int nDiscs) {
        super("G Graphics Library - Demo 14");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        nDiscs_ = nDiscs;

        // Create the graphic canvas
        window_ = new GWindow(new Color(200, 230, 200));
        getContentPane().add(window_.getCanvas());

        // Create scene
        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);

        // Add title object and add to scene
        scene.add(new Title());

        // Create the 3 pegs and add to the scene
        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]);
        }

        // Create the discs and add to the first peg
        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);

        // Create the puzzle and execute the solution
        towersOfHanoi_ = new TowersOfHanoi();
        towersOfHanoi_.solve();
    }

    public void discMoved(int source, int destination) {
        // This is the disc to move
        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();

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

        // Reparent peg
        pegs_[source].remove(disc);
        pegs_[destination].add(disc);

        // Animate horizontal movement
        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;
        }

        // Animate vertical down movement
        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);
        }
    }

    /**
     * Graphics representation of a peg.
     */
    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_);
        }
    }

    /**
     * Graphics representation of a disc.
     */
    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 for solving the "Towers of Hanoi" puzzle.
     */
    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;
        Demo14 demo = new Demo14(nDiscs);
    }
}