2016年3月2日 星期三

範例:老鼠走迷宮_堆疊

入口 ■■■■■■■■■■■■■
 ■■■■ ■■■■■■■■
 ■■■■ ■■■■■■■■
           ■■■
■■ ■■■■ ■■■■■■
■■ ■■■■ ■■■■■■
■■ ■■■■ ■■■■■■
■■ ■■■■       出口
■■ ■■■■ ■■■■■■
■■ ■■■■ ■■■■■■
■■■■■■■■■■■■■■
■■■■■■■■■■■■■■

老鼠走迷宮,以 0 代表牆壁 1 代表可走的路,只要走過的路就記錄起來,利用stack 後進先出的概念,正確的座標放進 stack 裡,錯誤的話就回頭直到有另一條沒走過的路,直到找到最右邊的出口。

MouseMaze:
public class MouseMaze {
public static void main(String[] args) {
int[][] map=   {{1,0,0,0,0,0,0,0,0,0,0,0,0,0},
{1,0,0,0,0,1,0,0,0,0,0,0,0,0},
{1,0,0,0,0,1,0,0,0,0,0,0,0,0},
{1,1,1,1,1,1,1,1,1,1,1,0,0,0},
{0,0,1,0,0,0,0,1,0,0,0,0,0,0},
{0,0,1,0,0,0,0,1,0,0,0,0,0,0},
{0,0,1,0,0,0,0,1,0,0,0,0,0,0},
{0,0,1,0,0,0,0,1,1,1,1,1,1,1},
{0,0,1,0,0,0,0,1,0,0,0,0,0,0},
{0,0,1,0,0,0,0,1,0,0,0,0,0,0},
{0,0,1,0,0,0,0,1,0,0,0,0,0,0},
{0,0,1,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
int range=map.length;//取得 map 長度
boolean check=false;//判斷是否還有路可以走
int x=0;
int y=0;

MyStack s=new MyStack(0,0);

do {
if(y+1<range&&map[x][y+1]==1) {//向右走
map[x][y+1]=0;//設定要前往的格子為0,紀錄為走過了
check=true;
y=y+1;
}
else if(y-1>=0&&map[x][y-1]==1) {//向左走
map[x][y-1]=0;
check=true;
y=y-1;
}
else if(x+1<range&&map[x+1][y]==1) {//向下走
map[x+1][y]=0;
check=true;
x=x+1;
}
else if(x-1>=0&&map[x-1][y]==1) {//向上走
map[x-1][y]=0;
check=true;
x=x-1;
}
else {
check=false;//上下左右都無法行走的時候 check 為 false
}

if(check==true){//有路可以走
s.push(x,y);//在 stack 加進一格的座標
System.out.println("Go to : (" + s.peekX() + " , " + s.peekY() + ")");
}
else {//沒路可以走
System.out.println("Back from : (" + s.peekX() + " , " + s.peekY() + ")");
s.pop();//在 stack 移除後退的格子的座標
y=s.peekY();
x=s.peekX();
map[x][y]=0;
}
if(y==range) {//到了邊界,跳出迴圈
break;
}
}while(true);

s.displayStack();//執行 stack 裡的印出佇列內容的function

if(y==range-1) {
System.out.print("You win!");
}
else {
System.out.print("You dead!");
}
}
}

在 Stack 的部分因為要存 X 及 Y 座標,所以自訂一個 class 並加入需要的功能。
MyStack:
public class MyStack {
private Node last;
private Node front;
private Node first;

public MyStack(int x,int y) { //定義
first=new Node();
last=new Node();
first.setX(x);
first.setY(y);
first.setNext(null);
last.setFront(first);
last=first;
}
public void push(int inputX,int inputY) { //放置新資料
Node newNode=new Node();
Node oldNode=new Node();

if(first.getNext()==null) {
first.setNext(newNode);
}
oldNode=last;      
newNode.setX(inputX);
newNode.setY(inputY);
newNode.setFront(oldNode);
last.setNext(newNode);
last=newNode;
}
public int peekX(){ //抓取最後的X值
return last.getX();
}
public int peekY(){ //抓取最後的Y值
return last.getY();
}
public void displayStack(){ //印出stack的內容
Node tmpNode;
tmpNode = first.getNext();
System.out.print("佇列內容:");
while(tmpNode != null) {
System.out.print("(" + tmpNode.getX() + " , " + tmpNode.getY() + ")");
tmpNode = tmpNode.getNext();
System.out.println();
}
}
public void pop(){ //刪除最後存進的資料
Node tmpNode;    
tmpNode=last.getFront();
last.setFront(tmpNode.getFront());
last=tmpNode;
}
}
節點紀錄資料部分需要能記住前一格與下一格的資料,所以多了front 及 next
Node:
public class Node {
private int x;
private int y;   // 節點資料 ,定義X及Y
private Node front;
private Node next;
public void setX(int x) { //設定值
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public int getX() { //取得值
return x;
}
public int getY() {
return y;
}
public void setFront(Node front) { //設定前一格
this.front = front;
}
public Node getFront() { //取得前一格
return front;
}
public void setNext(Node next) { //設定下一格
this.next = next;
}
public Node getNext() { //取得下一格
return next;
}
}

如果您喜歡我的文章,請在文章最末按5下Like!
我將得到LikeCoin的回饋:)

回饋由LikeCoin基金會出資,您只要註冊/登入帳號(FB、Google帳號都可以註冊,流程超快),按L五次左鍵,可以贊助我的文章且完全不會花到錢!
支持創作,正向交流:)

沒有留言:

張貼留言