//-------------------------- // triangle.java // // by Lei Yu // May 6, 1996 //-------------------------- import java.applet.*; import java.awt.*; import java.awt.image.*; import java.lang.Math; import java.net.*; import java.util.*; public class triangle extends Applet { Trianglewindow Twin; Frame f; // from peg number to peg position (x,y) public final int loc[] = { 100, 30, 85, 60, 115, 60, 70, 90, 100, 90, 130, 90, 55, 120, 85, 120, 115, 120, 145, 120, 40, 150, 70, 150, 100, 150, 130, 150, 160, 150}; public final int radius = 10; public final int num = 15; Circle peg[]; int oldPos, newPos, interPos; int left; int initial = 4; //initial hole position boolean drag; public void init() { resize(230, 230); // generate pegs peg = new Circle[num]; for (int i = 0; i < num; i++) peg[i] = new Circle(loc[2*i], loc[2*i+1], radius); initPegs(); } public void initPegs() { int open; // set all holes to have pegs for (int i = 0; i < num; i++) peg[i].occupied = true; // generate the empty hole //open = (int)Math.round(Math.random()*num); open = initial; peg[open].occupied = false; // how many pegs left left = num - 1; } public void paint(Graphics g) { // reset parameters drag = false; oldPos = newPos = interPos = 0; // draw the board g.setColor(Color.black); g.fillRect(0, 0, 230, 230); g.setColor(Color.white); g.fillRect(2, 2, 228, 228); g.setColor(Color.lightGray); g.drawLine(105, 35, 45, 155); g.drawLine(105, 35, 165, 155); g.drawLine(45, 155, 165, 155); g.drawLine(90, 65, 135, 155); g.drawLine(120, 65, 75, 155); g.drawLine(90, 65, 120, 65); g.drawLine(75, 95, 135, 95 ); g.drawLine(75, 95, 105, 155 ); g.drawLine(60, 125, 150, 125); g.drawLine(60, 125, 75, 155); g.drawLine(135, 95, 105, 155); g.drawLine(150, 125, 135, 155); // Show what's peg and what's hole g.setColor(Color.black); g.drawString("Peg = ", 10, 40); g.setColor(Color.blue); g.fillOval(50, 30, radius, radius); g.setColor(Color.black); g.drawString("Hole = ", 5, 70); g.setColor(Color.black); g.fillOval(50, 60, radius, radius); // paint pegs for (int i = 0; i < num; i++) peg[i].paint(g); // number of pegs left g.setColor(Color.red); g.drawString("Pegs left = "+Integer.toString(left), 65, 20); // Initial hole position g.setColor(Color.magenta); g.drawString("Set 1st hole at "+Integer.toString(initial), 55, 178); // + button g.setColor(Color.lightGray); g.fill3DRect(87, 185, 20, 15, true); g.setColor(Color.black); g.drawLine(92, 192, 102, 192); g.drawLine(97, 187, 97, 197); // - button g.setColor(Color.lightGray); g.fill3DRect(107, 185, 20, 15, true); g.setColor(Color.black); g.drawLine(112, 192, 122, 192); // window button g.setColor(Color.lightGray); g.fill3DRect(15, 205, 55, 20, true); g.setColor(Color.black); g.drawString("Window", 18, 220); // restart button g.setColor(Color.lightGray); g.fill3DRect(80, 205, 55, 20, true); g.setColor(Color.black); g.drawString("Restart", 85, 220); // solve button g.setColor(Color.lightGray); g.fill3DRect(145, 205, 55, 20, true); g.setColor(Color.black); g.drawString("Solve", 155, 220); } // determine where peg is clicked public int where(int x, int y) { for (int i = 0; i < num; i++) if (peg[i].inside(x, y)) return i; // no peg is clicked return -1; } // in mouseDown, mouseUp, mouseDrag: // return false - event will get processed // return true - event will be ignored public boolean mouseDown(Event evt, int x, int y) { // is it request for window if ((x > 15) && (x < 70) && (y > 205) && (y < 225)) { f = new Frame("Triangle Puzzle Message Window"); f.resize(0,0); f.show(); Twin = new Trianglewindow (f, "Triangle Puzzle Message Window", "starting Triangle Puzzle"); Twin.resize(230, 300); Twin.show(); Twin.write_msg("starting Triangle Puzzle"); } // is it request for restart if ((x > 80) && (x < 135) && (y > 205) && (y < 225)) { initPegs(); repaint(); return false; } // is it request for solve if ((x > 145) && (x < 200) && (y > 205) && (y < 225)) { f = new Frame("Triangle Puzzle Message Window"); f.resize(0,0); f.show(); Twin = new Trianglewindow (f, "Triangle Puzzle Message Window", "Solving the puzzle"); Twin.resize(250, 300); Twin.show(); Twin.write_msg("You are SMARTER than me !!!\n"+"Try it out :)"); } // is it + request for resetting initial hole if ((x > 87) && (x < 107) && (y > 185) && (y < 200)) { if (initial < 14){ initial ++; repaint(); } else repaint(); return false; } // is it - request for resetting initial hole if ((x > 107) && (x < 127) && (y > 185) && (y < 200)) { if (initial > 0){ initial --; repaint(); } else repaint(); return false; } if ((oldPos = where(x, y)) < 0) return true; // does the move-from hole have a peg if (peg[oldPos].occupied) return false; else return true; } public boolean mouseDrag(Event evt, int x, int y) { drag = true; return false; } public boolean mouseUp(Event evt, int x, int y) { int a, b; if (drag) { drag = false; if ((newPos = where(x, y)) < 0) return true; // does the move-to have have a peg if (peg[newPos].occupied) return true; else { // determine the intermediate hole a = (peg[oldPos].X + peg[newPos].X) / 2; b = (peg[oldPos].Y + peg[newPos].Y) / 2; // is it a valid jump if (((interPos = where(a, b)) < 0) || (interPos == oldPos) || (interPos == newPos) || (!peg[interPos].occupied)) return true; else { // valid jump peg[oldPos].occupied = false; peg[newPos].occupied = true; peg[interPos].occupied = false; left--; repaint(); return true; } } } else return true; } } class Circle { public int X, Y, R; public boolean occupied; Circle(int x, int y, int r) { X = x; Y = y; R = r; } public boolean inside(int x, int y) { // use sqrt(x^2 + y^2) to determine the distance // between mouse click and circle center double dis = Math.sqrt(Math.pow((double)(X-x), 2) + Math.pow((double)(Y-y), 2)); if (dis <= R) return true; else return false; } public void paint(Graphics g) { if (occupied) g.setColor(Color.blue); else g.setColor(Color.black); g.fillOval(X, Y, R, R); } } class Trianglewindow extends Dialog { protected Button button; protected TextField inputfield; protected TextArea outputarea; public Trianglewindow (Frame parent, String title, String message) { // Create a dialog with the specified title super(parent, title, false); this.resize(230, 300); // Create and use a BorderLayout manager with margins this.setLayout(new BorderLayout(15, 15)); // Create input and output fields inputfield = new TextField(15); outputarea = new TextArea(); outputarea.setEditable(false); this.add("Center", outputarea); // Create QUIT button in panel; add Panel to window // Use a FlowLayout to center the button button = new Button("QUIT"); Panel p = new Panel(); p.setLayout(new FlowLayout(FlowLayout.CENTER, 15, 15)); p.add(button); this.add("South", p); // Resize the window to preferred size of components this.pack(); } public boolean action(Event e, Object what) { if (e.target instanceof Button) { String label = (String)what; if (label.equals ("QUIT")) { if (this.isShowing()) { this.hide(); this.dispose(); } } return true; } return false; } // When the window gets keyboard focus, give it to button. // This allows keyboard shortcuts to pop down the dialog. public boolean gotFocus (Event e, Object arg) { button.requestFocus(); return true; } public void write_msg(String message) { outputarea.setText(message); this.show(); } public void kill() { this.hide(); this.dispose(); } }