Converting coding challenge ‘slide-puzzle-canvas’ from p5.js to Processing (Java)

Hi my friends,

I am trying to learn coding challenge Slide-Puzzle, the 'slide- puzzle-canvas" and convert p5js code to processing version. But I am struggling with the PGraphics and the copy function.
Here is the code I have:

PGraphics pg;

ArrayList<Tile> tiles;
int cols = 4; 
int rows = 4;
int w, h;

// Order of tiles
IntList board;

ArrayList<Bubble> bubbles;

void setup()
{
  size(400, 400);
  pg = createGraphics(400, 400);
  
  // pixel dimensions of each tiles
  w = width / cols;
  h = height / rows;
  
  board = new IntList();
  tiles = new ArrayList<Tile>();
  
  bubbles = new ArrayList<Bubble>();
  
  // Chop up source image into tiles
  for(int i = 0; i < cols; i++)
  {
    for(int j = 0; j < rows; j++)
    {
      PImage img = createImage(w, h, RGB);
      int index = i+j*cols;
      board.append(index);
      Tile tile = new Tile(index, img);
      tiles.add(tile);
    }
  }
  
  // Remove the last tile
  tiles.remove(tiles.size()-1);
  board.remove(board.size()-1);
  
  // -1 means empty spot?
  board.append(-1);
  
  startViz();  

  simpleShuffle(board);
  printArray(board);
}

void draw()
{
  background(0);
  pg.beginDraw();
  pg.background(250);
  
  drawViz();
  
  pg.endDraw();
  
  //image(pg, 0, 0);
  
  
  updateTiles();
  //randomMove(board);

  
  for(int i = 0; i < cols; i++)
  {
    for(int j = 0; j < rows; j++)
    {
      int index = i+j*cols;
      int x = i*w;
      int y = j*h;
      int tileIndex = board.get(index);
      if(tileIndex > -1)
      {
        PImage img = tiles.get(tileIndex).img;
        image(img, x, y, w, h);
      }
    }
  }
  
  for(int i = 0; i < cols; i++)
  {
    for(int j = 0; i < rows; j++)
    {
      int x = i*w;
      int y = j*h;
      stroke(250, 160, 0);
      strokeWeight(2);
      noFill();
      rect(x, y, w, h);
    }
  }
  
  if(isSolved())
  {
    println("SOLVED");
  }
  
}

// Shuffle the board
void simpleShuffle(IntList arr)
{
  for(int i = 0; i < 1000; i++)
  {
    randomMove(arr);
  }
}

void randomMove(IntList arr)
{
  int r1 = floor(random(cols));
  int r2 = floor(random(rows));
  move(r1, r2, arr);
}

void move(int i, int j, IntList arr)
{
  int blank = findBlank();
  int blankCol = blank % cols;
  int blankRow = floor(blank / rows);
  
  if(isNeighbor(i, j, blankCol, blankRow))
  {
    swap(blank, i+j*cols, arr);  
  }
}

// Probably could just use a variable
// to track blank spot
int findBlank()
{
  int index = 0;
  for(int i = 0; i < board.size(); i++)
  {
    if(board.get(i) == -1)
    {
      index = i;
    }
  }
  return index;
}

boolean isNeighbor(int i, int j, int x, int y)
{
  if(i != x && j != y)
  {
    return false;
  }
  if(abs(i-x) == 1 || abs(j-y) ==1)
  {
    return true;
  }
  return false;  
}

void swap(int i, int j, IntList arr)
{
  int temp = arr.get(i);
  arr.set(i, arr.get(j));
  arr.set(j, temp);
}

void updateTiles()
{
  for(int i = 0; i < cols; i++)
  {
    for(int j = 0; j < rows; j++)
    {
      int x = i*w;
      int y = j*h;
      int index = i+j*cols-1;
      if(index > -1)
      {
        PImage img = tiles.get(index).img;
        img.copy(pg, x, y, w, h, 0, 0, w, h);
      }
    }
  }
}

boolean isSolved()
{
  for(int i = 0; i < board.size()-1; i++)
  {
    int t = tiles.get(i).index;
    if(board.get(i) != t)
    {
      return false;
    }
  }
  return true;
}

void startViz()
{
  for(int i = 0; i < 3; i++)
  {
    bubbles.add(new Bubble());
  }
}

void drawViz()
{

  for(Bubble b: bubbles)
  {
    b.update();
    b.show();
  }
}

class Bubble
{
  int r;
  int x, y;
  int vx, vy;
  color clr;
  
  Bubble()
  {
    r = (int)random(60, 80);
    x = (int)random(r, width-r);
    y = (int)random(r, height-r);
    vx = (int)random(-2, 2);
    vy = (int)random(-2, 2);
    clr = color((int)random(255), (int)random(255), (int)random(255));
  }
  
  void update()
  {
    x += vx;
    y += vy;
    if(x > width-r || x < r)
    {
      vx *= -1;
    }
    if(y > height-r || y < r)
    {
      vy *= -1;
    }
  }
  
  void show()
  {

    pg.stroke(250, 160, 0);
    pg.fill(clr);
    pg.strokeWeight(2);
    pg.circle(x, y, r*2);

  }
}

class Tile
{
  int index;
  PImage img;
  
  Tile(int index, PImage img)
  {
    this.index = index;
    this.img = img;
  }
}

It seems the copy function in the updateTiles() doesn’t copy the PGraphics. It gives a black screen. :frowning:

void updateTiles()
{
  for(int i = 0; i < cols; i++)
  {
    for(int j = 0; j < rows; j++)
    {
      int x = i*w;
      int y = j*h;
      int index = i+j*cols-1;
      if(index > -1)
      {
        PImage img = tiles.get(index).img;
        img.copy(pg, x, y, w, h, 0, 0, w, h);
      }
    }
  }
}

if all the copy stuff is removed, the PGraphics stuff works. But I can not get the slided canvas. :confused:

PGraphics pg;

ArrayList<Tile> tiles;
int cols = 4; 
int rows = 4;
int w, h;

// Order of tiles
IntList board;

ArrayList<Bubble> bubbles;

void setup()
{
  size(400, 400);
  pg = createGraphics(400, 400);
  
  // pixel dimensions of each tiles
  w = width / cols;
  h = height / rows;
  
  board = new IntList();
  tiles = new ArrayList<Tile>();
  
  bubbles = new ArrayList<Bubble>();
  
  // Chop up source image into tiles
  for(int i = 0; i < cols; i++)
  {
    for(int j = 0; j < rows; j++)
    {
      PImage img = createImage(w, h, RGB);
      int index = i+j*cols;
      board.append(index);
      Tile tile = new Tile(index, img);
      tiles.add(tile);
    }
  }
  
  // Remove the last tile
  tiles.remove(tiles.size()-1);
  board.remove(board.size()-1);
  
  // -1 means empty spot?
  board.append(-1);
  
  startViz();  

  simpleShuffle(board);
  printArray(board);
}

void draw()
{
  background(0);
  pg.beginDraw();
  pg.background(250);
  
  drawViz();
  
  pg.endDraw();
  
  image(pg, 0, 0);
  
/*  
  updateTiles();
  //randomMove(board);

  
  for(int i = 0; i < cols; i++)
  {
    for(int j = 0; j < rows; j++)
    {
      int index = i+j*cols;
      int x = i*w;
      int y = j*h;
      int tileIndex = board.get(index);
      if(tileIndex > -1)
      {
        PImage img = tiles.get(tileIndex).img;
        image(img, x, y, w, h);
      }
    }
  }
  
  for(int i = 0; i < cols; i++)
  {
    for(int j = 0; i < rows; j++)
    {
      int x = i*w;
      int y = j*h;
      stroke(250, 160, 0);
      strokeWeight(2);
      noFill();
      rect(x, y, w, h);
    }
  }
  
  if(isSolved())
  {
    println("SOLVED");
  }
*/  
}

// Shuffle the board
void simpleShuffle(IntList arr)
{
  for(int i = 0; i < 1000; i++)
  {
    randomMove(arr);
  }
}

void randomMove(IntList arr)
{
  int r1 = floor(random(cols));
  int r2 = floor(random(rows));
  move(r1, r2, arr);
}

void move(int i, int j, IntList arr)
{
  int blank = findBlank();
  int blankCol = blank % cols;
  int blankRow = floor(blank / rows);
  
  if(isNeighbor(i, j, blankCol, blankRow))
  {
    swap(blank, i+j*cols, arr);  
  }
}

// Probably could just use a variable
// to track blank spot
int findBlank()
{
  int index = 0;
  for(int i = 0; i < board.size(); i++)
  {
    if(board.get(i) == -1)
    {
      index = i;
    }
  }
  return index;
}

boolean isNeighbor(int i, int j, int x, int y)
{
  if(i != x && j != y)
  {
    return false;
  }
  if(abs(i-x) == 1 || abs(j-y) ==1)
  {
    return true;
  }
  return false;  
}

void swap(int i, int j, IntList arr)
{
  int temp = arr.get(i);
  arr.set(i, arr.get(j));
  arr.set(j, temp);
}

void updateTiles()
{
  for(int i = 0; i < cols; i++)
  {
    for(int j = 0; j < rows; j++)
    {
      int x = i*w;
      int y = j*h;
      int index = i+j*cols-1;
      if(index > -1)
      {
        PImage img = tiles.get(index).img;
        img.copy(pg, x, y, w, h, 0, 0, w, h);
      }
    }
  }
}

boolean isSolved()
{
  for(int i = 0; i < board.size()-1; i++)
  {
    int t = tiles.get(i).index;
    if(board.get(i) != t)
    {
      return false;
    }
  }
  return true;
}

void startViz()
{
  for(int i = 0; i < 3; i++)
  {
    bubbles.add(new Bubble());
  }
}

void drawViz()
{

  for(Bubble b: bubbles)
  {
    b.update();
    b.show();
  }
}

class Bubble
{
  int r;
  int x, y;
  int vx, vy;
  color clr;
  
  Bubble()
  {
    r = (int)random(60, 80);
    x = (int)random(r, width-r);
    y = (int)random(r, height-r);
    vx = (int)random(-2, 2);
    vy = (int)random(-2, 2);
    clr = color((int)random(255), (int)random(255), (int)random(255));
  }
  
  void update()
  {
    x += vx;
    y += vy;
    if(x > width-r || x < r)
    {
      vx *= -1;
    }
    if(y > height-r || y < r)
    {
      vy *= -1;
    }
  }
  
  void show()
  {

    pg.stroke(250, 160, 0);
    pg.fill(clr);
    pg.strokeWeight(2);
    pg.circle(x, y, r*2);

  }
}

class Tile
{
  int index;
  PImage img;
  
  Tile(int index, PImage img)
  {
    this.index = index;
    this.img = img;
  }
}

Can anyone help me a bit to figure out the problem?

1 Like

I figure out a way to solve it
here is the code:

// Source graphic to chop up
PGraphics source;

ArrayList<Tile> tiles;
int cols = 4; 
int rows = 4;
int w, h;

// Order of tiles
IntList board;

ArrayList<Bubble> bubbles;

void setup()
{
  size(400, 400);
  source = createGraphics(400, 400);
  
  // pixel dimensions of each tiles
  w = width / cols;
  h = height / rows;
  
  board = new IntList();
  tiles = new ArrayList<Tile>();
  
  bubbles = new ArrayList<Bubble>();
  
  // Chop up source image into tiles
  for(int i = 0; i < cols; i++)
  {
    for(int j = 0; j < rows; j++)
    {
      PImage img = createImage(w, h, RGB);
      int index = i+j*cols;
      board.append(index);
      Tile tile = new Tile(index, img);
      tiles.add(tile);
      
    }
  }
  
  // Remove the last tile
  tiles.remove(tiles.size()-1);
  board.remove(board.size()-1);
  
  // -1 means empty spot?
  board.append(-1);
  
  startViz();  

  simpleShuffle(board);
  printArray(board);
}

void draw()
{
  background(0);
  
  drawViz();
   

  updateTiles();
  ////randomMove(board);
  //println("board: "+board.size());
  
  for(int i = 0; i < cols; i++)
  {
    for(int j = 0; j < rows; j++)
    {
      int index = i+j*cols;
      println("index: "+index);
      int x = i*w;
      int y = j*h;
      int tileIndex = board.get(index);
      if(tileIndex > -1)
      {
        PImage img = tiles.get(tileIndex).img;
        image(img, x, y, w, h);
      }
    }
  }
  
  
  //for(int i = 0; i < cols; i++)
  //{
  //  for(int j = 0; i < rows; j++)
  //  {
  //    int x = i*w;
  //    int y = j*h;
  //    stroke(250, 160, 0);
  //    strokeWeight(2);
  //    noFill();
  //    rect(x, y, w, h);
  //  }
  //}
  
  if(isSolved())
  {
    println("SOLVED");
  }

}

// Shuffle the board
void simpleShuffle(IntList arr)
{
  for(int i = 0; i < 1000; i++)
  {
    randomMove(arr);
  }
}

void randomMove(IntList arr)
{
  int r1 = floor(random(cols));
  int r2 = floor(random(rows));
  move(r1, r2, arr);
}

void move(int i, int j, IntList arr)
{
  int blank = findBlank();
  int blankCol = blank % cols;
  int blankRow = floor(blank / rows);
  
  if(isNeighbor(i, j, blankCol, blankRow))
  {
    swap(blank, i+j*cols, arr);  
  }
}

// Probably could just use a variable
// to track blank spot
int findBlank()
{
  int index = 0;
  for(int i = 0; i < board.size(); i++)
  {
    if(board.get(i) == -1)
    {
      index = i;
    }
  }
  return index;
}

boolean isNeighbor(int i, int j, int x, int y)
{
  if(i != x && j != y)
  {
    return false;
  }
  if(abs(i-x) == 1 || abs(j-y) ==1)
  {
    return true;
  }
  return false;  
}

void swap(int i, int j, IntList arr)
{
  int temp = arr.get(i);
  arr.set(i, arr.get(j));
  arr.set(j, temp);
}

void updateTiles()
{
  for(int i = 0; i < cols; i++)
  {
    for(int j = 0; j < rows; j++)
    {
      int x = i*w;
      int y = j*h;
      int index = i+j*cols-1;
      if(index > -1)
      {
        PImage img = tiles.get(index).img;
        img.copy(source, x, y, w, h, 0, 0, w, h);
        //image(img, x, y);
      }
    }
  }
}

boolean isSolved()
{
  for(int i = 0; i < board.size()-1; i++)
  {
    int t = tiles.get(i).index;
    if(board.get(i) != t)
    {
      return false;
    }
  }
  return true;
}

void startViz()
{
  for(int i = 0; i < 5; i++)
  {
    bubbles.add(new Bubble());
  }
}

void drawViz()
{
  source.beginDraw();
  source.background(250);
  for(Bubble b: bubbles)
  {
    b.update();
    b.show();
  }  
  source.endDraw();
  //image(source, 0, 0);
}

void mousePressed()
{
  int i = floor(mouseX/w);
  int j = floor(mouseY/h);
  move(i, j, board);
}

class Bubble
{
  int r;
  int x, y;
  int vx, vy;
  color clr;
  
  Bubble()
  {
    r = (int)random(60, 80);
    x = (int)random(r, width-r);
    y = (int)random(r, height-r);
    vx = (int)random(-2, 2);
    vy = (int)random(-2, 2);
    clr = color((int)random(255), (int)random(255), (int)random(255));
  }
  
  void update()
  {
    x += vx;
    y += vy;
    if(x > width-r || x < r)
    {
      vx *= -1;
    }
    if(y > height-r || y < r)
    {
      vy *= -1;
    }
  }
  
  void show()
  {
    source.noFill();
    source.stroke(250, 0, 160);
    source.fill(clr);
    source.strokeWeight(2);
    source.circle(x, y, r*2);
  }
}

class Tile
{
  int index;
  PImage img;
  
  Tile(int index, PImage img)
  {
    this.index = index;
    this.img = img;
  }
}

I was disabling this part of code:

 //for(int i = 0; i < cols; i++)
  //{
  //  for(int j = 0; i < rows; j++)
  //  {
  //    int x = i*w;
  //    int y = j*h;
  //    stroke(250, 160, 0);
  //    strokeWeight(2);
  //    noFill();
  //    rect(x, y, w, h);
  //  }
  //}

It seems there is a conflict between the PGraphics and the usual way of drawing shapes in my case.

1 Like