加工中的Knight's Tour GUI

时间:2014-12-04 14:27:52

标签: java user-interface applet processing backtracking

我正在研究一个基本gui的骑士旅行问题,我想在用户输入构成(x,y)的两个文本字段中的用户输入,然后在一个文本框中打印,如果解决方案是可用的,在另一个我写的骑士采用的路径。我的算法工作正常,我有问题gui.i给了一些默认值(x,y)为我得到正确的输出。但是,当我改变的值(x,y)在文本字段中,没有发生任何变化。这是主文件,还有另一个事件处理程序文件,它位于它下面。您的帮助将真诚地感谢。我正在处理2.2.1。这是如何输出屏幕看起来像enter image description here

主文件/ project.pde

// Need G4P library
import g4p_controls.*;
Maxim maxim;
AudioPlayer player;
int x=-1;
int y=-1;
String solution="";
PImage img;
int count=0;

public void setup(){
  size(480, 320, JAVA2D);
  maxim=new Maxim(this);
  player=maxim.loadFile("song.wav");
  player.setLooping(true);

  img=loadImage("chess.jpg");

  createGUI();
  customGUI();

  // Place your setup code here

}
int t[]=new int[25];
boolean visited[][]=new boolean[5][5];
int check[][]=new int[5][5];
boolean b;
int counter=-1;
boolean move(int x,int y , int m){
 boolean result=false; 
   if (x<0 || x>=5 || y<0 || y>=5 || visited[x][y]==true)
   {
        return false;
   }

    visited[x][y]=true;

    if (m==24)
    {

        visited[x][y]=true;

        return true;
    }
    else
    {
      String xstring=String.valueOf(x);
      String ystring=String.valueOf(y);
      solution=solution+xstring+","+ystring+"  ";
        print (x);
        print(",");
        print(y);
        check[x][y]=counter+1;
        if (move(x+2,y+1,m+1) || move(x+2,y-1,m+1)
            || move(x-2,y+1,m+1) || move(x-2,y-1,m+1)
            || move(x+1,y+1,m+1) || move(x+1,y-1,m+1)
            || move(x-1,y+1,m+1) || move(x-1,y-1,m+1)){
            print (x);
            print(",");
            print(y);
            //check[x][y]=1;
            return true;

            }


    return false;


}
}


public void draw(){
 counter=counter+1; 
   background(0,128,128);
   image(img,0,0,480,320);
   player.play();
   textarea2.setText(solution);


   String txt1 = textfield1.getText();
   x = Integer.parseInt(txt1);

   String txt2 = textfield2.getText();
   y= Integer.parseInt(txt2);
   print(solution);
   if(x>=0 && y>=0)
   {
     b=move(x,y,0);


     if(b==false)
     {
       textarea1.setText("Solution is not possible,enter other coordinates");
     }
     if(b==true)
     {
       textarea1.setText("Congratulations solution is possible");
     }
   }
   if(count%8==0)
   {
     delay(1000);
     println(counter);

   }

}
void keyPressed()
{
  if (key==13)
  {
    solution="";
    print(solution);
    textarea2.setText(solution);
    String txt1 = textfield1.getText();
   x = Integer.parseInt(txt1);

   String txt2 = textfield2.getText();
   y= Integer.parseInt(txt2);
  }
    if(x>=0 && y>=0)
   {
     b=move(x,y,0);


     if(b==false)
     {
       textarea1.setText("Solution is not possible,enter other coordinates");
     }
     if(b==true)
     {
       textarea1.setText("Congratulations solution is possible");
     }
   }
}

// Use this method to add additional statements
// to customise the GUI controls
public void customGUI(){

}

这是事件处理程序文件

/* =========================================================
 * ====                   WARNING                        ===
 * =========================================================
 * The code in this tab has been generated from the GUI form
 * designer and care should be taken when editing this file.
 * Only add/edit code inside the event handlers i.e. only
 * use lines between the matching comment tags. e.g.

 void myBtnEvents(GButton button) { //_CODE_:button1:12356:
     // It is safe to enter your event code here  
 } //_CODE_:button1:12356:

 * Do not rename this tab!
 * =========================================================
 */

public void tf1(GTextField source, GEvent event) { //_CODE_:textfield1:418637:
  println("textfield1 - GTextField >> GEvent." + event + " @ " + millis());
} //_CODE_:textfield1:418637:

public void tf2(GTextField source, GEvent event) { //_CODE_:textfield2:859413:
  println("textfield2 - GTextField >> GEvent." + event + " @ " + millis());
} //_CODE_:textfield2:859413:

public void ta1(GTextArea source, GEvent event) { //_CODE_:textarea1:252891:
  println("textarea1 - GTextArea >> GEvent." + event + " @ " + millis());
} //_CODE_:textarea1:252891:

public void ta2(GTextArea source, GEvent event) { //_CODE_:textarea2:483845:
  println("textarea2 - GTextArea >> GEvent." + event + " @ " + millis());
} //_CODE_:textarea2:483845:

public void slider1_change1(GSlider source, GEvent event) { //_CODE_:slider1:280049:
  println("slider1 - GSlider >> GEvent." + event + " @ " + millis());
} //_CODE_:slider1:280049:

public void slider2_change1(GSlider source, GEvent event) { //_CODE_:slider2:362722:
  println("slider2 - GSlider >> GEvent." + event + " @ " + millis());
} //_CODE_:slider2:362722:



// Create all the GUI controls. 
// autogenerated do not edit
public void createGUI(){
  G4P.messagesEnabled(false);
  G4P.setGlobalColorScheme(GCScheme.BLUE_SCHEME);
  G4P.setCursor(ARROW);
  if(frame != null)
    frame.setTitle("Sketch Window");
  textfield1 = new GTextField(this, 210, 32, 160, 30, G4P.SCROLLBARS_NONE);
  textfield1.setText("1");
  textfield1.setPromptText("Enter x-Cordinate");
  textfield1.setOpaque(true);
  textfield1.addEventHandler(this, "tf1");
  textfield2 = new GTextField(this, 204, 96, 160, 30, G4P.SCROLLBARS_NONE);
  textfield2.setText("1");
  textfield2.setPromptText("Enter y Cordinate");
  textfield2.setLocalColorScheme(GCScheme.PURPLE_SCHEME);
  textfield2.setOpaque(true);
  textfield2.addEventHandler(this, "tf2");
  textarea1 = new GTextArea(this, 53, 196, 160, 80, G4P.SCROLLBARS_NONE);
  textarea1.setLocalColorScheme(GCScheme.GREEN_SCHEME);
  textarea1.setOpaque(true);
  textarea1.addEventHandler(this, "ta1");
  textarea2 = new GTextArea(this, 288, 192, 160, 80, G4P.SCROLLBARS_NONE);
  textarea2.setLocalColorScheme(GCScheme.YELLOW_SCHEME);
  textarea2.setOpaque(true);
  textarea2.addEventHandler(this, "ta2");
  slider1 = new GSlider(this, 96, 276, 264, 40, 10.0);
  slider1.setLimits(0.5, 0.0, 1.0);
  slider1.setNumberFormat(G4P.DECIMAL, 2);
  slider1.setOpaque(false);
  slider1.addEventHandler(this, "slider1_change1");
  slider2 = new GSlider(this, 348, 240, 100, 36, 10.0);
  slider2.setLimits(0.5, 0.0, 1.0);
  slider2.setNumberFormat(G4P.DECIMAL, 2);
  slider2.setOpaque(false);
  slider2.addEventHandler(this, "slider2_change1");
}

// Variable declarations 
// autogenerated do not edit
GTextField textfield1; 
GTextField textfield2; 
GTextArea textarea1; 
GTextArea textarea2; 
GSlider slider1; 
GSlider slider2; 

1 个答案:

答案 0 :(得分:2)

上述结构存在一些问题。 您在move()方法中执行递归draw()方法。但是处理 draw()每秒都会被动画线程多次调用。

此类案件的常见设定是:

  • 您应该拥有保持应用程序状态(逻辑状态)
  • 的变量
  • 您的draw()方法绘制的内容仅取决于州
  • 状态可以通过动画线程或任何其他线程修改

我建议您稍微更改一下代码:

第一个 - 状态变量:

// 1 - display status, wait to enter values
// 2 - check if x and y are correct
// 3 - solve problem
int state=1;
boolean solutionExists=false;

public void setup() {
...
}

next draw()方法:

void draw() {

   counter=counter+1; 
   background(0,128,128);

   String coords = "(" + x + "," + y + ")";

  if (state == 1) {
     if(solutionExists) {
       textarea1.setText("Congratulations solution is possible  " + coords);       
     } else {
       textarea1.setText("Solution is not possible,enter other coordinates  " +coords);
     }

     return; 
  }

  if (state == 2) {
    readXY();
    return;
  }

  if (state == 3) {
    println("find solution for: " + coords);
    solutionExists = move(x,y,0);
    state = 1;
    return;
  }

}

public void readXY() {
  try {
   x = Integer.parseInt(textfield1.getText().trim());
   y = Integer.parseInt(textfield2.getText().trim());
   state = 3;
  } catch(Exception e) {
    state = 1;
  }

}

最后是textfields处理程序:

public void tf1(GTextField source, GEvent event) {
  if (event.getType().equals("LOST_FOCUS")) {
    state=2;
  }
}

public void tf2(GTextField source, GEvent event) {
  if (event.getType().equals("LOST_FOCUS")) {
    state=2;
  } 
}

如你所见:

  • 如果state==1 - draw()仅更新消息
  • if state==2 - draw()检查x和y是否有效,如果有效 - &gt;将状态更改为3
  • 如果state==3 - draw()执行递归算法,请更新solutionExists变量,将状态更改为1

当textfield1或textfield2松散焦点时,它会将状态更改为2。

  • draw()仅由应用程序状态驱动。
  • 应用程序状态由其他事件修改。

为了获得最佳效果,递归算法应该在另一个线程中执行,而不是在动画线程中。

一个很好的注意事项:编辑文本字段时,它可能包含""(空)或" 3"(前导空格)或" 3 "等字符串 - 此类文本无法使用Integer进行解析.parseInt - 您需要修剪此类文本并确保不抛出NumberFormatException - 请参阅readXY()方法。