Search code examples
processingbacktracking

Can I draw a step by step my backtracking using Processing?


I want to write a backtracking -8 Queens- visualization code using processing.

So I tried to use noLoop() inside setup() and call redraw() followed by a delay(100) in each update step but it didn't work.

Here are my functions.

int cellH = 38, cellW = 38, n = 8;
PImage img;
boolean [][] grid;
boolean [] visC, visMD, visSD;
boolean firstTime = true;

void drawQueen(int r, int c){
  image(img, c*cellW, r*cellH, cellW, cellH);
}

void drawGrid(){
  background(255);
  for(int r = 0 ; r < n ; ++r){
    for(int c = 0 ; c < n ; ++c){
     if((r&1) != (c&1)) fill(0);
     else  fill(255);
     rect(c*cellW, r*cellH, (c+1)*cellW, (r+1)*cellH);
   }
  }
}

void updateQueens(){
  for(int r = 0 ; r < n ; ++r)
    for(int c = 0 ; c < n ; ++c)
      if(grid[r][c] == true)
        drawQueen(r, c);
}
boolean backTrack(int r){
 if(r == n)  return true;
 else{
   for(int c = 0 ; c < n ; ++c){
     if(!visC[c] && !visMD[n+r-c] && !visSD[r+c]){
       //Do
       grid[r][c] = visC[c] = visMD[n+r-c] = visSD[r+c] = true;
       redraw();
       delay(100);
       //Recurse
       if(backTrack(r+1))  return true;
       //Undo
       grid[r][c] = visC[c] = visMD[n+r-c] = visSD[r+c] = false;
     }
   }
 }
 return false;
}

void setup(){
  size(280, 280);
  cellH = 280/n;
  cellW = 280/n;

  grid = new boolean[n][n];
  visC = new boolean[n];
  visMD = new boolean[2*n];
  visSD = new boolean[2*n];

  noLoop();
  img = loadImage("queen.png");
  backTrack(0);
}

void draw(){
  drawGrid();
  updateQueens();
}

When I run the sketch only the final state appears.

Are there any other Idea to do so?


Solution

  • I tried to solve it using a Thread and it gave me an excellent output, so here's my code:

    int cellH = 38, cellW = 38, n = 8;
    PImage img;
    boolean [][] grid;
    boolean [] visC, visMD, visSD;
    boolean firstTime = true;
    
    Thread thread;
    
    void setup(){
      size(560, 560);
      cellH = 560/n;
      cellW = 560/n;
    
      grid = new boolean[n][n];
      visC = new boolean[n];
      visMD = new boolean[2*n];
      visSD = new boolean[2*n];
      img = loadImage("queen.png");
      thread = new Thread(new MyThread());
    
      thread.start();
    }
    
    void draw(){
      if(thread.isAlive())
        drawGrid();
      else{
        noLoop();
        endRecord();
        return;
      }
    }
    
    void drawGrid(){
      background(255);
      for(int r = 0 ; r < n ; ++r){
       for(int c = 0 ; c < n ; ++c){
         if((r&1) != (c&1)) fill(0);
         else  fill(255);
         rect(c*cellW, r*cellH, (c+1)*cellW, (r+1)*cellH);
         if(grid[r][c] == true)
           image(img, c*cellW, r*cellH, cellW, cellH);
       }
      }
    }
    
    boolean backTrack(int r){
      if(r == n)  return true;
      else{
        for(int c = 0 ; c < n ; ++c){
          if(!visC[c] && !visMD[n+r-c] && !visSD[r+c]){
            //Do
            grid[r][c] = visC[c] = visMD[n+r-c] = visSD[r+c] = true;
    
            try{
              Thread.sleep(200);
            }catch(InterruptedException e){System.out.println(e);}  
    
            //Recurse
            if(backTrack(r+1))  return true;
            //Undo
            grid[r][c] = visC[c] = visMD[n+r-c] = visSD[r+c] = false;
    
            try{
              Thread.sleep(200);
            }catch(InterruptedException e){System.out.println(e);}
          }
        }
      }
      return false;
    }
    
    class MyThread implements Runnable{    
      public void run(){    
        backTrack(0);    
      }
    }  
    

    And here's the output:

    The output of the sketch