java实现八皇后可视化输出

来源:互联网 发布:被子品牌推荐知乎 编辑:程序博客网 时间:2024/06/11 03:12

八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当n = 1n4时问题有解。

主要方法:回朔法——基本思想,就是能进则进,不能进则退,就是说在一个问题没有明确的解决办法的时候,回溯法是方法之一,实质上就是穷举法的思想,不过要比穷举法省时一点点,因为发现问题错误之后是退到上一步,而不是问题的初始。

在此八皇后问题上,就是逐行摆放皇后,初始第1行皇后放第1列;摆放第i行皇后时,从第1列开始,逐列判定是否与前i-1行皇后攻击,直到找到一个不攻击的位置,继续第i+1行的摆放;若第i行无摆放位置,则拿掉该行皇后,回溯至第i-1行,第i-1行皇后从当前位置的下一列开始判定,继续搜索。当第1行皇后的摆放位置超出棋盘时,全部求解过程结束。


代码:代码包含了n皇后问题对n输入之后图形界面的展示,每次更新n皇后皇后位置,刷新图形界面,以及读取文件校验给定坐标点是否符合n皇后摆放位置,代码设计知识全面。

废话少说,上代码:

package bahuanghou;import java.awt.Color;import java.awt.GridLayout;import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;import java.util.regex.Matcher;import java.util.regex.Pattern;import javax.swing.ImageIcon;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JOptionPane;public class huanghou2 {      public static int ways = 0; //累计方案总数      public static int MAXQUEEN;//皇后个数,同时也是棋盘行列总数      public static int[] OK; //定义数组,表示8列棋子摆放情况      ImageIcon image = new ImageIcon("one.png");//JLabel的皇后图标    static Paintchess p = null;//构造类    static Thread thread = null;//主线程//------------------------------------------------------------------------------------主函数,检测组合,弹出窗口,显示结果    public static void main(String args[]) throws InterruptedException, IOException{    if(how()){    System.out.println("该文件中的位置组符合八皇后排列!");    }else{    System.out.println("该文件中的位置组不符合八皇后排列!");    }    thread=Thread.currentThread(); //主线程,正在执行的线程    p = new Paintchess();//弹窗      String str =JOptionPane.showInputDialog(p.frame,"输入皇后个数","输入",JOptionPane.QUESTION_MESSAGE);    MAXQUEEN = Integer.parseInt(str);    OK = new int[MAXQUEEN];//确定皇后个数    p.show();   huanghou2 queen = new huanghou2();//开始计算queen.getBoard(0);//调用算法函数    System.out.println("\r\n"+MAXQUEEN+"皇后问题有"+ways+"种摆放方法。");      } //-------------------------------------------------------------------------------算法函数,计算位置是否合适    public void  getBoard(int n) throws InterruptedException{           boolean[] rows = new boolean[MAXQUEEN];//遍历该列所有不合法的行,并用rows数组记录,不合法即rows[i]=true      for(int i=0;i<n;i++){       rows[OK[i]]=true;      int d = n-i;      if(OK[i]-d >= 0){    rows[OK[i]-d]=true;    }    if(OK[i]+d <= MAXQUEEN-1){    rows[OK[i]+d]=true;     }    }      for(int i=0;i<MAXQUEEN;i++){            if(rows[i]){    continue;//判断该行是否合法,否则退出    }    OK[n] = i;//设置当前列合法棋子所在行数          if(n<MAXQUEEN-1){//当前列不为最后一列时      getBoard(n+1);//列加1,即移动到后一列    }else{//如当前已是最后一列,即该方法合理,满足皇后不同线    ways++;//累计方案个数            PaintBoard(); //调用打印棋盘函数    }                     }             } //------------------------------------------------------------------------------设置皇后Icon    public void PaintBoard() throws InterruptedException{           //    System.out.println("种走法"+ways);    for(int i=0;i<MAXQUEEN;i++){      for(int j=0;j<MAXQUEEN;j++){      if(i==OK[j]){ //如果可以摆放皇后    //System.out.print("0 ");      p.lab[i][j].setIcon(image);//就设置该位置图标为皇后图片    }//    else{//    System.out.print("+ ");  //    }    }  //    System.out.println();      }     thread.sleep(1000);//整个任务的主线程停止一秒钟    for(int i=0;i<MAXQUEEN;i++){    for(int j=0;j<MAXQUEEN;j++){    (p.lab[i][j]).setIcon(null);//清楚所有的皇后格子的Icon    }    }    }    //-------------------------------------------------------------------------------判断组合是否符合八皇后       public static boolean how() throws IOException{FileReader fr=new FileReader("xy.txt");//读取txt文件BufferedReader br=new BufferedReader(fr);int a[] = new int[8], b[] = new int[8];String s,str="";while((s=br.readLine())!= null){str+=s;}System.out.println("读入文本:\n"+str);Pattern pattern=Pattern.compile("(\\d,\\d)");// \\(\\)可以匹配括号//匹配(1,1)格式Matcher matcher=pattern.matcher(str);System.out.println("输入的坐标为:");int which = 0;while(matcher.find()){//正则找到行和列s=matcher.group(0);System.out.println("("+s+")");String[] tmp=s.split(",");int i=Integer.parseInt(tmp[0]);//行int j=Integer.parseInt(tmp[1]);//列a[which] = i;b[which] = j;which++;}for(int i=0; i<8; i++){//行不可相等for(int j=i+1; j<8; j++){if(a[i]==a[j]){return false;}}}for(int i=0; i<8; i++){//列不可相等for(int j=i+1; j<8; j++){if(a[i]==a[j]){System.out.println("h2");return false;}}}for(int i=0; i<8; i++){//行的差与列的差不可相同,否则在一条斜线for(int j=i+1; j<8; j++){if(Math.abs(a[i]-a[j])==Math.abs(b[i]-b[j])){System.out.println("h3");return false;}}}return true;    }   };//----------------------------------------------------------------------------------------------------------------输出棋盘外部类class Paintchess{JFrame frame = new JFrame("皇后棋盘");JLabel lab[][] = null;public Paintchess(){ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(500, 500);      frame.setResizable(false);     frame.setLocation(200,0);     frame.setVisible(true);  }public void show(){frame.setLayout(new GridLayout(huanghou2.MAXQUEEN,huanghou2.MAXQUEEN));  frame.setSize(huanghou2.MAXQUEEN*100, huanghou2.MAXQUEEN*100); lab=new JLabel[huanghou2.MAXQUEEN][huanghou2.MAXQUEEN];  for(int i=0;i<huanghou2.MAXQUEEN;i++){              for(int j=0;j<huanghou2.MAXQUEEN;j++){                  lab[i][j]=new JLabel();                  lab[i][j].setOpaque(true);//设置为透明,才能显示背景色                if((i+j)%2==0){                  lab[i][j].setBackground(Color.black);                }                  else{                  lab[i][j].setBackground(Color.white);                }                  frame.add(lab[i][j]);               }       }  }}
最后n=8的八皇后结果截图展示:



2 0
原创粉丝点击