javanetbeansprologn-queensb-prolog

8 queens puzzle Netbeans(java) graphical interface + SWI prolog


I'm found a solution, only on Bprolog, and ask for a help how to translate it by JPL on SWI PROLOG? OR maybe you can take me solution by jpl libriry using

    // by Nobukuni Kino
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import bprolog.plc.Plc;   
public 
class Queens extends Applet implements Runnable {
  static int nqueens = 8;
  /* Run as an application */
    public static void main(String args[]) {
        Frame f = new Frame("Queens");

  f.addWindowListener(new WindowAdapter(){
    public void windowClosing(WindowEvent e){
      System.exit(0);
    }});

  Queens qb = new Queens();
        qb.init();
        f.add("Center",qb);
        f.setSize(321,321);
        f.show();
  qb.run1();
  System.exit(0);
    }

  int w,h;
  Color pieceColor = new Color(255,150,150);
  Thread runner;

  public void start() {
      if (runner == null) {
          runner = new Thread(this);
          System.out.println("Start");
          runner.start();
      } else {
          runner.resume();
      }
  }

  public void stop() {
      if (runner != null) {
          runner.suspend();
      }
  }

  public void run(){}

  public void run1() {
      Plc.startPlc(new String []{});
      Integer[] queens = new Integer[nqueens];
      for (int i=0; i<nqueens; i++) queens[i] = new Integer(i+1);
      Plc goal = new Plc("callQueens", new Object[] {queens,this});
                Plc.exec("load('queens')");
      goal.call();
  }

  public void paint(Graphics g) {
      board(g);
  }
  public void update(Graphics g) {
  }

  public void board(Graphics g) {
      w = (getSize().width-1)/nqueens;
      h = (getSize().height-1)/nqueens;
      g.setColor(Color.black);
      g.drawRect(0, 0, nqueens*w+1, nqueens*h+1);

      for (int i = 1; i <= nqueens; i++) {
          for (int j = 1; j <= nqueens; j++) {
              clearSquare(i,j);
          }
      }
  }
  public void putSquare(Integer row, Integer col) {
      putSquare(row.intValue(), col.intValue());
  }
  public void putSquare(int row, int col) {
      Graphics g = getGraphics();
      g.setColor(pieceColor);
      g.fillRect(w*(row-1)+1, h*(col-1)+1, w, h);
      Thread.yield();
  }

  public void clearSquare(Integer row, Integer col) {
      clearSquare(row.intValue(), col.intValue());
  }
  public void clearSquare(int row, int col) {
      Graphics g = getGraphics();
      if ((row+col)%2 == 1) {
          g.setColor(Color.black);
      }
      else {
          g.setColor(Color.white);
      }
      g.fillRect(w*(row-1)+1, h*(col-1)+1, w, h);
      Thread.yield();
  }
  public void sleep(Integer mill) {
      try {
          Thread.sleep(mill.intValue(),0);
      } catch(InterruptedException e) {}
  }
}
:-module queens.
:-public queens/2.
draw(M,N):-
        global_get(board,Qb),
    javaMethod(Qb,putSquare(M,N)).
draw(M,N):-
        global_get(board,Qb),
    javaMethod(Qb,clearSquare(M,N)),
    fail.

callQueens(Q,Qb):-
    cputime(Start),
    queens(Q,Qb),
    cputime(End),
    T is End-Start,
        write(executionTime(T)),nl,
        statistics.

queens(Q,Qb):-
    javaMethod(Qb,sleep(500)),
        global_set(board,Qb),
        put(Q,[],R),write(R),nl,
    javaMethod(Qb,sleep(1000)),
    fail.
queens(Q,Qb):-
    global_set(board,[]). % Qb is not valid after return to Java

put([Q1|Qs],Board,Result):-!,
    sel([Q1|Qs],Q,Rs),
    safe(Board,Q,Q),
    length(Qs,L),N is 1+L,
    draw(Q,N),
    put(Rs,[Q|Board],Result).
put([],Result,Result).

safe([Q|Rs],P,M):-!,
   PP is P+1,
   Q\==PP,
   MM is M-1,
    Q\==MM,
   safe(Rs,PP,MM).
safe([],P,M).

sel([X|Y],X,Y).
sel([X|Y],Z,[X|W]):-sel(Y,Z,W).

Solution

  • A literal translation is probably not worth the effort. The code you show encodes a very specific search strategy which is extremely difficult to modify. The actual logic and side effects are completely interwoven.

    However, there is an animation for library(clpfd) of SWI which is far more interesting. There, it is possible to exchange the labeling strategies directly. So you can see why simple naive labeling turns out to be ineffective. Equally, you can add your own strategy, without any modification of the viewer's code.