2

我找到了一个解决方案,仅在 Bprolog 上,并寻求帮助如何由 JPL 在 SWI PROLOG 上翻译它?或者,也许您可​​以使用 jpl 库为我提供解决方案

    // 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).
4

1 回答 1

2

直译可能不值得努力。您显示的代码编码了一个非常难以修改的非常具体的搜索策略。实际的逻辑和副作用是完全交织在一起的。

但是, SWI的动画library(clpfd)更有趣。在那里,可以直接交换标记策略。所以你可以看到为什么简单的幼稚标签被证明是无效的。同样,您可以添加自己的策略,而无需修改查看器的代码。

于 2014-06-02T21:01:36.607 回答