Maze
此專案已打包為 exe 檔案,電腦有 gre 即可下載運行 download
先看效果圖


直接上代碼啦
- 啟動游戲單獨成類
package MyMaze;
public class Maze {
public static void main(String[] args) {
// 啟動迷宮游戲
new Figure().init();
}
}
- 保存迷宮每一個格子的資訊
package MyMaze;
/**
* 本類保存迷宮中每一個格子的資訊
*/
public class Place {
//定義當前格子是否可走,若 wall → 0,則表示可走,若 wall → 1,則表示不可走
private int wall;
//表示當前格子是否被搜索過
private boolean search = false;
//表示當前格子的四個方向分別是哪些格子,搜索時的上一個格子,
private Place east = null, south = null, west = null, north = null, last = null;
//保存迷宮格子位置索引
private int index = 0;
public Place(int wall) {
this.wall = wall;
}
public int getWall() {
return wall;
}
public void setWall(int wall) {
this.wall = wall;
}
public boolean isSearch() {
return search;
}
public void setSearch(boolean search) {
this.search = search;
}
public Place getEast() {
return east;
}
public void setEast(Place east) {
this.east = east;
}
public Place getSouth() {
return south;
}
public void setSouth(Place south) {
this.south = south;
}
public Place getWest() {
return west;
}
public void setWest(Place west) {
this.west = west;
}
public Place getNorth() {
return north;
}
public void setNorth(Place north) {
this.north = north;
}
public Place getLast() {
return last;
}
public void setLast(Place last) {
this.last = last;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
- 創建迷宮
package MyMaze;
/**
* 創建迷宮及提供迷宮的一些引數
*/
public class CreateMaze {
// 定義迷宮規模
private int size;
// 定義迷宮的入口和出口
private int entrance, exit;
// 用一維陣串列示迷宮,0 號下標位置空出
private Place[] maze = null;
// 設定迷宮中每一個格子下一步能移動的方向
private void setDirections(Place[] maze) {
for (int i = 1; i <= size * size; i++) {
if (i % size != 0 && maze[i + 1].getWall() == 0 && maze[i + 1] != null) {
maze[i].setEast(maze[i + 1]);
}
if (i <= size * (size - 1) && maze[i + size].getWall() == 0 && maze[i + size] != null) {
maze[i].setSouth(maze[i + size]);
}
if (i % size != 1 && maze[i - 1].getWall() == 0 && maze[i - 1] != null) {
maze[i].setWest(maze[i - 1]);
}
if (i > size && maze[i - size].getWall() == 0 && maze[i - size] != null) {
maze[i].setNorth(maze[i - size]);
}
}
}
// 設定默認迷宮引數
public CreateMaze() {
this.size = 10;
this.entrance = 1;
this.exit = this.size * this.size;
}
// 呼叫有參建構式獲取新迷宮大小及入口和出口
public CreateMaze(int size, int entrance, int exit) {
this.size = size;
this.entrance = entrance;
this.exit = exit;
}
// 回傳當前迷宮格隨機狀態
public Place[] getMaze() {
maze = new Place[size * size + 1];
for (int i = 1; i <= size * size; i++) {
maze[i] = new Place((int) (Math.random() * 2));
maze[i].setIndex(i); // 設為 0 或 1
}
setDirections(maze);
return maze;
}
// 回傳入口索引
public int getEntrance() {
return entrance;
}
// 設定入口索引
public void setEntrance(int entrance) {
this.entrance = entrance;
}
// 回傳出口索引
public int getExit() {
return exit;
}
// 設定出口索引
public void setExit(int exit) {
this.exit = exit;
}
// 回傳迷宮大小 size 表示邊長
public int getSize() {
return size;
}
// 設定迷宮邊長
public void setSize(int size) {
this.size = size;
}
}
- 對迷宮路徑進行搜索
package MyMaze;
/**
* 迷宮游戲
* 本類中對迷宮進行路徑搜索,保存合格迷宮的相關資訊(合格迷宮只有1條路徑)
*/
public class Path {
//呼叫創建迷宮類
CreateMaze newMaze;
//保存迷宮路徑
boolean[] path;
//保存合格迷宮
Place[] maze = null;
// 入口位置索引
int entrance;
// 出口位置索引
int exit;
private int searchPathNumber() {
// 獲取當前格狀態
maze = newMaze.getMaze();
// 定義路徑數
int pathAll = 0;
// 保存當前路徑
Place[][] path = new Place[maze.length][];
for (int i = 1; i < path.length; i++) {
path[i] = new Place[5];
}
// 當前格子路徑陣列下標
int pathTop = 0;
// 當前位置的下一位置的可能數下標
int[] top = new int[maze.length];
for (int i = 1; i < top.length; i++) {
top[i] = -1;
}
//尋找迷宮路徑數
if (maze[entrance].getWall() == 0) {
pathTop++;
top[pathTop]++;
path[pathTop][top[pathTop]] = maze[entrance];
while (pathTop > 0) {
//判斷當前位置是否為結束位置,是,保存迷宮路徑,退回上一位置,否,尋找下一不重復位置
if (path[pathTop][0] == maze[exit]) {
pathAll++;
top[pathTop]--;
pathTop--;
} else if (!path[pathTop][top[0]].isSearch()) {
//尋找當前位置的下一位置的可能數
if (path[pathTop][0].getEast() != null && path[pathTop][0].getEast() != path[pathTop][0].getLast() && !path[pathTop][0].getEast().isSearch()) {
path[pathTop][++top[pathTop]] = path[pathTop][0].getEast();
}
if (path[pathTop][0].getSouth() != null && path[pathTop][0].getSouth() != path[pathTop][0].getLast() && !path[pathTop][0].getSouth().isSearch()) {
path[pathTop][++top[pathTop]] = path[pathTop][0].getSouth();
}
if (path[pathTop][0].getWest() != null && path[pathTop][0].getWest() != path[pathTop][0].getLast() && !path[pathTop][0].getWest().isSearch()) {
path[pathTop][++top[pathTop]] = path[pathTop][0].getWest();
}
if (path[pathTop][0].getNorth() != null && path[pathTop][0].getNorth() != path[pathTop][0].getLast() && !path[pathTop][0].getNorth().isSearch()) {
path[pathTop][++top[pathTop]] = path[pathTop][0].getNorth();
}
path[pathTop][0].setSearch(true);
}
//當前位置的下一位置的所有可能依次查詢,無下一位置則回退到上一位置
if (top[pathTop] == 0) {
path[pathTop][0].setLast(null);
path[pathTop][0].setSearch(false);
top[pathTop]--;
pathTop--;
}
else {
pathTop++;
top[pathTop]++;
path[pathTop][0] = path[pathTop - 1][top[pathTop - 1]--];
path[pathTop][0].setLast(path[pathTop - 1][0]);
}
}
}
return pathAll;
}
// 設定路徑
private void setPath() {
// 保存當前路徑
Place[][] path = new Place[maze.length][];
for (int i = 1; i < path.length; i++) {
path[i] = new Place[5];
}
// 當前路徑陣列下標
int pathTop = 0;
// 當前位置的下一位置的可能數下標
int[] top = new int[maze.length];
for (int i = 1; i < top.length; i++) {
top[i] = -1;
}
//尋找迷宮路徑數
if (maze[entrance].getWall() == 0) {
pathTop++;
top[pathTop]++;
path[pathTop][top[pathTop]] = maze[entrance];
while (pathTop > 0) {
//判斷當前位置是否為結束位置,是,保存迷宮路徑,退回上一位置,否,尋找下一不重復位置
if (path[pathTop][0] == maze[exit]) {
for (int i = 1; i <= pathTop; i++) {
this.path[path[i][0].getIndex()] = true;
}
top[pathTop]--;
pathTop--;
break;
} else if (!path[pathTop][top[0]].isSearch()) {
//尋找當前位置的下一位置的可能數
if (path[pathTop][0].getEast() != null && path[pathTop][0].getEast() != path[pathTop][0].getLast() && !path[pathTop][0].getEast().isSearch()) {
path[pathTop][++top[pathTop]] = path[pathTop][0].getEast();
}
if (path[pathTop][0].getSouth() != null && path[pathTop][0].getSouth() != path[pathTop][0].getLast() && !path[pathTop][0].getSouth().isSearch()) {
path[pathTop][++top[pathTop]] = path[pathTop][0].getSouth();
}
if (path[pathTop][0].getWest() != null && path[pathTop][0].getWest() != path[pathTop][0].getLast() && !path[pathTop][0].getWest().isSearch()) {
path[pathTop][++top[pathTop]] = path[pathTop][0].getWest();
}
if (path[pathTop][0].getNorth() != null && path[pathTop][0].getNorth() != path[pathTop][0].getLast() && !path[pathTop][0].getNorth().isSearch()) {
path[pathTop][++top[pathTop]] = path[pathTop][0].getNorth();
}
path[pathTop][0].setSearch(true);
}
//當前位置的下一位置的所有可能依次查詢,無下一位置則回退到上一位置
if (top[pathTop] == 0) {
path[pathTop][0].setLast(null);
path[pathTop][0].setSearch(false);
top[pathTop]--;
pathTop--;
} else {
pathTop++;
top[pathTop]++;
path[pathTop][0] = path[pathTop - 1][top[pathTop - 1]--];
path[pathTop][0].setLast(path[pathTop - 1][0]);
}
}
}
}
// 當路徑唯一時,設定路徑
private void searchPath() {
while (true) {
if (searchPathNumber() == 1) {
setPath();
break;
}
}
}
// 默認建構式
public Path() {
newMaze = new CreateMaze();
path = new boolean[newMaze.getSize() * newMaze.getSize() + 1];
this.entrance = newMaze.getEntrance();
this.exit = newMaze.getExit();
}
// 多載建構式
public Path(int size, int entrance, int exit) {
newMaze = new CreateMaze(size, entrance, exit);
path = new boolean[newMaze.getSize() * newMaze.getSize() + 1];
this.entrance = newMaze.getEntrance();
this.exit = newMaze.getExit();
}
// 獲取當前格子
public Place[] getMaze() {
searchPath();
return maze;
}
// 獲取新迷宮大小
public int getSize() {
return newMaze.getSize();
}
// 獲取入口
public int getEntrance() {
return entrance;
}
// 獲取出口
public int getExit() {
return exit;
}
// 回傳當前格子為路還是墻
public boolean[] getPath() {
return path;
}
// 回傳迷宮
public CreateMaze getNewMaze() {
return newMaze;
}
}
- 構建圖形界面
package MyMaze;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/*
* 本類為迷宮游戲提供圖形化界面
*/
public class Figure {
// 定義路徑
Path path;
// 定義當前迷宮周圍狀態
Place[] maze = null;
// 用按鈕實作迷宮格
JButton[] button = null;
boolean[] isPath = null;
// A* 尋路界面 比較遺憾的是只實作了圖形化界面,A* 自動尋路并未實作,有機會有能力再更吧
class FindMaze extends JFrame implements ActionListener {
public FindMaze() {
super("A* Maze");
// 界面大小
this.setSize(500, 500);
// 回傳默認工具箱
Toolkit kit = Toolkit.getDefaultToolkit();
// 獲取螢屏尺寸
Dimension screenSize = kit.getScreenSize();
// 獲取螢屏寬度
int screenWidth = screenSize.width;
// 獲取螢屏高度
int screenHeight = screenSize.height;
// 獲取界面視窗寬度
int windowWidth = this.getWidth();
// 獲取界面視窗高度
int windowHeight = this.getHeight();
// 界面居中
this.setLocation((screenWidth - windowWidth) / 2, (screenHeight - windowHeight) / 2);
// 四行一列布局
this.setLayout(new GridLayout(path.getSize(), path.getSize()));
maze = path.getMaze();
int entrance = path.getEntrance();
int exit = path.getExit();
button = new JButton[maze.length];
for (int i = 1; i < maze.length; ++i) {
// 當前格子是路則設定活動指令為 1,背景顏色為綠色
if (maze[i].getWall() == 0) {
button[i] = new JButton();
button[i].setActionCommand("1");
button[i].setBackground(Color.GREEN);
}
// 當前格子為墻則設定活動指令為 0,標記為灰色
if (maze[i].getWall() == 1) {
button[i] = new JButton();
button[i].setActionCommand("0");
button[i].setBackground(Color.LIGHT_GRAY);
}
}
for (int i = 1; i < button.length; i++) {
button[i].addActionListener(this);
add(button[i]);
}
button[path.getSize() * path.getSize()].setActionCommand("退出");
button[path.getSize() * path.getSize()].setText("退出");
button[path.getSize() * path.getSize()].setFont(new Font("宋體", 0, 7));
addWindowListener(new closeWin());
this.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("退出")) {
dispose();
Figure figure = new Figure();
figure.init();
}
}
}
// 啟動游戲界面
class MazeGameFigure extends JFrame implements ActionListener {
public MazeGameFigure() {
super("迷宮游戲");
}
public void init() {
// 界面大小
this.setSize(500, 500);
// 回傳默認工具箱
Toolkit kit = Toolkit.getDefaultToolkit();
// 獲取螢屏尺寸
Dimension screenSize = kit.getScreenSize();
// 獲取螢屏寬度
int screenWidth = screenSize.width;
// 獲取螢屏高度
int screenHeight = screenSize.height;
// 獲取界面視窗寬度
int windowWidth = this.getWidth();
// 獲取界面視窗高度
int windowHeight = this.getHeight();
// 界面居中
this.setLocation((screenWidth - windowWidth) / 2, (screenHeight - windowHeight) / 2);
// 四行一列布局
this.setLayout(new GridLayout(5, 1));
JLabel welcom = new JLabel("歡迎進入迷宮游戲!");
welcom.setBackground(Color.CYAN);
welcom.setFont(new Font("宋體", 1, 25));
JButton find = new JButton("A* 尋路");
find.setFont(new Font("宋體", 1, 25));
JButton start = new JButton("開始游戲");
start.setFont(new Font("宋體", 1, 25));
JButton set = new JButton("游戲設定");
set.setFont(new Font("宋體", 1, 25));
JButton end = new JButton("退出游戲");
end.setFont(new Font("宋體", 1, 25));
find.setBackground(Color.PINK);
start.setBackground(Color.PINK);
set.setBackground(Color.PINK);
end.setBackground(Color.PINK);
add(welcom);
add(find);
add(start);
add(set);
add(end);
find.addActionListener(this);
start.addActionListener(this);
set.addActionListener(this);
end.addActionListener(this);
addWindowListener(new closeWin());
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("A* 尋路")) {
dispose();
new FindMaze();
}
// 點擊開始游戲生成迷宮
if (e.getActionCommand().equals("開始游戲")) {
MazeFigure mazeFigure = new MazeFigure();
mazeFigure.init();
dispose();
}
// 點擊游戲設定進入設定模式
if (e.getActionCommand().equals("游戲設定")) {
MazeSetFigure mazeSetFigure = new MazeSetFigure();
mazeSetFigure.init();
dispose();
}
if (e.getActionCommand().equals("退出游戲")) {
dispose();
}
}
}
// 開始游戲界面
class MazeFigure extends JFrame implements ActionListener {
public MazeFigure() {
super("Maze");
}
public void init() {
this.setSize(500, 500);
this.setBackground(Color.BLACK);
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension screenSize = kit.getScreenSize();
int screenWidth = screenSize.width;
int screenHeight = screenSize.height;
int windowWidth = this.getWidth();
int windowHeight = this.getHeight();
this.setLocation((screenWidth - windowWidth) / 2, (screenHeight - windowHeight) / 2);
// 獲取迷宮尺寸設計按鈕布局
this.setLayout(new GridLayout(path.getSize(), path.getSize()));
maze = path.getMaze();
int entrance = path.getEntrance();
int exit = path.getExit();
button = new JButton[maze.length];
for (int i = 1; i < maze.length; i++) {
// 當前格子是路則設定活動指令為 1,背景顏色為綠色
if (maze[i].getWall() == 0) {
button[i] = new JButton();
button[i].setActionCommand("1");
button[i].setBackground(Color.GREEN);
}
// 當前格子為墻則設定活動指令為 0,標記為灰色
if (maze[i].getWall() == 1) {
button[i] = new JButton();
button[i].setActionCommand("0");
button[i].setBackground(Color.LIGHT_GRAY);
}
}
button[entrance].setText("入口");
button[entrance].setFont(new Font("宋體", 1, 7));
button[exit].setText("出口");
button[exit].setFont(new Font("宋體", 1, 7));
// 為每個按鈕添加監聽器
for (int i = 1; i < button.length; i++) {
button[i].addActionListener(this);
add(button[i]);
}
addWindowListener(new closeWin());
this.setVisible(true);
}
// 判斷是否完成通路
private boolean isComplete() {
isPath = path.getPath();
for (int i = 1; i < isPath.length; i++) {
if (isPath[i] && button[i].getBackground() != Color.YELLOW) {
return false;
}
}
return true;
}
public void actionPerformed(ActionEvent e) {
JButton button = (JButton) e.getSource();
if (button.getActionCommand().equals("1")) {
if (button.getBackground() == Color.GREEN) {
button.setBackground(Color.YELLOW);
} else if (button.getBackground() == Color.YELLOW) {
button.setBackground(Color.GREEN);
}
}
if (isComplete()) {
CongratulationFigure congratulationFigure = new CongratulationFigure();
congratulationFigure.init();
this.dispose();
}
}
}
// 迷宮設定界面
class MazeSetFigure extends Frame implements ActionListener, TextListener {
String newSize, newEntrance, newExit;
JTextField setMaze, setEntrance, setExit;
int size, entrance, exit;
public MazeSetFigure() {
super("迷宮設定");
}
public void init() {
this.setSize(500, 400);
this.setBackground(Color.WHITE);
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension screenSize = kit.getScreenSize();
int screenWidth = screenSize.width;
int screenHeight = screenSize.height;
int windowWidth = this.getWidth();
int windowHeight = this.getHeight();
this.setLocation((screenWidth - windowWidth) / 2, (screenHeight - windowHeight) / 2);
GridLayout layout = new GridLayout(5, 2);
this.setLayout(layout);
JLabel size = new JLabel("迷宮規模");
size.setFont(new Font("宋體", 1, 20));
JLabel entrance = new JLabel("迷宮入口");
entrance.setFont(new Font("宋體", 1, 20));
JLabel exit = new JLabel("迷宮出口");
exit.setFont(new Font("宋體", 1, 20));
JButton menu = new JButton("回傳選單");
menu.setFont(new Font("宋體", 1, 20));
JButton set = new JButton("設定完成");
set.setFont(new Font("宋體", 1, 20));
setMaze = new JTextField("10");
setEntrance = new JTextField("左上角");
setEntrance.setFont(new Font("宋體", 1, 18));
setExit = new JTextField("右下角");
setExit.setFont(new Font("宋體", 1, 18));
JLabel tip = new JLabel("tips:出入口只能設定為四個角");
JLabel tips = new JLabel("即左上角,右上角,左下角,右下角");
add(tip);
add(tips);
add(size);
add(setMaze);
add(entrance);
add(setEntrance);
add(exit);
add(setExit);
add(menu);
add(set);
menu.addActionListener(this);
set.addActionListener(this);
setMaze.addActionListener(this);
setEntrance.addActionListener(this);
setExit.addActionListener(this);
addWindowListener(new closeWin());
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("回傳選單")) {
dispose();
Figure figure = new Figure();
figure.init();
}
if (e.getActionCommand().equals("設定完成")) {
boolean isSizeReasonable = true;
boolean isEntranceReasonable = true;
boolean isExitReasonable = true;
newSize = setMaze.getText();
newEntrance = setEntrance.getText();
newExit = setExit.getText();
try {
size = Integer.parseInt(newSize);
} catch (Exception ex) {
isSizeReasonable = false;
}
if (isSizeReasonable == true) {
if (newEntrance.equals("左上角")) {
entrance = 1;
} else if (newEntrance.equals("右上角")) {
entrance = size;
} else if (newEntrance.equals("左下角")) {
entrance = size * (size - 1) + 1;
} else if (newEntrance.equals("右下角")) {
entrance = size * size;
} else {
isEntranceReasonable = false;
}
if (newExit.equals("左上角")) {
exit = 1;
} else if (newExit.equals("右上角")) {
exit = size;
} else if (newExit.equals("左下角")) {
exit = size * (size - 1) + 1;
} else if (newExit.equals("右下角")) {
exit = size * size;
} else {
isExitReasonable = false;
}
if (isEntranceReasonable == true && isExitReasonable == true) {
if (entrance == exit) {
isEntranceReasonable = false;
isExitReasonable = false;
}
}
}
if (isSizeReasonable == true && isEntranceReasonable == true && isExitReasonable == true) {
dispose();
Figure figure = new Figure(size, entrance, exit);
figure.init();
} else {
SetErrorFigure setErrorFigure = new SetErrorFigure();
setErrorFigure.init();
dispose();
}
}
}
public void textValueChanged(TextEvent e) {
}
}
// 通過迷宮游戲界面
class CongratulationFigure extends Frame implements ActionListener {
public CongratulationFigure() {
super("恭喜");
}
public void init() {
this.setSize(220, 200);
this.setBackground(Color.WHITE);
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension screenSize = kit.getScreenSize();
int screenWidth = screenSize.width;
int screenHeight = screenSize.height;
int windowWidth = this.getWidth();
int windowHeight = this.getHeight();
this.setLocation((screenWidth - windowWidth) / 2, (screenHeight - windowHeight) / 2);
this.setLayout(new GridLayout(2, 1));
JLabel text = new JLabel("恭喜您成功走出迷宮!");
JButton button = new JButton("確認");
button.setBackground(Color.WHITE);
add(text);
add(button);
button.addActionListener(this);
addWindowListener(new closeWin());
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("確認")) {
dispose();
Figure figure = new Figure();
figure.init();
}
}
}
// 游戲設定資料錯誤界面
class SetErrorFigure extends Frame implements ActionListener {
public SetErrorFigure() {
super("錯誤");
}
public void init() {
this.setSize(230, 100);
this.setBackground(Color.WHITE);
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension screenSize = kit.getScreenSize();
int screenWidth = screenSize.width;
int screenHeight = screenSize.height;
int windowWidth = this.getWidth();
int windowHeight = this.getHeight();
this.setLocation((screenWidth - windowWidth) / 2, (screenHeight - windowHeight) / 2);
this.setLayout(new GridLayout(2, 1));
JLabel text = new JLabel("您輸入的資料不合理,設定失敗!");
JButton button = new JButton("確認");
button.setBackground(Color.WHITE);
add(text);
add(button);
button.addActionListener(this);
addWindowListener(new closeWin());
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("確認")) {
dispose();
Figure figure = new Figure();
figure.init();
}
}
}
class closeWin extends WindowAdapter {
public void windowClosing(WindowEvent e) {
Window w = e.getWindow();
w.dispose();
}
}
public Figure() {
path = new Path();
}
public Figure(int size, int entrance, int exit) {
path = new Path(size, entrance, exit);
}
public void init() {
MazeGameFigure mazeGameFigure = new MazeGameFigure();
mazeGameFigure.init();
}
}
核心原始碼摘自 鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/237144.html
標籤:其他
下一篇:Unity NGUI部分講解
