2012-02-08 17 views
6

Vì vậy, tôi đang cố tạo một chương trình giải quyết mê cung có thể giải quyết một mê cung của X và O. Những gì tôi muốn làm là tạo ra một lớp các điểm, để tôi có thể tạo ra một mảng 2-chiều của các điểm mà sẽ cho phép in ấn một trang đầu ra cũng như thực hiện ngăn xếp để được tương đối đơn giản.Sử dụng ngăn xếp để di chuyển và giải quyết mê cung - Java

Thuật toán đơn giản nhất của ý tưởng chung tôi muốn thực hiện trong chương trình thực tế bản thân tôi tin rằng cần phải:

1) Move forward 
2) Are you at a wall? 
2a) If yes, turn left 
3) Are you at the finish? 
3a) If no, go to 1 
3b) If yes, solved 

Nhưng tôi đang gặp rắc rối đến với một sâu hơn thuật toán, cũng như nhận được điểm lớp của tôi nằm. Tôi biết cho các điểm tôi nên đã thiết lập tọa độ X, và thiết lập Y phối hợp cũng như getters cho cả hai là tốt. Bạn có nghĩ tôi cần nhiều phương pháp hơn hai phương pháp này không? Giống như, tôi có nên tạo một phương thức chuyển một tham số x, và y như là các tham số để tôi có thể chỉ đẩy các phương thức đó lại với nhau, thay vì thiết lập x và y riêng lẻ?

Đây là những gì một mê cung mẫu sẽ trông như thế nào, nơi bạn bắt đầu ở góc dưới bên và cố gắng đi qua để phía trên bên trái, với X là bức tường, và không gian như mở O trong mê cung:

O O O O O X O 
X X O X O O X 
O X O O X X X 
X X X O O X O 
X X X X O O X 
O O O O O O O 
X X O X X X O 
+1

Xin chào Copernikush, đây có phải là bài tập về nhà không? – DaveFar

+0

Tôi muốn sử dụng biểu đồ thay thế và sử dụng thuật toán djikstras để tìm đường dẫn. Đã có thư viện cho việc này. – willcodejavaforfood

+0

Mê cung của bạn có nhiều lần mở, sau đó có thể kết thúc quá trình truyền tải tại bất kỳ điểm nào trong số đó không? – 0605002

Trả lời

0

Bạn có thể sử dụng số

Stack<Point> points = new Stack<>(); 

// add a point 
Point p = new Point(x, y); 
if (points.contains(p)) 
    // been here before, in circles. 
else 
    points.add(p); 
1

Bạn có chắc chắn thuật toán của mình sẽ giải quyết được bất kỳ mê cung nào không? Tôi nghĩ rằng nó sẽ gặp khó khăn trong việc này đơn giản mock-up (trong đó S là bắt đầu và F là kết thúc):

xxxxxxxxxx 
Sooooooxxx 
xxxxxxoxxx 
xxxxxxFxxx 

thuật toán của bạn sẽ tiến hành dọc hành lang đầu tiên cho đến khi nó phải đối mặt với sự sụp đổ, rẽ trái, phải đối mặt với "phía bắc" bức tường, rẽ trái một lần nữa, và đi bộ trở lại hành lang đầu tiên, nơi nó sẽ rẽ trái hai lần nữa và tiếp tục lặp lại vấn đề này.

Thuật toán quy tắc bên phải (xem wikipedia page, cũng như các phần khác để biết thêm các mê cung) nên giải quyết bất kỳ mê cung nào mà không có vòng lặp và phải khá dễ thực hiện trong java.

+1

Liên kết đẹp, tôi không biết quy tắc tay phải (+1). Nhưng quy tắc đó chỉ hoạt động nếu mê cung được kết nối đơn giản .... – DaveFar

+0

Tôi cho rằng các nhân vật duy nhất trong Mê cung là của O và X. – Copernikush

+0

Phải, tôi chỉ sử dụng S và F để đánh dấu không gian O nơi bạn hoàn thành và bắt đầu. Bạn có gợi ý rằng trong mô hình của bạn, đi bộ xuống hành lang, quay lại và thoát khỏi mê cung thông qua mục nhập sẽ là kết quả có thể chấp nhận được? – Greg

0

Đối với các thuật toán bạn có thể sử dụng backtracking (EDIT mặc dù nó không hoàn toàn phù hợp với ý tưởng chung của bạn.) Bạn chỉ phải nhận ra chuyển động của bạn được "đẩy" vào một chồng ảo, và họ phải unpushed (và do đó bạn có thể phải tự mình thực hiện ngăn xếp nếu "robot" là một đối tượng thực sự di chuyển, nhưng bạn có thể dựa vào ngăn xếp cuộc gọi nếu bạn chỉ muốn giải quyết mê cung.

+0

+1 cho liên kết ngược. -1 vì thuật toán trừu tượng của Copernikush không yêu cầu backtracking. làm cho 0 trong tổng số;) – DaveFar

+0

@ DaveBall bạn hoàn toàn đúng, tôi phải ngừng lướt qua văn bản, đó là một thói quen rất xấu :) Tôi đã chỉnh sửa câu trả lời của mình để sửa lỗi. – kaoD

0

Đối với phần thuật toán, độ sâu đệ quy đầu tiên thông qua ngăn xếp được ưu tiên. Một cái gì đó dọc theo dòng:

currentSpot = (0,0) // The starting point // 

while(! currentSpot.isExit()) { 

    if (! currentSpot.left().isWall()) stack.push(currentSpot.left()); 
    if (! currentSpot.forward().isWall()) stack.push(currentSpot.forward()); 
    if (! currentSpot.right().isWall()) stack.push(currentSpot.right()); 

    currentSpot = stack.pop(); // Get the next location // 
} 

Bạn sẽ muốn lớp điểm trở lại điểm tiếp theo theo từng hướng nhất định (trừ lùi), cũng như phát hiện khi bạn ở các cạnh của mê cung. Có thể bạn sẽ muốn một lớp Maze chứa tất cả các điểm, in ấn, lưu trữ X/O, vv Vì vậy, bạn có thể thay thế currentSpot = (0,0) ban đầu bằng currentSpot = Maze.getStartingSpot() ;

+0

Ngoài ra, psuedocode này giả định rằng tất cả mê cung sẽ có một giải pháp. Nếu bạn muốn bảo vệ chống lại các mê cung không thể giải quyết được, thì bạn nên thay đổi thời gian trong khi (! CurrentSpot.isExit() && stack.size()> 0). Sau đó, bạn có thể kiểm tra một mê cung được giải quyết thực tế bằng cách kiểm tra currentSpot.isExit() sau vòng lặp while. –

+0

Khi tạo lớp Điểm, làm cách nào để chuyển tiếp, sang trái, sang phải và phát hiện khi tôi ở cạnh mê cung/ – Copernikush

+0

Khi bạn tạo mê cung, lý tưởng nhất là bạn có một lớp Mê cung chứa tổng thể cấu trúc và điểm. Tại thời điểm đó, lớp Point chỉ có thể ủy quyền cho Maze để trả về điểm tiếp theo. –

0

Đối với thuật toán của bạn, bạn không cần ngăn xếp. Chỉ khi bạn sử dụng backtracking để hoàn tác quyết định truyền tải, bạn sẽ cần một ngăn xếp.

0

Chúng tôi giải quyết vấn đề này một lần khi tôi còn đi học và chúng tôi sử dụng một giải pháp tương tự ở bên phải/quy tắc bàn tay trái. Tôi tin rằng chúng tôi đã làm điều này trong khi tìm hiểu về Danh sách được liên kết. Tóm lại, thuật toán giống như sau:

  1. Chuyển sang trái. Nếu có thể, hãy lặp lại.
  2. Nếu không, hãy đi thẳng. Nếu có thể, hãy quay lại bước 1.
  3. Nếu không, hãy đi thẳng. Nếu có thể, hãy quay lại bước 1.

Ở mỗi bước, bạn cũng kiểm tra xem vị trí bạn đang đứng là kết thúc hay không. Nếu bạn không thể tiếp tục (ví dụ, không thể đi sang trái, thẳng, hoặc phải), bạn đánh dấu vị trí bạn đang đứng trên là 'đã truy cập' và sao lưu. Rửa sạch và lặp lại.