/* Written by Matt Taylor */ import java.awt.*; import java.applet.Applet; import java.util.Random; import java.lang.Number; import java.util.Vector; import java.net.URL; import java.net.URLConnection; import java.io.DataInputStream; import java.io.IOException; import java.io.BufferedInputStream; import java.net.MalformedURLException; public class nQueens extends Applet implements Runnable { private Button DDFSButton; private Button RDFSButton; private Button LocalSearchButton; private Button HaltButton; private Button RestoreButton; private Button ClearButton; private Button SetUpButton; private Button RedrawButton; private Button AboutButton; private Scrollbar N; private Label NLabel; private TextField NValue; private Scrollbar Delay; private Label DelayLabel; private TextField DelayValue; private TextField DelayField; private Scrollbar Cutoff; private Label CutoffLabel; private TextField CutoffValue; private TextArea Output; private Label OutputLabel; private TextField OutputValue; private TextArea AboutBox; //private Color[][] Board; private static boolean InitialBoard [][]; private static boolean CurrentBoard [][]; private static int Attacks [][]; private static int iAttacks[][]; private Thread SearchThread; private MediaTracker ImageTracker; private Image queen; private String LoadImage; private static boolean Halt; private int Status; private static int Backtracks; private static boolean solved; private int Search; private static boolean canChange; private static int n; private static int Moves; private static int SquareWidth; private static int Qx[]; private static int Qy[]; private static int iQx[]; private static int iQy[]; private static int MaxAttackQx[]; private static int MaxAttackQy[]; private static int NoAttacks[]; private static int AttackTracker[]; private static int iAttackTracker[]; private static int StartSquare[]; private static int PlacedQ; private static int QonBoard; private static int BoardSize; private boolean noCutoff; private boolean Qfound; private boolean Check; private boolean about; private boolean JustPlaced[]; private boolean QinRow[]; private int x1, y1; private int p, p1, p2; private int diff; private int bound; private int Qcount1, Qcount2; private int MaxAttack; private int TrueMaxAttack; private int BestIndex; private int Qindex; private int xValue; private int CurrentRow; private int Hindent, Vindent; private Vector rows; //private Vector random; private int random[]; private URL uRL; private String string; private DataInputStream dataInputStream; private URLConnection uRLConnection; public void init() { setBackground(Color.black); setForeground(Color.white); setFont(new Font("SansSerif", 0, 11)); setLayout(null); DDFSButton= new Button("Deterministic DFS"); DDFSButton.reshape(22, 25, 115, 20); DDFSButton.setForeground(Color.black); add(DDFSButton); RDFSButton= new Button("Random DFS"); RDFSButton.reshape(22, 47, 115, 20); RDFSButton.setForeground(Color.black); add(RDFSButton); LocalSearchButton = new Button("Optimized LS"); LocalSearchButton.reshape(22, 85, 115, 20); LocalSearchButton.setForeground(Color.black); add(LocalSearchButton); Cutoff = new Scrollbar(Scrollbar.HORIZONTAL, 500, 0, 0, 32001); Cutoff.reshape(22, 123, 115, 10); add(Cutoff); CutoffLabel = new Label("Cutoff:"); CutoffLabel.reshape(26, 135, 40, 17); CutoffLabel.setBackground(Color.black); CutoffLabel.setForeground(Color.white); add(CutoffLabel); CutoffValue = new TextField(Integer.toString(Cutoff.getValue())); CutoffValue.reshape(70, 135, 55, 17); CutoffValue.setBackground(Color.black); CutoffValue.setForeground(Color.white); CutoffValue.setEditable(false); add(CutoffValue); Delay = new Scrollbar(Scrollbar.HORIZONTAL, 0, 0, 0, 500); Delay.reshape(22, 155, 115, 10); add(Delay); DelayLabel = new Label ("Delay:"); DelayLabel.reshape(26, 167, 40, 17); DelayLabel.setBackground(Color.black); DelayLabel.setForeground(Color.white); add(DelayLabel); DelayValue = new TextField(Integer.toString(Delay.getValue())); DelayValue.reshape(70, 167, 55, 17); DelayValue.setBackground(Color.black); DelayValue.setForeground(Color.white); add(DelayValue); HaltButton = new Button("Halt Search"); HaltButton.reshape(22, 188, 115, 20); HaltButton.setForeground(Color.black); add(HaltButton); RestoreButton = new Button("Restore Start Board"); RestoreButton.reshape(22, 227, 115, 20); RestoreButton.setForeground(Color.black); add(RestoreButton); ClearButton = new Button("Clear Board"); ClearButton.reshape(22, 249, 115, 20); ClearButton.setForeground(Color.black); add(ClearButton); SetUpButton = new Button("Pre-Place Queens"); SetUpButton.reshape(22, 271, 115, 20); SetUpButton.setForeground(Color.black); add(SetUpButton); N = new Scrollbar(Scrollbar.HORIZONTAL, 5, 0, 5, 100); N.reshape(22, 293, 115, 10); add(N); NLabel = new Label("N:"); NLabel.reshape(26, 305, 40, 17); NLabel.setBackground(Color.black); NLabel.setForeground(Color.white); add(NLabel); NValue = new TextField(Integer.toString(N.getValue())); NValue.reshape(70, 305, 55, 17); NValue.setBackground(Color.black); NValue.setForeground(Color.white); NValue.setEditable(false); add(NValue); RedrawButton = new Button("Resize Board"); RedrawButton.reshape(22, 324, 115, 20); RedrawButton.setForeground(Color.black); RedrawButton.enable(false); add(RedrawButton); Output = new TextArea("Output: \n", 134, 160); Output.setBackground(Color.black); Output.setForeground(Color.white); Output.reshape(12, 346, 134, 160); Output.setEditable(false); add(Output); //AboutButton = new Button("About N-Queens"); //AboutButton.reshape(12, 688, 134, 20); //AboutButton.setForeground(Color.black); //add(AboutButton); about = false; ImageTracker = new MediaTracker(this); queen = getImage(getCodeBase(),"queen.jpg"); ImageTracker.addImage(queen, 0); /*try { ImageTracker.waitForAll(); } catch (InterruptedException e){ } paintString("Test", 400, 600, getGraphics()); while(ImageTracker.checkAll()){ paintString(LoadImage, 400, 600, getGraphics()); }*/ reInit(); //allabout(getGraphics()); } //end init() public boolean reInit(){ n = N.getValue(); InitialBoard = new boolean[n][n]; CurrentBoard = new boolean[n][n]; Attacks = new int [n][n]; iAttacks = new int [n][n]; Qx = new int[n]; Qy = new int[n]; iQx = new int[n]; iQy = new int[n]; MaxAttackQx = new int[n]; MaxAttackQy = new int[n]; NoAttacks = new int[n]; JustPlaced = new boolean[n]; QinRow = new boolean [n]; AttackTracker = new int[n+1]; iAttackTracker = new int[n+1]; StartSquare = new int[n]; rows = new Vector(n); SquareWidth = (int)(500/n); BoardSize = n * SquareWidth; //black out old board (if any) and calcualate board dimensions + location //g.setColor(Color.black); //g.fillRect(152, 4, 710, 708); //g.setColor(Color.lightGray); Hindent = 152 + (int)((510-BoardSize)/2); Vindent = 4+ (int)((510-BoardSize)/2); Backtracks = 0; PlacedQ = 0; QonBoard = 0; noCutoff=false; //verbose = false; solved = false; canChange = false; Qfound = false; //about = false; SetUpButton.setLabel("Pre-Place Queens"); Search = 0; Moves = 0; for (int i = 0; i < n; i++){ Qx[i] = -1; Qy[i] = -1; iQx[i] = -1; iQy[i] = -1; AttackTracker[i] = 0; iAttackTracker[i] = 0; MaxAttackQx[i] = -1; MaxAttackQy[i] = -1; JustPlaced[i] = false; QinRow[i] = false; NoAttacks[i] = 0; StartSquare[i] = 0; for (int j = 0; j < n; j++) { InitialBoard[i][j] = false; CurrentBoard[i][j] = false; Attacks[i][j] = 0; iAttacks[i][j] = 0; } } AttackTracker[0] = n*n; iAttackTracker[0] = n*n; AttackTracker[n] = 0; iAttackTracker[n] = 0; paint(getGraphics()); return true; } //paint (graphics g); public void paintString(String theString, int xcoord, int ycoord, Graphics g){ g.drawString(theString, xcoord, ycoord); } public void blackout(Graphics g) { //SquareWidth = (int)(700/n); //BoardSize = n * SquareWidth; //black out old board (if any) and calcualate board dimensions + location g.setColor(Color.black); g.fillRect(152, 4, 710, 708); //g.setColor(Color.lightGray); //Hindent = 152 + (int)((710-BoardSize)/2); //Vindent = 4+ (int)((710-BoardSize)/2); //g.drawRect(Hindent-2, Vindent-2, BoardSize+3, BoardSize+3); } public void start() { if (SearchThread == null) { SearchThread = new Thread(this); SearchThread.start(); } } //end start() public void stop() { if (SearchThread != null && SearchThread.isAlive()) SearchThread.stop(); SearchThread = null; } //end stop() public void run(){ try { ImageTracker.waitForAll(); } catch (InterruptedException e) { SearchThread.stop(); } do { while (Search == 0) { try { SearchThread.sleep(150); } catch (InterruptedException e) { } } Halt = false; canChange = false; SetUpButton.setLabel("Board in Use"); SetUpButton.enable(false); RestoreButton.enable(false); ClearButton.enable(false); RedrawButton.enable(false); N.enable(false); DDFSButton.enable(false); RDFSButton.enable(false); LocalSearchButton.enable(false); Output.setText("Output: \n"); if (Search == 4) { allabout(getGraphics()); } else { if (Search == 1){ if (DDFS()){ Output.appendText("Solved! \n"); Output.appendText("Backtracks: " + Backtracks + "\n"); } else { if (Halt){ Output.appendText("Halted! \n"); Output.appendText("Backtracks: \n" + Backtracks + "\n"); } else if (!pastCutoff(Backtracks)){ //Output.appendText(noCutoff + "/n"); Output.appendText("No Solution!! \n"); Output.appendText("Backtracks: " + Backtracks + "\n"); } else { //Output.appendText(noCutoff + "/n"); Output.appendText("Not Solved Yet! \n"); Output.appendText("Backtracks: " + Backtracks + "\n"); } } } else if (Search == 2) { randomOrder(n); if(RDFS()){ Output.appendText("Solved! \n"); Output.appendText("Backtracks: " + Backtracks + "\n"); } else { if (Halt){ Output.appendText("Halted! \n"); Output.appendText("Backtracks: \n" + Backtracks + "\n"); } else if (!pastCutoff(Backtracks)){ //Output.appendText(noCutoff + "/n"); Output.appendText("No Solution!! \n"); Output.appendText("Backtracks: " + Backtracks + "\n"); } else { //Output.appendText(noCutoff + "/n"); Output.appendText("Not Solved Yet! \n"); Output.appendText("Backtracks: " + Backtracks + "\n"); } } } else { if(LocalSearch()) { Output.appendText("Solved! \n"); Output.appendText("Moves: " + Moves + "\n"); } else{ //Moves -= 1; if(Halt){ Output.appendText("Halted! \n"); Output.appendText("Moves: " + Moves + "\n"); } else{ Output.appendText("Not Solved Yet! \n"); Output.appendText("Moves: " + Moves + "\n"); } } } if(solved){ Output.appendText("Queens: \n"); for(int i=0; i< QonBoard; i++){ Output.appendText("#" + (i+1) + ": (" + Qx[i] + ", " + Qy[i] + ") \n"); } } //paint(getGraphics()); Search = 0; SetUpButton.setLabel("Pre-Place Queens"); //SetUpButton.enable(true); canChange = false; RestoreButton.enable(true); ClearButton.enable(true); N.enable(true); if (n != N.getValue()){ RedrawButton.enable(true); } } } while (true); } //end run() public boolean action(Event e, Object o){ if (e.target == DDFSButton){ Search = 1; } else if (e.target == RDFSButton){ Search = 2; } else if (e.target == LocalSearchButton){ Search = 3; } else if (e.target == HaltButton){ Halt = true; } else if (e.target == RestoreButton) { Restore(true); } else if (e.target == ClearButton){ Restore(false); } else if (e.target == SetUpButton){ if (canChange){ canChange = false; SetUpButton.setLabel("Pre-Place Queens"); PlacedQ = QonBoard; for (int i = 0; i < n; i++){ iQx[i] = Qx[i]; iQy[i] = Qy[i]; QinRow[i] = false; for (int j = 0; j < n; j++){ iAttacks[i][j] = Attacks[i][j]; iAttackTracker[i] = AttackTracker[i]; InitialBoard[i][j] = CurrentBoard[i][j]; } } for (int i = 0; i < QonBoard; i++){ QinRow[Qy[i]] = true; //Output.appendText("Qy[" + i + "]=" + Qy[i] + "\n"); } iAttackTracker[QonBoard] = AttackTracker[QonBoard]; RestoreButton.enable(true); LocalSearchButton.enable(true); DDFSButton.enable(true); RDFSButton.enable(true); } else { canChange = true; SetUpButton.setLabel("End Set Up"); RestoreButton.enable(false); LocalSearchButton.enable(false); DDFSButton.enable(false); RDFSButton.enable(false); } } else if (e.target == RedrawButton){ RedrawButton.enable(false); blackout(getGraphics()); reInit(); //blackout(getGraphics()); SetUpButton.setLabel("Pre-Place Queens"); SetUpButton.enable(true); RestoreButton.enable(true); ClearButton.enable(true); DDFSButton.enable(true); RDFSButton.enable(true); LocalSearchButton.enable(true); } else if (e.target == AboutButton){ about = allabout(getGraphics()); /*Output.appendText("about=" + about + "\n"); if(!about){ about = allbout(getGraphics()); AboutButton.setLabel("Close About"); about = true; Output.appendText("About \n"); AboutBox = new TextArea(200, 400); AboutBox.setEditable(false); AboutBox.setBackground(Color.black); AboutBox.setForeground(Color.white); AboutBox.reshape(Hindent + BoardSize/2 - 100, Vindent + BoardSize/2 - 200, 200, 400); AboutBox.setText("N-Queens Applet: \n Written by Matt Taylor: mst6@cornell.edu \n"); add(AboutBox); } else{ allabout(getGraphics()); AboutButton.setLabel("About N-Queens"); remove(AboutBox); about = false; }*/ } else { return super.action(e, o); } return true; } public boolean handleEvent (Event e){ if (e.target == Delay){ DelayValue.setText(Integer.toString(Delay.getValue())); return true; } else if (e.target == N) { if(n != N.getValue()){ RedrawButton.enable(true); } else { RedrawButton.enable(false); } NValue.setText(Integer.toString(N.getValue())); return true; } else if (e.target == Cutoff){ if(Cutoff.getValue() >= 32000){ CutoffValue.setText("None"); noCutoff = true; } else{ CutoffValue.setText(Integer.toString(Cutoff.getValue())); noCutoff = false; } return true; } else return super.handleEvent(e); } private boolean allabout(Graphics g){ if (about) { AboutButton.setLabel("About N-Queens"); remove(AboutBox); return false; } else { AboutButton.setLabel("Close About"); AboutBox = new TextArea(800, 600); AboutBox.setEditable(false); AboutBox.setBackground(Color.black); AboutBox.setForeground(Color.white); AboutBox.reshape(Hindent + BoardSize/2 - 300, Vindent + BoardSize/2 - 250, 600, 500); AboutBox.setText(" N-QUEENS APPLET : Written by MATT TAYLOR, 1999 : mst6@cornell.edu \n\n"); StringBuffer stringBuffer = new StringBuffer(); try { uRL = new URL(getCodeBase() + "info.txt"); } catch (MalformedURLException malURL){ } URLConnection uRLConnecton = null; DataInputStream dataInputStream = null; String string; stringBuffer = new StringBuffer(); try { uRLConnection = uRL.openConnection(); uRLConnection.connect(); dataInputStream = new DataInputStream(new BufferedInputStream( uRLConnection.getInputStream())); while ((string = dataInputStream.readLine()) != null) { stringBuffer.append(string + "\n"); } AboutBox.appendText(stringBuffer.toString()); } catch (IOException e) { System.out.println("IO Error:" + e.getMessage()); } add(AboutBox); return true; } } private void randomOrder(int num){ //random = new Vector(0); random = new int[num]; int index; //double randnum; //Output.appendText("rows.size = " + rows.size() + "\n"); //Output.appendText("random.size = " + random.size() + "\n"); for (int i = 0; i < n; i++){ rows.addElement(new Integer(i)); //rows.setElementAt(new Integer(i), i); //Output.appendText("Rows[" + i +"]=" + i + "\n"); } for (int i = 0; i < PlacedQ; i++){ rows.removeElement(new Integer(Qy[i])); //random.addElement(new Integer(Qy[i])); random[i] = Qy[i]; //Output.appendText("random[" + i + "]=" + random.elementAt(i) + "\n"); } int j = PlacedQ; while (rows.size() > 0){ index = (int) Math.floor(Math.random() * rows.size()); //Output.appendText("index = " + index + "\n"); if ((index >= 0) && (index <= rows.size())){ //random.addElement(new Integer(rows.elementAt(index).toString())); random[j] = Integer.parseInt(rows.elementAt(index).toString()); j++; rows.removeElementAt(index); } /*else { Output.appendText("false \n"); Output.appendText("rows.size = " + rows.size() +"\n"); }*/ } /*for (int i = 0; i < n; i++){ Output.appendText("random[" + i + "]=" + random[i] + "\n"); }*/ } private void Restore(boolean bool){ if (bool){ Output.appendText("Restore Board \n"); int i = n-1; while(Qx[i] == -1){ i--; } int j = i; for(i = j; i >= PlacedQ; i--){ Qx[i] = -1; Qy[i] = -1; } for(i = PlacedQ-1; i > -1; i--){ Qx[i] = iQx[i]; Qy[i] = iQy[i]; } for (i = 0; i < n; i++) { AttackTracker[i] = iAttackTracker[i]; MaxAttackQx[i] = -1; MaxAttackQy[i] = -1; JustPlaced[i] = false; NoAttacks[i] = 0; StartSquare[i] = 0; for (j = 0; j < n; j++) { CurrentBoard[i][j] = InitialBoard[i][j]; Attacks[i][j] = iAttacks[i][j]; } } AttackTracker[n] = iAttackTracker[n]; QonBoard = PlacedQ; } else { Output.appendText("Clear Board \n"); for (int i = 0; i < n; i++){ Qx[i] = -1; Qy[i] = -1; iQx[i] = -1; iQy[i] = -1; AttackTracker[i] = 0; iAttackTracker[i] = 0; MaxAttackQx[i] = -1; MaxAttackQy[i] = -1; JustPlaced[i] = false; QinRow[i] = false; NoAttacks[i] = 0; StartSquare[i] = 0; for (int j = 0; j < n; j++) { InitialBoard[i][j] = false; CurrentBoard[i][j] = false; Attacks[i][j] = 0; iAttacks[i][j] = 0; } } AttackTracker[0] = n*n; iAttackTracker[0] = n*n; AttackTracker[n] = 0; iAttackTracker[n] = 0; PlacedQ = 0; QonBoard = 0; } SetUpButton.setLabel("Pre-Place Queens"); SetUpButton.enable(true); RestoreButton.enable(true); ClearButton.enable(true); N.enable(true); LocalSearchButton.enable(true); DDFSButton.enable(true); RDFSButton.enable(true); Backtracks = 0; solved = false; canChange = false; Qfound = false; Search = 0; Moves = 0; paint(getGraphics()); } public void UpdateAttacks(int x, int y, int diff) { //horizontal for(int i = 0; i < n; i++) { if(i != x){ if(!CurrentBoard[i][y]){ AttackTracker[(Attacks[i][y])] -= 1; AttackTracker[(Attacks[i][y]) + diff] += 1; } Attacks[i][y] += diff; } } // vertical for(int j = 0; j < n; j++) { if (j != y){ if(!CurrentBoard[x][j]){ AttackTracker[(Attacks[x][j])] -= 1; AttackTracker[(Attacks[x][j]) + diff] += 1; } Attacks[x][j] += diff; } } //diagonals //NorthWest int i = 1; int j = 1; while ((x+i) < n && (y-j) > -1) { if(!CurrentBoard[x+i][y-j]){ AttackTracker[(Attacks[x+i][y-j])] -= 1; AttackTracker[(Attacks[x+i][y-j]) + diff] += 1; } Attacks[x+i][y-j] += diff; i++; j++; } // SouthWest i=1; j=1; while((x+i) < n && (y+j) < n){ if(!CurrentBoard[x+i][y+j]){ AttackTracker[(Attacks[x+i][y+j])] -= 1; AttackTracker[(Attacks[x+i][y+j]) + diff] += 1; } Attacks[x+i][y+j] += diff; i++; j++; } // SouthEast i=1; j=1; while((x-i) > -1 && (y+j) < n){ if(!CurrentBoard[x-i][y+j]){ AttackTracker[(Attacks[x-i][y+j])] -= 1; AttackTracker[(Attacks[x-i][y+j]) + diff] += 1; } Attacks[x-i][y+j] += diff; i++; j++; } // NorthEast i=1; j=1; while((x-i) > -1 && (y-j) > -1){ if(!CurrentBoard[x-i][y-i]){ AttackTracker[(Attacks[x-i][y-j])] -= 1; AttackTracker[(Attacks[x-i][y-j]) + diff] += 1; } Attacks[x-i][y-j] += diff; i++; j++; } if(diff == -1){ CurrentBoard[x][y] = false; Attacks[x][y] -= 1; AttackTracker[Attacks[x][y]] += 1; } else{ CurrentBoard[x][y] = true; Attacks[x][y] +=1; AttackTracker[Attacks[x][y]-1] -= 1; } paintq(x, y, getGraphics()); //showAT(); } /* public void showAT(){ Output.appendText("AttackTracker: \n"); Output.appendText("QonBoard= " + QonBoard + "\n"); Output.appendText("Attacks: \n"); for (int j=0; j-1; i--){ Output.appendText("AT[" + i + "]= " + AttackTracker[i] + "\n"); } } */ public boolean UpdateQ(int removex, int removey, int placex, int placey){ if(removex == -1){ //just placing queen Qx[QonBoard] = placex; Qy[QonBoard] = placey; QonBoard++; } else { // (re)moving a queen if(canChange){ bound = -1; } else { bound = PlacedQ -1; } for (int k = QonBoard-1; k > bound; k--){ if (Qx[k] == removex){ if (Qy[k] == removey){ if (placex == -1) { //removing queen only QonBoard--; Qx[k] = Qx[QonBoard]; Qy[k] = Qy[QonBoard]; Qx[QonBoard] = -1; Qy[QonBoard] = -1; } else { //moving queen paintq(Qx[k], Qy[k], getGraphics()); Qx[k] = placex; Qy[k] = placey; } break; } } } } /*for(int w = 0; w < n; w++){ Output.appendText("#" + w + ": (" + Qx[w] + ", " + Qy[w] + ")\n"); } Output.appendText("\n");*/ return true; } private boolean pastCutoff(int num){ if(noCutoff | (num < Cutoff.getValue())){ return false; } else { return true; } } public boolean mouseDown(Event e, int x, int y) { if (canChange) { for (int iValue = 0; iValue < n; iValue++) { if ((x >= iValue * SquareWidth + Hindent) && (x <= (iValue+1) * SquareWidth + Hindent)) { for (int jValue = 0; jValue < n; jValue++) { if ((y >= jValue * SquareWidth + Vindent) && (y <= (jValue+1) * SquareWidth + Vindent)){ if((Attacks[iValue][jValue] == 0) | (CurrentBoard[iValue][jValue])){ if(Attacks[iValue][jValue] == 0) { UpdateQ(-1, -1, iValue, jValue); diff = 1; } else { UpdateQ(iValue, jValue, -1, -1); diff = -1; } UpdateAttacks(iValue, jValue, diff); //do i need this?? paint(getGraphics()); return true; } else { Output.appendText("Square is attacked \n"); //showAT(); } } } } } } else { if((x > 149) && (x < (150 + BoardSize)) && (y > 15) && (y < (15 + BoardSize))){ Output.appendText("Click Pre-Place \n"); Output.appendText("Queens Button to \n"); Output.appendText("edit board. \n"); } } //paint(getGraphics()); return false; } public void paint(Graphics g) { //applet boarder g.setColor(Color.white); g.draw3DRect(3, 3, 658, 511, true); //control panel boarder g.setColor(Color.lightGray); //g.draw3DRect(7, 7, 143, 144, false); //g.draw3DRect(7, 156, 143, 147, false); //g.draw3DRect(7, 308, 143, 185, false); //g.draw3DRect(7, 498, 143, 180, false); //g.draw3DRect(7, 683, 143, 27, false); //button group boarders //g.setColor(Color.darkGray); //g.draw3DRect(13, 18, 131, 71, false); //g.draw3DRect(13, 105, 131, 39, false); //g.draw3DRect(13, 167, 131, 130, false); //g.draw3DRect(13, 319, 131, 168, false); //block out button group boarder beneath group header g.setColor(Color.black); g.fillRect(21, 16, 116, 5); g.fillRect(33, 103, 92, 5); g.fillRect(26, 165, 106, 5); g.fillRect(26, 317, 106, 5); //draw button group header g.setColor(Color.white); g.drawString("Depth First Search", 28, 21); g.drawString("Local Search", 34, 80); g.drawString("Search Controls", 34, 118); g.drawString("Board Controls", 37, 222); //draw board //SquareWidth = (int)(700/n); //BoardSize = n * SquareWidth; //black out old board (if any) and calcualate board dimensions + location //g.setColor(Color.black); //g.fillRect(152, 4, 710, 708); g.setColor(Color.lightGray); //Hindent = 152 + (int)((710-BoardSize)/2); //Vindent = 4+ (int)((710-BoardSize)/2); g.drawRect(Hindent-2, Vindent-2, BoardSize+3, BoardSize+3); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (CurrentBoard[i][j]){ g.drawImage(queen, i * SquareWidth + Hindent, j * SquareWidth + Vindent, SquareWidth, SquareWidth, this); //g.fillRect(i * SquareWidth + Hindent, j * SquareWidth + Vindent, SquareWidth, SquareWidth); } else { if ((i+j)%2 == 0) { g.setColor(Color.lightGray); } else { g.setColor(Color.black); } g.fillRect(i * SquareWidth + Hindent, j * SquareWidth + Vindent, SquareWidth, SquareWidth); } } } } public void update(Graphics g){ paint(g); } public void paintq(int i, int j, Graphics g){ if (CurrentBoard[i][j]){ g.drawImage(queen, i * SquareWidth + Hindent, j * SquareWidth + Vindent, SquareWidth, SquareWidth, this); //g.setColor(Color.red); } else { if ((i+j)%2 == 0) { g.setColor(Color.lightGray); } else { g.setColor(Color.black); } g.fillRect(i * SquareWidth + Hindent, j * SquareWidth + Vindent, SquareWidth, SquareWidth); } } public boolean DDFS() { Output.appendText("Deterministic DFS \n"); Backtracks = 0; CurrentRow = 0; solved = false; while(!pastCutoff(Backtracks)){ xValue = 0; while ((QonBoard < n) && (StartSquare[CurrentRow] < n) && (QonBoard >= PlacedQ) && (xValue < n)) { //Output.appendText("placing q's \n"); //Output.appendText("QonBoard= " + QonBoard + "\n"); //Output.appendText("StartSquare[CurrentRow]= " + StartSquare[CurrentRow] + "\n"); //Output.appendText("PlacedQ= " + PlacedQ + "\n"); try{ SearchThread.sleep(Delay.getValue()); } catch (InterruptedException e) { Output.appendText("Error! Halted! \n"); Halt = true; } if(Halt){ return solved; } if(!QinRow[CurrentRow]){ //Output.appendText("!QinRow \n"); xValue=StartSquare[CurrentRow]; //Output.appendText("SS[" + CurrentRow + "]= " + StartSquare[CurrentRow] + "\n"); Qfound = false; while((xValue < n) && (!Qfound)){ if(Halt){ return solved; } if (Attacks[xValue][CurrentRow] == 0){ //Output.appendText("Attacks == 0 \n"); StartSquare[CurrentRow] = xValue + 1; //Output.appendText("SS[" + StartSquare[CurrentRow] + "]= " + StartSquare[CurrentRow] + "\n"); UpdateAttacks(xValue, CurrentRow, 1); UpdateQ(-1, -1, xValue, CurrentRow); Qfound = true; //Output.appendText("Qfound == true \n"); CurrentRow++; //Output.appendText("CurrentRow= " + CurrentRow + "\n"); } if(!Qfound){ xValue++; //Output.appendText("!Qfound, xValue = " + xValue + "\n"); } } }//end QinRow if else{ while(QinRow[CurrentRow]){ //Output.appendText("QinRow! \n"); CurrentRow++; } } } if(QonBoard == n) { //solved!! //Output.appendText("All Q's placed! \n"); solved = true; return solved; } else if (CurrentRow == -1){ //Output.appendText("CurrentRow= -1 \n"); return solved; } else { //must backtrack //Output.appendText("removing Q's \n"); StartSquare[CurrentRow] = 0; //Output.appendText("StartSquare[" + CurrentRow + "]= " + StartSquare[CurrentRow] + "\n"); if(QonBoard-1 < PlacedQ){ return solved; } CurrentRow = Qy[QonBoard-1]; //Output.appendText("CurrentRow=" + CurrentRow + "\n"); StartSquare[CurrentRow] = Qx[QonBoard-1]+1; //Output.appendText("SS[" + CurrentRow + "]= " + StartSquare[CurrentRow] + "\n"); UpdateAttacks(Qx[QonBoard-1], Qy[QonBoard-1], -1); UpdateQ(Qx[QonBoard-1], Qy[QonBoard-1], -1, -1); Backtracks++; //Output.appendText("removed Q, backtracks++ \n"); } } //we have exceeded the cutoff, end DFS return solved; } public boolean RDFS() { Output.appendText("Random DFS \n"); Backtracks = 0; CurrentRow = PlacedQ; //0 solved = false; while(!pastCutoff(Backtracks)){ xValue = 0; while ((QonBoard < n) && (StartSquare[random[CurrentRow]] < n) && (QonBoard >= PlacedQ) && (xValue < n)) { //Output.appendText("placing q's \n"); //Output.appendText("QonBoard= " + QonBoard + "\n"); //Output.appendText("StartSquare[random[CurrentRow]]= " + StartSquare[random[CurrentRow]] + "\n"); //Output.appendText("PlacedQ= " + PlacedQ + "\n"); try{ SearchThread.sleep(Delay.getValue()); } catch (InterruptedException e) { Output.appendText("Error! Halted! \n"); Halt = true; } if(Halt){ return solved; } if(!QinRow[random[CurrentRow]]){ //Output.appendText("!QinRow \n"); xValue=StartSquare[random[CurrentRow]]; //Output.appendText("SS[" + CurrentRow + "]= " + StartSquare[CurrentRow] + "\n"); Qfound = false; while((xValue < n) && (!Qfound)){ if(Halt){ return solved; } if (Attacks[xValue][random[CurrentRow]] == 0){ //Output.appendText("Attacks == 0 \n"); StartSquare[random[CurrentRow]] = xValue + 1; //Output.appendText("SS[" + StartSquare[CurrentRow] + "]= " + StartSquare[CurrentRow] + "\n"); UpdateAttacks(xValue, random[CurrentRow], 1); UpdateQ(-1, -1, xValue, random[CurrentRow]); Qfound = true; //Output.appendText("Qfound == true \n"); CurrentRow++; //Output.appendText("CurrentRow= " + CurrentRow + "\n"); } if(!Qfound){ xValue++; //Output.appendText("!Qfound, xValue = " + xValue + "\n"); } } }//end QinRow if else{ while(QinRow[random[CurrentRow]]){ //Output.appendText("QinRow! \n"); CurrentRow++; } } } if(QonBoard == n) { //solved!! //Output.appendText("All Q's placed! \n"); solved = true; return solved; } else if (CurrentRow == -1){ //Output.appendText("CurrentRow= -1 \n"); return solved; } else { //must backtrack //Output.appendText("removing Q's \n"); StartSquare[random[CurrentRow]] = 0; //Output.appendText("StartSquare[" + random[CurrentRow] + "]= " + StartSquare[random[CurrentRow]] + "\n"); if(QonBoard-1 < PlacedQ){ return solved; } CurrentRow--; //Output.appendText("CurrentRow=" + CurrentRow + "\n"); StartSquare[random[CurrentRow]] = Qx[QonBoard-1]+1; //Output.appendText("SS[" + CurrentRow + "]= " + StartSquare[CurrentRow] + "\n"); UpdateAttacks(Qx[QonBoard-1], Qy[QonBoard-1], -1); UpdateQ(Qx[QonBoard-1], Qy[QonBoard-1], -1, -1); Backtracks++; //Output.appendText("removed Q, backtracks++ \n"); } } //we have exceeded the cutoff, end DFS return solved; } public boolean LocalSearch (){ int i, j, k; Output.appendText("Optimized LS \n"); solved = false; Moves = 0; while (!pastCutoff(Moves)){ try{ SearchThread.sleep(Delay.getValue()); } catch (InterruptedException e) { Output.appendText("Error! Halted! \n"); Halt = true; } if (Halt) { Search = 0; return solved; } while(QonBoard < n){ if (Halt) { Search = 0; return solved; } i = (int) Math.floor(n * (Math.random() -.0000001)); j = (int) Math.floor(n * (Math.random() -.0000001)); if(!CurrentBoard[i][j]){ UpdateQ(-1, -1, i, j); UpdateAttacks(i, j, 1); } } BestIndex = 0; while(AttackTracker[BestIndex] == 0){ BestIndex++; } TrueMaxAttack = 0; MaxAttack = 0; Qcount1 = 0; for(i=0; i TrueMaxAttack){ TrueMaxAttack = Attacks[Qx[i]][Qy[i]]; } } for(i = PlacedQ; i < n; i++){ if(Attacks[Qx[i]][Qy[i]] >= MaxAttack){ if (Attacks[Qx[i]][Qy[i]] > MaxAttack){ MaxAttackQx[0] = Qx[i]; MaxAttackQy[0] = Qy[i]; MaxAttack = (Attacks[Qx[i]][Qy[i]]); Qcount1 = 1; } else { MaxAttackQx[Qcount1] = Qx[i]; MaxAttackQy[Qcount1] = Qy[i]; Qcount1++; } if (MaxAttack > TrueMaxAttack){ TrueMaxAttack = MaxAttack; } } } if(TrueMaxAttack == 1){ Search = 0; solved = true; return solved; } p1 = (int)Math.floor(Qcount1 * (Math.random() - .0000001)); p2 = (int) Math.floor(AttackTracker[BestIndex] * (Math.random() - .0000001)); x1=0; k=0; Qfound = false; while(!Qfound){ y1 = 0; while ((y1 < n) && (!Qfound)){ if (Halt) { Search = 0; return solved; } if(!CurrentBoard[x1][y1]){ if((Attacks[x1][y1] == BestIndex)){ if(k == p2){ Qfound = true; } else { k++; } } } y1++; } x1++; } x1--; y1--; UpdateAttacks(MaxAttackQx[p1], MaxAttackQy[p1], -1); UpdateAttacks(x1, y1, 1); UpdateQ(MaxAttackQx[p1], MaxAttackQy[p1], x1, y1); Moves++; } Search = 0; return solved; }//end LocalSearch }//end class