Java非遞歸實現迷宮問題
這個題目是本人的一次課程設計,也是我第一次獨立做完的一個小玩意,說實話,昨晚的那一刻很有成就感。整個人開心到在自習室蹦起來。因為之前一直是自學的Java,從沒有自己做過任何一個項目,這一個課程設計就花費了我三天的時間,其實應該是兩天半,兩天半我做出來之後和室友去炫耀,老哥看完說一句,要是把之前的路堵死,從新換一條路呢。然後就炸了。。。。。。。。。。。。。。。在做完之後我也只開心了三秒,因為興奮之後確實無盡的空虛,不知道該向誰去分享自己的這個成就,單身狗傷不起啊。話不多說,直接上代碼
界面構造部分
package 迷宮問題;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MyFrame extends JFrame {
private int FIELDSIZE = 50;
public JLabel[][] labs;
public MyFrame() {
setTitle("迷宮問題");
// setName("test");
setBounds(400, 200, 800, 850);
setResizable(false);
JPanel boardPane = new JPanel();
boardPane.setLayout(null);
add(boardPane);
labs = new JLabel[16][16];
for (int x = 0; x < 16; x++) {
for (int y = 0; y < 16; y++) {
JLabel backgroundLabel = new JLabel();
backgroundLabel.setOpaque(true);
backgroundLabel.setBounds(x * FIELDSIZE, y * FIELDSIZE, FIELDSIZE, FIELDSIZE);
boardPane.add(backgroundLabel, new Integer(1), 0);
labs[x][y] = backgroundLabel;
}
}
setColor(labs);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
private void setColor(JLabel[][] labs) {
for (int x = 0; x < 16; x++) {
for (int y = 0; y < 16; y++) {
if (x == 0) {
labs[x][y].setBackground(Color.BLACK);
}
}
}
for (int x = 0; x < 16; x++) {
for (int y = 0; y < 16; y++) {
if (x == 15) {
labs[x][y].setBackground(Color.BLACK);
}
}
}
for (int x = 0; x < 16; x++) {
for (int y = 0; y < 16; y++) {
if (y == 0) {
labs[x][y].setBackground(Color.BLACK);
}
}
}
for (int x = 0; x < 16; x++) {
for (int y = 0; y < 16; y++) {
if (y == 15) {
labs[x][y].setBackground(Color.BLACK);
}
}
}
for (int y = 0; y < 8; y++) {
labs[2][y].setBackground(Color.BLACK);
}
for (int y = 9;y < 15; y++) {
labs[2][y].setBackground(Color.BLACK);
}
for (int x= 3; x < 7;x++) {
labs[x][7].setBackground(Color.BLACK);
}
for (int x= 6; x < 12;x++) {
labs[x][4].setBackground(Color.BLACK);
}
labs[6][9].setBackground(Color.BLACK);
labs[6][10].setBackground(Color.BLACK);
for (int x= 3; x < 10;x++) {
labs[x][10].setBackground(Color.BLACK);
}
for (int x= 4; x < 11;x++) {
labs[x][13].setBackground(Color.BLACK);
}
labs[8][15].setBackground(Color.BLACK);
for (int y = 2;y < 4; y++) {
labs[11][y].setBackground(Color.BLACK);
}
for (int y = 6;y < 14; y++) {
labs[11][y].setBackground(Color.BLACK);
}
for (int y = 7;y < 14; y++) {
labs[13][y].setBackground(Color.BLACK);
}
labs[1][1].setBackground(Color.RED);
labs[14][14].setBackground(Color.GREEN);
labs[9][6].setBackground(Color.black);
labs[9][5].setBackground(Color.black);
labs[13][1].setBackground(Color.black);
labs[13][2].setBackground(Color.black);
labs[13][3].setBackground(Color.black);
labs[14][3].setBackground(Color.black);
labs[14][4].setBackground(Color.black);
labs[11][5].setBackground(Color.black);
// labs[14][5].setBackground(Color.black);
labs[12][13].setBackground(Color.black);
//labs[3][13].setBackground(Color.black);
labs[14][6].setBackground(Color.black);
}//構造界面
public static void main(String[] args) {
MyFrame myFrame = new MyFrame();
}
分析:
紅色為入口,綠色為出口。當訪問至綠色,程序結束。
}
自己實現棧的定義,因為我們的課程設計不允許直接調用API
package 迷宮問題;
public class MyStack_Text {
Object[] stacks;
int size;
int top;
int len;
public MyStack_Text(int size) {
super();
this.size = size;
this.stacks = new Object[this.size];
this.top = -1;
}
public Object peek() {
return this.stacks[top];
}
public boolean empty() {
return top == (-1);
}
public boolean isFull() {
return top == (size - 1);
}
public void push(Object value) {
len++;
stacks[++this.top] = value;
}
public Object pop() {
len--;
return stacks[this.top--];
}
public int len() {
return this.len;
}
}
核心算法部分
分析:不用分析,就是基礎的數據結構棧的構建
package 迷宮問題;
import java.awt.Color;
import java.util.Stack;
import java.util.TimerTask;
import javax.swing.JLabel;
public class Run extends TimerTask{
// Stack<JLabel> stack = new Stack<JLabel>();//不願意定義棧,可以在此調用
Run(){
}
MyFrame myFrame = new MyFrame();
MyStack_Text stack=new MyStack_Text(100);
public void run(){
int i=1,j=1;
stack.push(myFrame.labs[1][1]);
while(!stack.empty()||myFrame.labs[i][j].getBackground() != Color.GREEN){
//??
while(myFrame.labs[i][j-1].getBackground() != Color.BLACK &&myFrame.labs[i][j].getBackground() != Color.GREEN&& myFrame.labs[i][j-1].getBackground() != Color.yellow&& myFrame.labs[i][j-1].getBackground() != Color.RED&& myFrame.labs[i][j-1].getBackground() != Color.pink){
if (myFrame.labs[i][--j].getBackground() != Color.GREEN)
try{
Thread.sleep(100);
}
catch(InterruptedException e){
e.printStackTrace();
}
myFrame.labs[i][j].setBackground(Color.yellow);
stack.push(myFrame.labs[i][j]);
}
//??
while(myFrame.labs[i][j+1].getBackground() != Color.BLACK&&myFrame.labs[i][1+j].getBackground() != Color.GREEN && myFrame.labs[i][j+1].getBackground() != Color.yellow&& myFrame.labs[i][j+1].getBackground() != Color.RED&& myFrame.labs[i][j+1].getBackground() != Color.pink){
if (myFrame.labs[i][++j].getBackground() != Color.GREEN){
myFrame.labs[i][j].setBackground(Color.yellow);
try{
Thread.sleep(100);
}
catch(InterruptedException e){
e.printStackTrace();
}
stack.push(myFrame.labs[i][j]);
}
}
//??
while(myFrame.labs[i-1][j].getBackground() != Color.BLACK &&myFrame.labs[i][j].getBackground() != Color.GREEN&& myFrame.labs[i-1][j].getBackground() != Color.yellow&& myFrame.labs[i-1][j].getBackground() != Color.RED&& myFrame.labs[i-1][j].getBackground() != Color.pink){
if (myFrame.labs[--i][j].getBackground() != Color.GREEN){
myFrame.labs[i][j].setBackground(Color.yellow);
try{
Thread.sleep(100);
}
catch(InterruptedException e){
e.printStackTrace();
}
stack.push(myFrame.labs[i][j]);
}
}
//??
while(myFrame.labs[i+1][j].getBackground() != Color.BLACK &&myFrame.labs[i][j].getBackground() != Color.GREEN&& myFrame.labs[i+1][j].getBackground() != Color.yellow&& myFrame.labs[i+1][j].getBackground() != Color.RED&& myFrame.labs[i+1][j].getBackground() != Color.pink){
if (myFrame.labs[++i][j].getBackground() != Color.GREEN){
myFrame.labs[i][j].setBackground(Color.yellow);
try{
Thread.sleep(100);
}
catch(InterruptedException e){
e.printStackTrace();
}
stack.push(myFrame.labs[i][j]);
}
}
if (myFrame.labs[i][j+1].getBackground() != Color.GREEN) {
try{
Thread.sleep(100);
}
catch(InterruptedException e){
e.printStackTrace();
}
JLabel XX= (JLabel) stack.peek();
i= XX.getX()/50;
j = XX.getY()/50;
int pp = 0;
if( myFrame.labs[i+1][j].getBackground() == Color.black||myFrame.labs[i+1][j].getBackground() == Color.pink||myFrame.labs[i+1][j].getBackground() == Color.yellow)
pp++;
if( myFrame.labs[i-1][j].getBackground() == Color.black||myFrame.labs[i-1][j].getBackground() == Color.pink||myFrame.labs[i-1][j].getBackground() == Color.yellow)
pp++;
if( myFrame.labs[i][j+1].getBackground() == Color.black||myFrame.labs[i][j+1].getBackground() == Color.pink||myFrame.labs[i][j+1].getBackground() == Color.yellow)
pp++;
if( myFrame.labs[i][j-1].getBackground() == Color.black||myFrame.labs[i][j-1].getBackground() == Color.pink||myFrame.labs[i][j-1].getBackground() == Color.yellow)
pp++;
if (myFrame.labs[i][j].getBackground() != Color.GREEN)
if(pp==4){
stack.pop();
XX.setBackground(Color.pink);
//System.out.println(i);
// System.out.println(j);
}//if
}//if
}//while
}
public static void main(String[] args) {
// MyFrame myFrame = new MyFrame();
Run R =new Run();
//R.run(1, 1);
R.run();
}
}
分析 :此處黑色代表障礙,白色代表可以走的路徑,黃色表示最終路徑,而粉色則是進棧之後出棧的標記。
try{
Thread.sleep(100);
}
catch(InterruptedException e){
e.printStackTrace();
}
用到了進程的休眠,讓進棧出棧能夠直觀的看出來
int pp = 0;
if( myFrame.labs[i+1][j].getBackground() == Color.black||myFrame.labs[i+1][j].getBackground() == Color.pink||myFrame.labs[i+1][j].getBackground() == Color.yellow)
pp++;
if( myFrame.labs[i-1][j].getBackground() == Color.black||myFrame.labs[i-1][j].getBackground() == Color.pink||myFrame.labs[i-1][j].getBackground() == Color.yellow)
pp++;
if( myFrame.labs[i][j+1].getBackground() == Color.black||myFrame.labs[i][j+1].getBackground() == Color.pink||myFrame.labs[i][j+1].getBackground() == Color.yellow)
pp++;
if( myFrame.labs[i][j-1].getBackground() == Color.black||myFrame.labs[i][j-1].getBackground() == Color.pink||myFrame.labs[i][j-1].getBackground() == Color.yellow)
pp++;
if (myFrame.labs[i][j].getBackground() != Color.GREEN)
if(pp==4){
stack.pop();
XX.setBackground(Color.pink);
//System.out.println(i);
// System.out.println(j);
}//if
這應該是本人的得意之作了,進行判斷什麽時候出棧。進過分析後發現,出棧是棧頂元素上下左右均不可走,即上下左右被黃色、粉色、黑色這三種顏色中的一種或幾種包圍了。所以,此處定義一個pp變量,在上下左右有黃色、粉色、黑色三種顏色任意幾種的時候,pp++,當pp==4,即上下左右都是這三種顏色的一種或幾種時,出棧。我想,我想啊,這應該是就是抽象思維的一種表現形式吧,抽象出四周環境的一致性,就行統一判斷,減少了代碼量。
Java非遞歸實現迷宮問題