import java.awt.*; import java.applet.*; import java.util.Vector; import java.util.Enumeration; class ReviseGenerator extends Dialog{ GridBagLayout gridbag; Button buttonOK; MyWindow myWindow; GridPanel myGrid; int mySegments; int upSegments; int numberOfTurns = 0; int turns[] = {0}; /* usually same number of entries as numberOfTurns */ int lastdirection; /* lastdirection = 0, 1, 2, or 3 */ int lastx, lasty; /* -2 <= lastx <= mySegments + 2 */ /* - upSegments <= lasty <= upSegments */ int lastturn; Model myModel; /* layout */ public ReviseGenerator(MyWindow aWindow, boolean modal, Model theModel, int segments){ super(aWindow, modal); setTitle("Generator"); setResizable(false); myWindow = aWindow; myModel = theModel; mySegments = segments; upSegments = (segments + 4) / 2; if (myModel != null) { numberOfTurns = myModel.numberOfTurns; int myturns[] = new int[numberOfTurns]; turns = myturns; for (int i = 1; i <= numberOfTurns; i++) turns[i - 1] = myModel.turns[i - 1]; } GridBagLayout gridbag = new GridBagLayout(); setLayout(gridbag); myGrid = new GridPanel(this); constrain(this, myGrid, 0, 0, 1, 1, GridBagConstraints.NONE, GridBagConstraints.NORTHWEST, 0.0, 0.0, 10, 10, 5, 5); Panel panel2 = new Panel(); panel2.setLayout(new GridLayout(5, 3, 6, 6)); constrain(this, panel2, 1, 0, 1, 1, GridBagConstraints.NONE, GridBagConstraints.CENTER, 0.0, 0.0, 10, 10, 5, 5); Panel empty1 = new Panel(); panel2.add(empty1); Button upButton = new Button("Up"); panel2.add(upButton); Panel empty2 = new Panel(); panel2.add(empty2); Button leftButton = new Button("Left"); panel2.add(leftButton); Panel empty3 = new Panel(); panel2.add(empty3); Button rightButton = new Button("Right"); panel2.add(rightButton); Panel empty4 = new Panel(); panel2.add(empty4); Button downButton = new Button("Down"); panel2.add(downButton); Panel empty5 = new Panel(); panel2.add(empty5); Panel empty6 = new Panel(); panel2.add(empty6); Panel empty7 = new Panel(); panel2.add(empty7); Panel empty8 = new Panel(); panel2.add(empty8); Panel empty9 = new Panel(); panel2.add(empty9); Button undoButton = new Button("Undo"); panel2.add(undoButton); Panel empty10 = new Panel(); panel2.add(empty10); Panel panelOK = new Panel(); panelOK.setLayout(gridbag); constrain(this, panelOK, 0, 1, 2, 1, GridBagConstraints.NONE, GridBagConstraints.NORTHEAST, 0.0, 0.0, 2, 2, 2, 2); Button buttonCancel = new Button("Cancel"); constrain(panelOK, buttonCancel, 0, 0, 1, 1, 5, 5, 5, 5); buttonOK = new Button("OK"); constrain(panelOK, buttonOK, 1, 0, 1, 1, 5, 5, 5, 5); pack(); move(60, 60); show(); } public void constrain(Container container, Component component, int grid_x, int grid_y, int grid_width, int grid_height, int fill, int anchor, double weight_x, double weight_y, int top, int left, int bottom, int right){ GridBagConstraints c = new GridBagConstraints(); c.gridx = grid_x; c.gridy = grid_y; c.gridwidth = grid_width; c.gridheight = grid_height; c.fill = fill; c.anchor = anchor; c.weightx = weight_x; c.weighty = weight_y; if (top + bottom + left + right > 0) c.insets = new Insets(top, left, bottom, right); ((GridBagLayout)container.getLayout()).setConstraints(component, c); container.add(component); } public void constrain(Container container, Component component, int grid_x, int grid_y, int grid_width, int grid_height){ constrain(container, component, grid_x, grid_y, grid_width, grid_height, GridBagConstraints.NONE, GridBagConstraints.NORTHWEST, 0.0, 0.0, 0, 0, 0, 0); } public void constrain(Container container, Component component, int grid_x, int grid_y, int grid_width, int grid_height, int top, int left, int bottom, int right){ constrain(container, component, grid_x, grid_y, grid_width, grid_height, GridBagConstraints.NONE, GridBagConstraints.NORTHWEST, 0.0, 0.0, top, left, bottom, right); } /* end layout */ public boolean handleEvent(Event e) { switch (e.id) { case Event.WINDOW_DESTROY: dispose(); return true; } return super.handleEvent(e); } public boolean action(Event e, Object arg){ int newsize; if (e.target instanceof Button) { if (((String)e.arg).equals("Up")) doUp(true); else if (((String)e.arg).equals("Down")) doDown(true); else if (((String)e.arg).equals("Left")) doLeft(true); else if (((String)e.arg).equals("Right")) doRight(true); else if (((String)e.arg).equals("Undo")) doUndo(); else if (((String)e.arg).equals("Cancel")) dispose(); else if (((String)e.arg).equals("OK")) { doOK(); dispose(); } return true; } return false; } public void doUp(boolean show) { int temp[] = new int[numberOfTurns + 1]; for (int i = 0; i < numberOfTurns; i++) temp[i] = turns[i]; if (lasty > (- upSegments)) { switch (lastdirection) { case 0: lastturn = 90; break; case 1: lastturn = 0; break; case 2: lastturn = - 90; break; case 3: lastturn = 180; break; } temp[numberOfTurns] = lastturn; numberOfTurns++; turns = temp; myGrid.repaintlast(show); } } public void doDown(boolean show) { int temp[] = new int[numberOfTurns + 1]; for (int i = 0; i < numberOfTurns; i++) temp[i] = turns[i]; if (lasty < upSegments) { switch (lastdirection) { case 0: lastturn = - 90; break; case 1: lastturn = 180; break; case 2: lastturn = 90; break; case 3: lastturn = 0; break; } temp[numberOfTurns] = lastturn; numberOfTurns++; turns = temp; myGrid.repaintlast(show); } } public void doLeft(boolean show) { int temp[] = new int[numberOfTurns + 1]; for (int i = 0; i < numberOfTurns; i++) temp[i] = turns[i]; if (lastx > (-2)) { switch (lastdirection) { case 0: lastturn = 180; break; case 1: lastturn = 90; break; case 2: lastturn = 0; break; case 3: lastturn = - 90; break; } temp[numberOfTurns] = lastturn; numberOfTurns++; turns = temp; myGrid.repaintlast(show); } } public void doRight(boolean show) { int temp[] = new int[numberOfTurns + 1]; for (int i = 0; i < numberOfTurns; i++) temp[i] = turns[i]; if (lastx < (mySegments + 2)) { switch (lastdirection) { case 0: lastturn = 0; break; case 1: lastturn = -90; break; case 2: lastturn = 180; break; case 3: lastturn = 90; break; } temp[numberOfTurns] = lastturn; numberOfTurns++; turns = temp; myGrid.repaintlast(show); } } public void doUndo() { if (numberOfTurns > 0) { numberOfTurns--; int temp[] = new int[numberOfTurns]; for (int i = 0; i < numberOfTurns; i++) temp[i] = turns[i]; turns = temp; myGrid.repaint(); } } public void doOK() { int size; int maxSafe; boolean found; Model tempModel; int finish = 1; Integer finishObj; fix(); if (myModel == null) { finishObj = new Integer(finish); String start = "Temp"; found = true; while (found) { found = false; Enumeration oldModels = myWindow.myModels.elements(); while ((!found) && oldModels.hasMoreElements()) { try { tempModel = (Model)oldModels.nextElement(); if (tempModel.name.equals(start + finishObj.toString())) { found = true; finish++; finishObj = new Integer(finish); } } catch(Exception e) ; } } String name = start + finishObj.toString(); size = 100; maxSafe = 4; myModel = new Model(size, mySegments, numberOfTurns, turns, maxSafe, name); fixSafe(); myWindow.myModels.addElement(myModel); MyCheckboxMenuItem newItem = new MyCheckboxMenuItem(name, myWindow.choiceGroup); myWindow.choiceMenu.add(newItem); myWindow.choiceGroup.setCurrent(newItem); } else { myModel.numberOfTurns = numberOfTurns; myModel.turns = turns; fixSafe(); } myWindow.drawArea.offscreenbad = true; myWindow.drawArea.repaint(); } public void fixSafe(){ int tempsafe = 1, tempsafe1 = 2; tempsafe = numberOfTurns; tempsafe1 = 1; if (numberOfTurns < 2) myModel.maxSafe = 6; else { do { tempsafe = tempsafe * numberOfTurns; tempsafe1++; } while (tempsafe < 1000); if (tempsafe1 > 6) tempsafe1 = 6; myModel.maxSafe = tempsafe1; } } public void fix(){ int amount; if (lastx < mySegments) { amount = mySegments - lastx; for (int i = 1; i <= amount; i++) doRight(false); } else if (lastx > mySegments) { amount = lastx - mySegments; for (int j = 1; j <= amount; j++) doLeft(false); } if (lasty < 0) { amount = - lasty; for (int k = 1; k <= amount; k++) doDown(false); } else if (lasty > 0) { amount = lasty; for (int m = 1; m <= amount; m++) doUp(false); } doRight(false); numberOfTurns--; } } class GridPanel extends Panel{ ReviseGenerator myRevise; int x0, y0; int dx, dy; int spacing; int spacesup; public GridPanel(ReviseGenerator aRevise){ myRevise = aRevise; } public Dimension minimumSize(){ Dimension d = new Dimension(310, 310); return d; } public Dimension preferredSize(){ return minimumSize(); } public void doOnePiece(int which, Graphics g){ turn(myRevise.turns[which - 1]); switch (myRevise.turns[which - 1]) { case 90: myRevise.lastdirection = (myRevise.lastdirection + 1) % 4; break; case -90: myRevise.lastdirection = (myRevise.lastdirection + 3) % 4; break; case 180: myRevise.lastdirection = (myRevise.lastdirection + 2) % 4; break; default: ; } if (dx > 0) myRevise.lastx++; else if (dx < 0) myRevise.lastx--; else if (dy > 0) myRevise.lasty++; else myRevise.lasty--; } public void paint(Graphics g){ Dimension r = size(); g.setColor(getBackground()); g.fillRect(0, 0, r.width, r.height); g.setColor(Color.black); spacing = 280 / (myRevise.mySegments + 4); spacesup = (myRevise.mySegments + 4) / 2; for (int i = 0; i <= 2 * spacesup; i++) { g.drawLine(10, 10 + spacing * i, 10 + spacing * (myRevise.mySegments + 4), 10 + spacing * i); } for (int j = 0; j <= (myRevise.mySegments + 4); j++) { g.drawLine(10 + spacing * j, 10, 10 + spacing * j, 10 + (spacing * 2 * spacesup)); } moveto(10 + 2 * spacing, 10 + spacing * spacesup); drawbox(g); moveto(10 + (2 + myRevise.mySegments) * spacing, 10 + spacing * spacesup); drawbox(g); moveto(10 + 2 * spacing, 10 + spacing * spacesup); initturtle(); myRevise.lastx = 0; myRevise.lasty = 0; myRevise.lastdirection = 0; if (myRevise.numberOfTurns > 0) for (int k = 1; k <= myRevise.numberOfTurns; k++) { doOnePiece(k, g); forward(spacing, g); } drawstar(g); } public void repaintlast(boolean show) { Graphics g = getGraphics(); spacing = 280 / (myRevise.mySegments + 4); spacesup = (myRevise.mySegments + 4) / 2; moveto(10 + 2 * spacing, 10 + spacing * spacesup); initturtle(); myRevise.lastx = 0; myRevise.lasty = 0; myRevise.lastdirection = 0; if (myRevise.numberOfTurns > 1) for (int k = 1; k <= myRevise.numberOfTurns - 1; k++) { doOnePiece(k, g); x0 = x0 + spacing * dx; y0 = y0 + spacing * dy; } if (show) drawstar(g); doOnePiece(myRevise.numberOfTurns, g); if (show) forward(spacing, g); else { x0 = x0 + spacing * dx; y0 = y0 + spacing * dy; } if (show) drawstar(g); } public void moveto(int x, int y){ x0 = x; y0 = y; } public void move(int x, int y){ x0 = x0 + x; y0 = y0 + y; } public void line(int x, int y, Graphics g){ g.drawLine(x0, y0, x0 + x, y0 + y); x0 = x0 + x; y0 = y0 + y; } public void thickline(int x, int y, Graphics g){ if (x > 0) { g.drawLine(x0, y0, x0 + x + 3, y0); g.drawLine(x0, y0 + 1, x0 + x + 3, y0 + 1); g.drawLine(x0, y0 + 2, x0 + x + 3, y0 + 2); g.drawLine(x0, y0 + 3, x0 + x + 3, y0 + 3); } else if (x < 0) { g.drawLine(x0 + 3, y0, x0 + x, y0); g.drawLine(x0 + 3, y0 + 1, x0 + x, y0 + 1); g.drawLine(x0 + 3, y0 + 2, x0 + x, y0 + 2); g.drawLine(x0 + 3, y0 + 3, x0 + x, y0 + 3); } else if (y > 0) { g.drawLine(x0, y0, x0, y0 + y + 3); g.drawLine(x0 + 1, y0, x0 + 1, y0 + y + 3); g.drawLine(x0 + 2, y0, x0 + 2, y0 + y + 3); g.drawLine(x0 + 3, y0, x0 + 3, y0 + y + 3); } else { g.drawLine(x0, y0 + 3, x0, y0 + y); g.drawLine(x0 + 1, y0 + 3, x0 + 1, y0 + y); g.drawLine(x0 + 2, y0 + 3, x0 + 2, y0 + y); g.drawLine(x0 + 3, y0 + 3, x0 + 3, y0 + y); } x0 = x0 + x; y0 = y0 + y; } public void drawbox(Graphics tempg){ move(-3, -3); line(6, 0, tempg); line (0, 6, tempg); line(-6, 0, tempg); line(0, -6, tempg); move(3, 3); } public void drawstar(Graphics g){ g.setXORMode(Color.white); move(-5, -5); line(11, 11, g); move(0, -11); line(-11, 11, g); move(5, -6); g.setPaintMode(); } public void initturtle() { dx = 1; dy = 0; } public void turn(int theta){ int temp; switch(theta) { case 0: break; case 90: temp = dx; dx = dy; dy = -temp; break; case -90: temp = dx; dx = - dy; dy = temp; break; case 180: dx = - dx; dy = - dy; break; } } public void forward(int d, Graphics g) { thickline(d * dx, d * dy, g); } }