我正在合作项目,我的合作伙伴为游戏创建了一个解算器类,而我的部分是创建MazeGUI。
当你单击Solve JButton
时,它应该突出显示它在GUI本身上所采用的路径,但它只突出显示它“结束”的位置,这是最右下角不应该因为它是“W”而可以访问。如果有解决方案,“F”将变为“RIP”,如果迷宫没有解决方案,则应该有JLabel
表示迷宫无法解析。
如何在ActionListener下的代码中为solveButton输入所有这些?
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MazeGUI {
String appName = "Zombie Attack!";
JLabel appNameLabel;
private JFrame frame;
private JPanel buttonPanel, solvePanel;
private JButton solveButton;
// private JLabel noSolutionLabel;
private final int rowCount = 10;
private final int colCount = 10;
private final int startRow = 0;
private final int startCol = 1;
private final int endRow = rowCount - 1;
private final int endCol = colCount - 2;
String[][] map;
private void createAndShowGui() {
frame = new JFrame("Zombie Attack!");
solveButton = new JButton("Solve");
map = new String[rowCount][colCount];
buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(rowCount, colCount, 2, 2));
appNameLabel = new JLabel(appName);
for (int rows = 0; rows < rowCount; rows++) {
for (int columns = 0; columns < colCount; columns++) {
map[rows][columns] = " ";
final JLabel jlabel = new JLabel("");
jlabel.setBackground(Color.BLACK);
if (rows == startRow && columns == startCol) {
jlabel.setBackground(Color.BLACK);
jlabel.setForeground(Color.MAGENTA);
jlabel.setText("S");
map[startRow][startCol] = "S";
}
if (rows == endRow && columns == endCol) {
jlabel.setBackground(Color.BLACK);
jlabel.setForeground(Color.MAGENTA);
jlabel.setText("F");
map[endRow][endCol] = "F";
}
if (!(rows == startRow && columns == startCol || rows == endRow
&& columns == endCol)) {
if (rows == 0 || rows == rowCount - 1 || columns == 0
|| columns == colCount - 1) {
jlabel.setBackground(Color.LIGHT_GRAY);
map[rows][columns] = "W";
}
}
final int rc = rows;
final int cc = columns;
jlabel.addMouseListener(new MouseListener() {
boolean clicked = false;
@Override
public void mouseClicked(MouseEvent e) {
if (clicked == false) {
clicked = true;
jlabel.setBackground(Color.LIGHT_GRAY);
map[rc][cc] = "W";
} else {
clicked = false;
jlabel.setBackground(Color.BLACK);
map[rc][cc] = "";
}
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
});
solveButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
MazeSolver solver;
solver = new MyMazeSolver();
solver.solve(map);
jlabel.setBackground(Color.RED);
jlabel.setForeground(Color.GREEN);
jlabel.setText("RIP");
for (int i = 0; i < map.length; i++){
for (int j = 0; j < map[0].length; j++){
System.out.print(map[i][j] + " ");
}
System.out.println();
}
}
});
System.out.print(map[rows][columns] + " ");
buttonPanel.add(jlabel);
jlabel.setOpaque(true);
}
System.out.println();
}
frame.add(appNameLabel, BorderLayout.NORTH);
frame.add(buttonPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setSize(500, 500);
frame.add(solveButton, BorderLayout.SOUTH);
frame.setVisible(true);
}
public static void main(String[] args) {
MazeGUI maze = new MazeGUI();
maze.createAndShowGui();
}
}
这是解算器的界面:
public interface MazeSolver {
public String[][] solve(String[][] map);
}
这是我的合作伙伴代码(坐标类):
public class Coordinate {
private int row;
private int col;
public Coordinate(int row, int col) {
this.row = row;
this.col = col;
}
public int getRow() {
return row;
}
public int getCol() {
return col;
}
@Override
public String toString() {
return "Coordinate [row=" + row + ", col=" + col + "]";
}
}
MyMazeSolver类:
import java.util.ArrayList;
public class MyMazeSolver implements MazeSolver {
private static ArrayList<Coordinate> coordinates = new ArrayList<Coordinate>();
private int row;
private int col;
@Override
public String[][] solve(String[][] map) {
startingPos(map);
//for (int i = 0; i < 15; i++) {
do{
makeMove(map);
if (nextToF(map, row, col)) {
System.out.println(row + "" + col);
map[row][col] = "X";
} else {
if (isExplorable(map, row, col)) {
map[row][col] = "D";
} else {
map[row][col] = "X";
}
if(deadEnd(map, row, col)){
}
}
addCoordinates(row, col);
//}
}while(!isEnded(map));
print(map);
// delete printCoordinates
printCoordinates();
return map;
}
public void startingPos(String[][] map) {
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[0].length; j++) {
if (map[i][j].contains("S")) {
row = i;
col = j;
}
}
}
}
public boolean clear(String[][] map, int row, int col) {
if (row <= 0 || col <= 0 ||row > map.length) {
return false;
}
if (col <= 0 || col > map[0].length) {
return false;
}
if ("S".equals(map[row][col])) {
return false;
}
if ("W".equals(map[row][col])) {
return false;
}
if ("X".equals(map[row][col])) {
return false;
}
if ("D".equals(map[row][col])) {
return false;
}
return true;
}
public void makeMove(String[][] map) {
if (clear(map, row + 1, col)) {
row++;
} else if (clear(map, row, col - 1)) {
col--;
} else if (clear(map, row, col + 1)) {
col++;
} else if (clear(map, row, col)) {
row--;
}
}
public boolean explorable(String[][] map, int row, int col) {
if (row > map.length) {
return false;
}
if (col > map[0].length) {
return false;
}
if (map[row][col].equals("S")) {
return false;
}
if (map[row][col].equals("W")) {
return false;
}
if (map[row][col].equals("X")) {
return false;
}
if (map[row][col].equals("D")) {
return false;
}
return true;
}
public boolean isExplorable(String[][] map, int row, int col) {
int squares = 0;
if (explorable(map, row + 1, col)) {
squares++;
}
if (explorable(map, row, col - 1)) {
squares++;
}
if (explorable(map, row, col + 1)) {
squares++;
}
if (explorable(map, row - 1, col)) {
squares++;
}
if (squares > 1) {
return true;
} else {
return false;
}
}
public void addCoordinates(int row, int col) {
coordinates.add(new Coordinate(row, col));
}
public void printCoordinates() {
for (int i = 0; i < coordinates.size(); i++) {
System.out.println(coordinates.get(i));
}
}
public boolean nextToF(String[][] map, int row, int col) {
if ("F".equals(map[row + 1][col])) {
// row++;
map[row + 1][col] = ("RIP");
return true;
} else if ("F".equals(map[row][col - 1])) {
// col--;
map[row][col - 1] = "RIP";
return true;
} else if ("F".equals(map[row][col + 1])) {
// col++;
map[row][col + 1] = "RIP";
return true;
} else if ("F".equals(map[row - 1][col])) {
// row--;
map[row - 1][col] = "RIP";
return true;
}
return false;
}
public boolean deadEnd(String[][] map, int row, int col) {
int deadEnds = 0;
if (row > map.length) {
deadEnds++;
}
if (col > map[0].length) {
deadEnds++;
}
if (map[row][col].equals("S")) {
deadEnds++;
}
if (map[row][col].equals("W")) {
deadEnds++;
}
if (map[row][col].equals("X")) {
deadEnds++;
}
if (map[row][col].equals("D")) {
deadEnds++;
}
if (deadEnds == 4) {
return true;
} else {
return false;
}
}
public void findD(){
}
public boolean isEnded(String[][] map) {
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map.length; j++) {
if (map[i][j].equals("RIP")) {
return true;
}
}
}
return false;
}
public void print(String[][] map) {
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[0].length; j++) {
System.out.print(map[i][j]);
}
System.out.println();
}
}
}
答案 0 :(得分:2)
我在solveButton的ActionListener下调用他的类,但我没有 知道如何在单击JLabel时更新String [] []映射。对于 例如,如果我在(5,5)单击JLabel,地图将更新map [5] [5] “W”而不是空字符串。
问题在于,您依赖的信息不会改变。
public void mouseClicked(MouseEvent e) {
if (clicked == false) {
clicked = true;
jlabel.setBackground(Color.LIGHT_GRAY);
map[rowCount - 1][colCount - 1] = "W";
} else {
clicked = false;
jlabel.setBackground(Color.BLACK);
//map[rowCount - 1][colCount -1 ] = "";
}
}
在您的代码中,您依赖的是rowCount
和colCount
,它不会(也可能不会)更改,而只会影响最后一个元素。 JLabel
和地图条目之间没有关系。
您需要做的是提供某种链接。在这种情况下,我通常会使用某种Map
,键入JLabel
并维护我需要的参考来循环map
值。
例如......
String[][] map;
// 1
private Map<JLabel, Point> labelMap;
//...
private void createAndShowGui() {
//...
map = new String[rowCount][colCount];
// 2
labelMap = new HashMap<>(rowCount * colCount);
//...
// 3
labelMap.put(jlabel, new Point(rows - 1, columns - 1));
jlabel.addMouseListener(new MouseListener() {
Map
labelMap
HashMap
的新实例
row
/ column
与给定标签然后在MouseListener
中,您需要获取点击的JLabel
,获取row
数组的关联column
/ map
并制作你的更新......
jlabel.addMouseListener(new MouseListener() {
boolean clicked = false;
@Override
public void mouseClicked(MouseEvent e) {
// Get the source of the event
JLabel label = (JLabel)e.getComponent();
// Get the map indices associated with the given label
Point point = labelMap.get(label);
// Flip the clicked state
clicked = !clicked;
// Update the state accordingly...
if (clicked) {
jlabel.setBackground(Color.LIGHT_GRAY);
map[point.x][point.y] = "W";
} else {
jlabel.setBackground(Color.BLACK);
map[point.x][point.y] = "";
}
}
此外,当您单击Solve JButton时,它应该突出显示 它所采用的路径,但它只突出显示它的结束位置。如果有的话 解决方案,“F”将变为“RIP”,如果没有解决方案 迷宫,它应该有一个JLabel说迷宫是无法解决的。
有一些问题导致这种情况无效,你应该看到它们发生时抛出异常。
我遇到的第一个问题是NullPointerException
,这是clear
方法在此行if (map[row][col].equals("S"))) {
这立刻告诉我map[row][col]
的价值是null
。不知道是否应该,不要太在意,因为它很容易使用...
if ("S".equals(map[row][col]))) {
您需要为此方法中的其他if
语句执行此操作。
我遇到的第二个问题是ArrayIndexOutOfBoundsException
,这是makeMove
方法造成的
} else if (clear(map, row, col - 1)) {
//...
} else if (clear(map, row - 1, col)) {
这里的主要问题是,当col
或row
0
时会发生什么?你最终没有对此进行边界检查......
您可以使用...
在clear
方法中解决此问题
public boolean clear(String[][] map, int row, int col) {
if (row < 0 || row > map.length) {
return false;
}
if (col < 0 || col > map[0].length) {
return false;
}
例如......
您nextToF
方法导致了类似问题